Skip to content

ci: pin actions and toolchains, scope permissions per event, and generate the benchmark tables from one result - #744

Open
owjs3901 wants to merge 43 commits into
mainfrom
ci/hardening
Open

owjs3901 wants to merge 43 commits into
mainfrom
ci/hardening

Conversation

@owjs3901

@owjs3901 owjs3901 commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Refs #683 (INF-03, INF-04, INF-09, INF-18, INF-19, INF-20, INF-22, INF-24, INF-25, NXT-23, NXT-24)

#731(test/react-18-fixture, react-18 잡 추가) 위에 쌓인 PR입니다. CI가 main 대상 PR에서만 도므로 base는 main이고, diff에 #731의 커밋이 함께 보입니다. 이 PR의 고유 커밋은 0ad2ad6d, 97ab9765 두 개이며 #731이 먼저 병합되어야 합니다.

요약

  • 워크플로의 모든 서드파티 action을 커밋 SHA로 고정하고(옆 주석에 릴리스), 툴체인을 고정하고(캐시 키에도 반영), PR 실행은 읽기 전용으로 만들고, 쓰기 권한이 필요한 게시/배포는 main push에서만 도는 별도 잡으로 옮겼습니다.
  • PR 실행이 e2e 스냅샷을 만들어 커밋하던 경로를 없애고(없으면 실패), 모든 잡에 timeout-minutes를 두었습니다.
  • wasm 패키지의 오래된 생성물과 템플릿 README를 정리하고, JS/WASM 경계를 검사하는 테스트를 추가했습니다.
  • README의 벤치마크 표를 하나의 결과 파일에서 영어/한국어로 함께 생성하고 CSS 크기를 별도 열로 보여줍니다.

항목별 결과

  • INF-18: 모든 uses:가 owner/repo@<40자 SHA> # vX 형태입니다(changepacks/action@main은 현재 main의 SHA d83fb1ec…이며 최신 태그 v0.1.0보다 앞서 있어 main을 고정했고 주석에 적었습니다). 최상위 권한은 contents: read뿐입니다. 이전에는 한 잡이 PR에서도 contents/id-token/pages/pull-requests: write를 가졌는데, 이제:
    • publish(검증, PR과 push 모두): 권한 없음(읽기).
    • deploy-pages: pages: write, id-token: write, needs: [publish], push to main에서만.
    • release(changepacks 게시): contents: write, id-token: write, pull-requests: write, needs: [publish, landing-next-e2e, react-18], push to main에서만.
    • 검증 잡의 id는 필수 상태 체크 이름이라 publish로 유지했습니다.
  • INF-19: Rust 1.99.0(+ clippy, rustfmt), Bun 1.4.0, Node 24.21.0, wasm-pack v0.15.0, 러너 ubuntu-24.04(ubuntu-latest 제거), cargo-tarpaulin 0.37.5, cargo-binstall v1.25.1을 워크플로 env에 한 번 적고 모든 잡이 씁니다. cargo-binstall은 curl | bash 대신 고정 릴리스를 받아 SHA-256(8e06c41a…)을 검증합니다.
  • INF-20: 캐시 키에 러너 이미지, Rust/wasm-pack(+tarpaulin), Bun, Node 버전이 들어갑니다. Playwright 브라우저 키는 러너, Node, bun.lock(Playwright 버전을 고정하므로 브라우저 리비전)입니다.
  • INF-22: stefanzweifel/git-auto-commit-action과 스냅샷 생성 단계를 제거했습니다. 체크인된 linux 기준 스냅샷이 하나도 없으면 실패하고, Playwright는 CI에서 updateSnapshots: 'none'이라 누락된 기준 이미지는 쓰지 않고 테스트를 실패시킵니다. 새 시각 테스트는 관리자가 bun run test:e2e:update로 만들어 커밋합니다.
  • INF-25: benchmark 60분, landing-next-e2e 60분, react-18 45분, publish(검증) 90분, deploy-pages 15분, release 45분(측정된 정상 소요 약 9~15분의 3배 이상).
  • INF-09: wasm 패키지 build가 pkg/를 비우고 시작하며, bun run verify:dist가 제거된 bindings/devup-ui-wasm/pkg/lite가 남아 있으면 실패합니다.
  • INF-24: bindings/devup-ui-wasm/README.md를 wasm-pack 템플릿 대신 실제 API, 빌드, 프로세스 전역 상태, 오류 형식 설명으로 교체했습니다.
  • NXT-23 / NXT-24: benchmark-results.json(main의 실제 CI 실행 36702867475의 결과)에서 render-benchmark-readme.js가 README.md와 README_ko.md의 표와 링크를 함께 만듭니다. 표에 빌드 사이즈와 별도로 CSS 사이즈 열이 있고 측정 대상(.next/dist, .css 파일)을 설명합니다. bun render-benchmark-readme.js --check가 검증 잡에서 두 README가 결과 파일과 같은지 확인합니다. benchmark.js는 이제 benchmark-run.json(행별 시간/크기/CSS, Turbopack 샘플/중앙값)을 쓰고 benchmark 잡이 아티팩트로 올립니다.
  • INF-04: packages/plugin-utils/src/__tests__/wasm-abi.test.ts가 빌드된 JS 바인딩을 직접 호출해 내보내는 함수 목록, 추출 결과(Output), 빌드 오류 메시지의 위치/내용, 접두사, 테마 등록과 타입 생성, 상태 저장/복원을 검증합니다(Rust 쪽 tarpaulin은 이 경계의 래퍼를 제외하므로 따로 보고하는 셈입니다).
  • INF-03(부분): 위 테스트는 시작 때 sheet/class/file/canonical 맵, debug, prefix를 저장하고 끝에 복원해 같은 프로세스의 다른 테스트에 상태를 남기지 않습니다. 전역 상태를 한 번에 되돌리는 테스트용 reset API와 next-plugin의 모듈 캐시 격리(wasm.test.ts)는 Rust 쪽 reset API가 필요해 이번에 하지 않았습니다.

