name: CI on: # push を main に限る。枝への push で発火させると、PR を開いている間は # 同じコミットに対して push と pull_request の 2 本が走る。中身は同一で、 # 片方は情報を増やさない。1 本あたり 11 分台(E2E を足す前は 6 分台。 # どちらも実測)なので、コミットごとに実行係の枠を二重に使っていた。 # 枝の検査は pull_request 側が見る。main への直 push(マージコミット含む) # は push 側が見る。 push: branches: - main pull_request: permissions: contents: read jobs: build-and-test: runs-on: ubuntu-latest # act_runner は本番オーケストレータと同じホストに同居している。 # テストが固まった場合(同期 SQLite クエリが止まらない等)、上限が無いと # プラットフォーム既定まで数時間占有し、周りごと巻き込む。 timeout-minutes: 30 steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: # checkout が残す認証情報を、この後に走る依存インストールとビルドへ # 引き渡さない。lifecycle script を止めてもトークンが読める状態なら # 意味が薄れる。 persist-credentials: false # setup-node の `cache: npm` はあえて使わない。act_runner は本番 # オーケストレータと同じホストに同居していて、キャッシュは全ジョブで共有 # される。未信頼 PR のジョブが書いたキャッシュを、既定ブランチのジョブが # 復元する経路を残さないため、共有キャッシュを持たない構成にしている。 # 設計上の根拠は docs/design/2026-08-07-supply-chain-install-policy.html の # 「共有キャッシュ」節を参照。復活させる場合は、キャッシュキーに信頼レベル # を含めたうえで同ドキュメントを更新すること。 - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: 22 - name: Install LibreOffice Calc and UNO run: | sudo apt-get update sudo apt-get install -y --no-install-recommends libreoffice-calc python3-uno # 依存を入れる前に lockfile を検査する。順序が逆になると、検査対象の # lockfile が持ち込んだコードが検査より先に走ってしまう。 - name: Check dependency policy run: node scripts/security/dependency-policy.mjs package-lock.json ui/package-lock.json - name: Install dependencies run: | npm ci --ignore-scripts --no-audit npm --prefix ui ci --ignore-scripts --no-audit # --ignore-scripts で入れた native パッケージのうち、許可一覧に載っている # ものだけを出所と integrity を確認したうえで rebuild する。 - name: Rebuild allowlisted native dependency run: node scripts/security/rebuild-native.mjs - name: Install Playwright Chromium run: node node_modules/playwright/cli.js install --with-deps chromium # UI の型検査を独立ステップにする。build に含めてはいるが、型エラーで # 落ちたのかバンドルで落ちたのかを、ログを読まずに判別できるようにする。 - name: Typecheck (UI) run: npm run typecheck:ui # Tailwind は「不透明度を置く場所が無い色」に /50 のような指定を書いても # 黙って規則を捨てる。型検査もテストもビルドも通るので、ここで止める。 # 既知の分は scripts/tailwind-opacity-baseline.json に控えてあり、 # 増えたときだけ落ちる。 - name: Check Tailwind opacity modifiers run: npm run check:tailwind-opacity # ui/src/index.css は暗い外観で slate の並びを上下ひっくり返す。素の # text-slate-700 が明暗どちらでも正しいので、そこへ dark: を足すと二度反転 # して文字が地に沈む。既知の分は scripts/dark-text-baseline.json に控えてあり、 # 増えたときだけ落ちる(コントラスト比は測っていない。#1388)。 - name: Check dark-theme slate text classes run: npm run check:dark-text - name: Build run: npm run build:all -- --skip-python - name: Test run: npm test - name: Test Excel recalculation with LibreOffice env: RUN_LIBREOFFICE_TESTS: '1' run: npx vitest run src/engine/tools/excel-recalculate.test.ts # ブラウザを実際に動かす検査。Chromium は上で入れているのに、それを使う段が # 無かった(#1338)。走っていなかった間に 6 件が壊れ、PR のレビューで手作業の # 切り分けが要る状態になっていた。 # # 最後に置く: いちばん遅く、いちばん落ちやすい。型検査・単体が先に出るので、 # 素早く分かる失敗をこれで待たせない。 # # webServer(scripts/e2e-web-server.mjs)は自分で build:server と build:ui を # 回してから起動する。上の Build と重なるが、E2E が見るのは自分が建てた # 使い捨ての木で、そこを飛ばすと途中の ui/dist を掴む事故に戻る。 # # `|| true` も continue-on-error も付けない。赤は赤として出す。 - name: Check egress controls (real worker and browser) run: | npm run security:egress-boundary npm run security:egress npm run security:egress-settings npm run security:ui-assets -- --csp - name: Check local UI assets (browser) run: | npm run security:ui-assets npm run check:execution-conversations npm run check:transcription npm run check:task-files-toolbar node scripts/check-ui-inspector.mjs - name: Test (E2E) run: npm run test:e2e # 認証を有効にして動かす検査(#1399)。上の E2E と別のハーネス # (ui/playwright.auth.config.ts)で、こちらだけが実在する利用者の識別子を # 必要とする権限まわり——管理者のユーザー管理・共有ワークスペース・公開範囲・ # 招待・ワークスペースのファイルの受け口——を見る。認証を切った上の段では # そもそも試せない。 # # 上の E2E と同じく `|| true` も continue-on-error も付けない。 - name: Test (E2E, auth) run: npm run test:e2e:auth