main(릴리스 경로)이 그대로 동작하는 이유

  • 게시 단계(changepacks/action + publish: true), 같은 체크아웃(fetch-depth: 0, fetch-tags), 같은 빌드(bun run build), 같은 git diff --exit-code 검증이 release 잡에 그대로 있습니다. npm 신뢰 게시는 워크플로 파일 이름(publish.yml)으로 매칭하므로 파일 이름은 바꾸지 않았고, OIDC id-token: write는 release 잡에만 있습니다.
  • Pages: upload-pages-artifact는 검증 잡(읽기 권한으로 충분)에서 push to main일 때만 올리고, deploy-pages 잡이 같은 조건에서 배포합니다.
  • codecov 업로드는 검증 잡에 그대로 있습니다(fail_ci_if_error: true).
  • PR에서는 changepacks/action(PR 코멘트 쓰기 권한 필요) 대신 같은 버전(0.3.6)의 CLI changepacks check --format json을 읽기 전용으로 실행해 잘못된 changepack 로그를 계속 실패시킵니다. CLI는 비교 대상인 로컬 main 브랜치가 필요해 그 단계에서 git fetch origin main:refs/heads/main을 먼저 실행합니다(97ab9765). 대신 PR에 버전 요약 코멘트는 더 이상 달리지 않습니다.
  • 병합 전에 PR 실행으로는 release/deploy-pages를 실행해 볼 수 없습니다(push to main 조건). 로컬에서 YAML을 파싱해 잡, 권한, needs, if, 타임아웃과 모든 uses:의 SHA 고정을 확인했습니다. 병합 후 첫 main 실행에서 release와 deploy-pages가 도는지 봐야 합니다.

새로 생기는 오류

빌드 에러는 없습니다. CI 실패 조건이 늘었습니다: 체크인된 e2e 기준 이미지가 없을 때, 제거된 pkg/lite가 남아 있을 때, README 벤치마크 표가 benchmark-results.json과 다를 때.

남는 한계

  • 벤치마크 회귀 검출(NXT-21, INF-16, NXT-22, INF-26)은 요청대로 이후 작업으로 남겼습니다(benchmark-run.json 아티팩트가 그 입력이 됩니다).
  • INF-21(소비자 smoke, 브라우저 매트릭스)와 INF-03의 나머지는 위에 적은 대로입니다.
  • jetli/wasm-pack-action은 Node 20 기반 action이라 GitHub 경고가 남습니다(고정 SHA 그대로 유지).

검증

  • bun test 5487 pass / 0 fail, 커버리지 100%. bun lint 오류 0. 로컬에서 bun render-benchmark-readme.js --check, bun verify-dist.ts(pkg/lite를 만들어 실패하는 것도 확인).
  • 체인지팩: bindings/devup-ui-wasm/package.json Patch(빌드 스크립트와 README 변경). 나머지 변경은 패키지가 아닙니다.
  • 이 PR의 모든 잡 결과는 아래 CI 실행에서 확인합니다.

W40 main 반영 (2026-10-06)

  • 2026-10-06: main의 a935315c34b45aeda6dc156e29a5c76df51b76bd까지 병합했습니다 (병합 head: 7a81003f259dafd7c55709a310a109641892a0d0).
  • 충돌 해결: main을 포함한 test: build and drive a React 18 app in CI #731 head5644a8a6를 병합했습니다. publish.yml의 vinext와 publish 검증 주석을 모두 유지하고 새 vinext에도 모든 actionSHA·공유 도구 버전·버전별 캐시·30분 타임아웃·contents:read를 적용했습니다. 기존 vinext 단계/두 CSS 모드, React18, 게시 버전 및 release/deploy 의존 관계를 보존했습니다.
  • 검증: CI37446381625 success; 다섯 검증 작업과 codecov/patch 모두 통과, MERGEABLE/CLEAN. release/deploy-pages는 PR 이벤트에서 정상 skip. Ubuntu Rust100%(10465/10465), Bun5495 pass/0 fail 및100%, landing 두 모드130개씩 통과. 직렬 빌드/1.99clippy/전체 훅, 실제 WASM ABI11개, verify:dist/README 표/7개 작업의 YAML 권한·SHA·타임아웃 검사가 통과했습니다. 기존 lint 경고11개 외 새 오류는 없고 YAML LSP는 미설치입니다.
  • 새로 생기는 오류: 이번 병합으로 추가되는 오류는 없습니다. 기존 PR의 동작 및 남는 한계는 유지합니다.

2026-10-08 main 11790bef를 병합하여 업데이트했습니다. 충돌 없이 갱신된 부모 PR의 변경과 main의 변경을 모두 보존했습니다.

owjs3901 and others added 21 commits October 1, 2026 21:16
…rations

css(a, b) composing classes whose styles the build knows, bound to css() in the file or exported by another module, merges their atoms per property, selector, breakpoint and layer, conditions included, instead of joining classes whose winner the stylesheet order picked. vanilla-extract style([...]) passes each composed style as its own argument, keeping a style composed again later.

Refs #688

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #688

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #688

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #688

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…asurable

Refs #688

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…JSX spreads win

Refs #688

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…led order and JSX element className

Refs #688

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #689

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…uate shouldForwardProp at build time

Refs #689

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…ring

Refs #689

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…APIs

Refs #691

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #691

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #691

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #691

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #691

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Refs #691

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…rate the benchmark tables from one result

Refs #683

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…s against

Refs #683

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@codecov

codecov Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Files with missing lines Coverage Δ
libs/extractor/src/composition.rs 100.00% <100.00%> (ø)
...tractor/src/extractor/extract_style_from_styled.rs 100.00% <100.00%> (ø)
libs/extractor/src/imported_constants.rs 100.00% <100.00%> (ø)
libs/extractor/src/lib.rs 100.00% <ø> (ø)
libs/extractor/src/prop_modify_utils.rs 100.00% <100.00%> (ø)
libs/extractor/src/prop_valid.rs 100.00% <100.00%> (ø)
libs/extractor/src/style_values.rs 100.00% <100.00%> (ø)
libs/extractor/src/styled_reads.rs 100.00% <100.00%> (ø)
libs/extractor/src/utils.rs 100.00% <100.00%> (ø)
libs/extractor/src/vanilla_extract.rs 100.00% <ø> (ø)
... and 9 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

owjs3901 and others added 2 commits October 6, 2026 18:09
Resolve .github/workflows/publish.yml by retaining both React 18 and main vinext/RSC CSS acceptance jobs as independent siblings. Keep every main job and step byte-equivalent after YAML parsing, preserve #700 published versions with React peer/dev dependency intent, and regenerate lockfile workspace metadata through bun install.

Refs #691, #683

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Merge #731 head 5644a8a containing main a935315. Resolve .github/workflows/publish.yml by keeping the complete main vinext job and publish validation comment, extending every action SHA/toolchain/cache pin plus timeout30/read-only permissions to vinext. Keep React18 and both CSS modes, original release/deploy needs, #700 published versions and the clean-pkg build script.

Refs #683

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
owjs3901 added a commit that referenced this pull request Oct 6, 2026
Merge #744 head 7a81003 containing main a935315. No new manual conflict files: .github/workflows/publish.yml cleanly inherits the hardened vinext/React18 job union and read-only validation with action SHA pins/timeouts. Preserve the calibrated benchmark manifest/baseline/results, regression rules, SemanticBuilder bench and WASM budgets byte-for-byte, plus all main published versions and acceptance steps.

Refs #683

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
No conflicted files; preserve composition changes and main ESLint checks.
No conflicted files; combine updated parent and PR changes.
No conflicted files; combine updated parent and PR changes.
owjs3901 and others added 17 commits October 8, 2026 15:15
Merge main history while preserving this PR implementation. No manual conflict resolutions.
Merge main history while preserving this PR implementation. No manual conflict resolutions.
Merge main history while preserving this PR implementation. No manual conflict resolutions.
Merge main history while preserving this PR implementation. No manual conflict resolutions.
Merge main history while preserving this PR implementation. No manual conflict resolutions.
Merge main history while preserving this PR implementation. No manual conflict resolutions.
Merge main history while preserving this PR implementation. No manual conflict resolutions.
Merge main history while preserving this PR implementation. No manual conflict resolutions.
Conflicted file: libs/extractor/src/lib.rs. Retain both composition helper and regression tests from PR 706 and Tailwind per-class regression tests from main 11790be; take rewritten main Tailwind implementation with Rust 1.99 assertions. bun.lock regenerated by bun install; no snapshots were hand-merged.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Merge updated parent PR 706 (30247ba), containing main 11790be. Conflicted file: libs/extractor/src/prop_modify_utils.rs. Preserve PR 707's last-written className/style spread semantics and no spread_props parameter with capacity 2, together with main's per-class Tailwind compiler. No snapshots were hand-merged.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
No conflicted files; retain PR changes and merge updated parent #707, which contains main 11790be.
No conflicted files; retain PR changes and merge updated parent #710, which contains main 11790be.
No conflicted files; retain PR changes and merge updated parent #711, which contains main 11790be.
No conflicted files; retain PR changes and merge updated parent #722, which contains main 11790be.
No conflicted files; retain PR changes and merge updated parent #720, which contains main 11790be.
No conflicted files; retain PR changes and merge updated parent #721, which contains main 11790be.
No conflicted files; retain PR changes and merge updated parent #731, which contains main 11790be.
owjs3901 added a commit that referenced this pull request Oct 8, 2026
No conflicted files; retain PR changes and merge updated parent #744, which contains main 11790be.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant