-
-
Notifications
You must be signed in to change notification settings - Fork 5.9k
ci: pin every Studio install path to its lockfile #5479
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
53c0d8c
883f26a
2f1d2de
75a8129
d1124c5
fd5f9be
cf39fb6
d43b0e3
b743e1b
032eb88
7238504
c244a9d
888347d
220ae11
1f397f4
35a30f1
dc2292a
9c0372d
819ed20
ca0d2fd
2f7cc2d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -53,6 +53,10 @@ on: | |
| - 'studio/backend/requirements/**' | ||
| - 'studio/frontend/package.json' | ||
| - 'studio/frontend/package-lock.json' | ||
| - 'studio/backend/core/data_recipe/oxc-validator/package.json' | ||
| - 'studio/backend/core/data_recipe/oxc-validator/package-lock.json' | ||
| - 'studio/package.json' | ||
| - 'studio/package-lock.json' | ||
| - 'studio/src-tauri/Cargo.toml' | ||
| - 'studio/src-tauri/Cargo.lock' | ||
| - 'pyproject.toml' | ||
|
|
@@ -278,7 +282,7 @@ jobs: | |
| { | ||
| echo "## Lockfile supply-chain audit" | ||
| echo | ||
| echo "Scanned: studio/frontend/package-lock.json + studio/src-tauri/Cargo.lock" | ||
| echo "Scanned: studio/frontend/package-lock.json + studio/backend/core/data_recipe/oxc-validator/package-lock.json + studio/package-lock.json + studio/src-tauri/Cargo.lock" | ||
| echo | ||
| echo "No structural anomalies or known IOC strings." | ||
| } >> "$GITHUB_STEP_SUMMARY" | ||
|
|
@@ -307,6 +311,39 @@ jobs: | |
| echo '```' | ||
| } >> "$GITHUB_STEP_SUMMARY" | ||
|
|
||
| - name: npm audit (oxc-validator runtime) | ||
| # Same audit surface, separate npm project (oxc-parser, oxlint). | ||
| continue-on-error: true | ||
| working-directory: studio/backend/core/data_recipe/oxc-validator | ||
| run: | | ||
| set +e | ||
| npm audit --audit-level=high | tee "$GITHUB_WORKSPACE/logs-npm-audit-oxc.txt" | ||
| npm audit --json > "$GITHUB_WORKSPACE/logs-npm-audit-oxc.json" || true | ||
| { | ||
| echo "## npm audit (oxc-validator)" | ||
| echo | ||
| echo '```' | ||
| tail -200 "$GITHUB_WORKSPACE/logs-npm-audit-oxc.txt" | ||
| echo '```' | ||
| } >> "$GITHUB_STEP_SUMMARY" | ||
|
|
||
| - name: npm audit (Studio Tauri CLI holder) | ||
| # Same audit surface, third npm project (@tauri-apps/cli for the | ||
| # signed desktop release; lockfile lives at studio/package-lock.json). | ||
| continue-on-error: true | ||
| working-directory: studio | ||
| run: | | ||
| set +e | ||
| npm audit --audit-level=high | tee "$GITHUB_WORKSPACE/logs-npm-audit-studio.txt" | ||
| npm audit --json > "$GITHUB_WORKSPACE/logs-npm-audit-studio.json" || true | ||
| { | ||
| echo "## npm audit (Studio Tauri CLI holder)" | ||
| echo | ||
| echo '```' | ||
| tail -200 "$GITHUB_WORKSPACE/logs-npm-audit-studio.txt" | ||
| echo '```' | ||
| } >> "$GITHUB_STEP_SUMMARY" | ||
|
|
||
| # ───────────────────────────────────────────────────────────── | ||
| # cargo: Studio Tauri shell | ||
| # ───────────────────────────────────────────────────────────── | ||
|
|
@@ -348,6 +385,8 @@ jobs: | |
| /tmp/osv-scanner --version | ||
| /tmp/osv-scanner scan source \ | ||
| --lockfile=studio/frontend/package-lock.json \ | ||
| --lockfile=studio/backend/core/data_recipe/oxc-validator/package-lock.json \ | ||
| --lockfile=studio/package-lock.json \ | ||
| --lockfile=studio/src-tauri/Cargo.lock \ | ||
| --lockfile=requirements.txt:audit-reqs/unsloth-deps.txt \ | ||
| --lockfile=requirements.txt:audit-reqs/studio.txt \ | ||
|
|
@@ -911,26 +950,71 @@ jobs: | |
| # full log and surface it in the step summary either way. It | ||
| # never runs `npm install`, never executes anything from a | ||
| # downloaded tarball, and only fetches from registry.npmjs.org. | ||
| # Initially non-blocking so the baseline can settle; drop | ||
| # continue-on-error once the baseline is clean for a week. | ||
| # This step is blocking: the final exit code is the worst rc | ||
| # across all three npm projects (no continue-on-error). | ||
| # | ||
| # Three separate npm projects share this scan surface; scan each. | ||
| # Capture exit codes via PIPESTATUS so a HIGH/CRITICAL on one | ||
| # lockfile does not skip the next scan (all reports are most | ||
| # useful exactly when one already failed). | ||
| run: | | ||
| set -o pipefail | ||
| set +e | ||
|
|
||
| LOG=logs-scan-npm.txt | ||
| python3 scripts/scan_npm_packages.py 2>&1 | tee "$LOG" | ||
| frontend_rc=${PIPESTATUS[0]} | ||
|
|
||
| LOG2=logs-scan-npm-oxc.txt | ||
| python3 scripts/scan_npm_packages.py \ | ||
| --lockfile studio/backend/core/data_recipe/oxc-validator/package-lock.json \ | ||
| 2>&1 | tee "$LOG2" | ||
|
Comment on lines
+967
to
+970
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
GitHub documents default bash run steps as fail-fast ( Useful? React with 👍 / 👎. |
||
| oxc_rc=${PIPESTATUS[0]} | ||
|
|
||
| LOG3=logs-scan-npm-studio.txt | ||
| python3 scripts/scan_npm_packages.py \ | ||
| --lockfile studio/package-lock.json \ | ||
| 2>&1 | tee "$LOG3" | ||
| studio_rc=${PIPESTATUS[0]} | ||
|
|
||
| { | ||
| echo "## scan_npm_packages" | ||
| echo "## scan_npm_packages (Studio frontend)" | ||
| echo | ||
| echo '### Findings (tail)' | ||
| echo '```' | ||
| tail -300 "$LOG" | ||
| echo '```' | ||
| echo | ||
| echo "## scan_npm_packages (oxc-validator)" | ||
| echo | ||
| echo '### Findings (tail)' | ||
| echo '```' | ||
| tail -300 "$LOG2" | ||
| echo '```' | ||
| echo | ||
| echo "## scan_npm_packages (Studio Tauri CLI holder)" | ||
| echo | ||
| echo '### Findings (tail)' | ||
| echo '```' | ||
| tail -300 "$LOG3" | ||
| echo '```' | ||
| } >> "$GITHUB_STEP_SUMMARY" | ||
|
|
||
| if [ "$frontend_rc" -ne 0 ]; then | ||
| exit "$frontend_rc" | ||
| fi | ||
| if [ "$oxc_rc" -ne 0 ]; then | ||
| exit "$oxc_rc" | ||
| fi | ||
| exit "$studio_rc" | ||
|
|
||
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | ||
| if: always() | ||
| with: | ||
| name: scan-npm-packages-log | ||
| path: logs-scan-npm.txt | ||
| path: | | ||
| logs-scan-npm.txt | ||
| logs-scan-npm-oxc.txt | ||
| logs-scan-npm-studio.txt | ||
| retention-days: 30 | ||
|
|
||
| # ───────────────────────────────────────────────────────────────────── | ||
|
|
@@ -1077,7 +1161,7 @@ jobs: | |
| working-directory: studio/frontend | ||
| run: npm ci --ignore-scripts | ||
|
|
||
| - name: npm audit signatures (informational) | ||
| - name: npm audit signatures (Studio frontend, informational) | ||
| # Surfaces unsigned / mis-signed packages from the npm | ||
| # transparency log. continue-on-error during baseline-build | ||
| # phase; promote to hard gate once the lockfile is fully | ||
|
|
@@ -1086,10 +1170,48 @@ jobs: | |
| continue-on-error: true | ||
| run: | | ||
| set -o pipefail | ||
| LOG=logs-audit-signatures.txt | ||
| LOG="$GITHUB_WORKSPACE/logs-audit-signatures.txt" | ||
| npm audit signatures 2>&1 | tee "$LOG" | ||
| { | ||
| echo "## npm audit signatures (Studio frontend)" | ||
| echo | ||
| echo '```' | ||
| tail -200 "$LOG" | ||
| echo '```' | ||
| } >> "$GITHUB_STEP_SUMMARY" | ||
|
|
||
| - name: Install oxc-validator deps (--ignore-scripts) | ||
| working-directory: studio/backend/core/data_recipe/oxc-validator | ||
| run: npm ci --ignore-scripts | ||
|
|
||
| - name: npm audit signatures (oxc-validator, informational) | ||
| working-directory: studio/backend/core/data_recipe/oxc-validator | ||
| continue-on-error: true | ||
| run: | | ||
| set -o pipefail | ||
| LOG="$GITHUB_WORKSPACE/logs-audit-signatures-oxc.txt" | ||
| npm audit signatures 2>&1 | tee "$LOG" | ||
| { | ||
| echo "## npm audit signatures" | ||
| echo "## npm audit signatures (oxc-validator)" | ||
| echo | ||
| echo '```' | ||
| tail -200 "$LOG" | ||
| echo '```' | ||
| } >> "$GITHUB_STEP_SUMMARY" | ||
|
|
||
| - name: Install Studio Tauri CLI holder deps (--ignore-scripts) | ||
| working-directory: studio | ||
| run: npm ci --ignore-scripts | ||
|
|
||
| - name: npm audit signatures (Studio Tauri CLI holder, informational) | ||
| working-directory: studio | ||
| continue-on-error: true | ||
| run: | | ||
| set -o pipefail | ||
| LOG="$GITHUB_WORKSPACE/logs-audit-signatures-studio.txt" | ||
| npm audit signatures 2>&1 | tee "$LOG" | ||
| { | ||
| echo "## npm audit signatures (Studio Tauri CLI holder)" | ||
| echo | ||
| echo '```' | ||
| tail -200 "$LOG" | ||
|
|
@@ -1103,13 +1225,25 @@ jobs: | |
| BASE_SHA="${{ github.event.pull_request.base.sha }}" | ||
| git show "$BASE_SHA:studio/frontend/package-lock.json" \ | ||
| > /tmp/base-package-lock.json | ||
| # OXC lockfile may not exist on the base ref (newly added). | ||
| git show "$BASE_SHA:studio/backend/core/data_recipe/oxc-validator/package-lock.json" \ | ||
| > /tmp/base-oxc-package-lock.json 2>/dev/null || echo '{}' > /tmp/base-oxc-package-lock.json | ||
| # Tauri CLI holder lockfile may not exist on the base ref (newly added). | ||
| git show "$BASE_SHA:studio/package-lock.json" \ | ||
| > /tmp/base-studio-package-lock.json 2>/dev/null || echo '{}' > /tmp/base-studio-package-lock.json | ||
|
|
||
| - name: Diff for newly-added install-script deps | ||
| if: github.event_name == 'pull_request' | ||
| run: | | ||
| python3 scripts/check_new_install_scripts.py \ | ||
| --base /tmp/base-package-lock.json \ | ||
| --head studio/frontend/package-lock.json | ||
| python3 scripts/check_new_install_scripts.py \ | ||
| --base /tmp/base-oxc-package-lock.json \ | ||
| --head studio/backend/core/data_recipe/oxc-validator/package-lock.json | ||
| python3 scripts/check_new_install_scripts.py \ | ||
| --base /tmp/base-studio-package-lock.json \ | ||
| --head studio/package-lock.json | ||
|
|
||
| - name: Skip install-script diff (non-PR trigger) | ||
| if: github.event_name != 'pull_request' | ||
|
|
@@ -1121,6 +1255,9 @@ jobs: | |
| if: always() | ||
| with: | ||
| name: npm-audit-signatures-log | ||
| path: studio/frontend/logs-audit-signatures.txt | ||
| path: | | ||
| logs-audit-signatures.txt | ||
| logs-audit-signatures-oxc.txt | ||
| logs-audit-signatures-studio.txt | ||
| if-no-files-found: ignore | ||
| retention-days: 30 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -60,32 +60,27 @@ jobs: | |
| with: | ||
| workspaces: studio/src-tauri -> target | ||
|
|
||
| # Must run BEFORE any `npm ci` so a tarball's prepare/postinstall | ||
| # cannot execute ahead of the structural scan. | ||
| - name: Lockfile supply-chain audit (pre-install scan) | ||
| run: python3 scripts/lockfile_supply_chain_audit.py | ||
|
|
||
| - name: Install pinned Tauri CLI (matches release-desktop.yml) | ||
| # Lifecycle scripts (esbuild native-binary postinstall, etc.) are | ||
| # required for `vite build`. The pre-install lockfile structural | ||
| # audit (lockfile_supply_chain_audit.py) is the practical defence | ||
| # against the npm postinstall-dropper class -- it fires BEFORE any | ||
| # tarball runs, on the injection pattern itself rather than an | ||
| # advisory-DB lookup. | ||
| run: npm install --save-dev --prefix studio @tauri-apps/cli@2.10.1 --no-fund --no-audit | ||
| # `npm ci` resolves @tauri-apps/cli from studio/package-lock.json | ||
| # (transitives fully pinned, integrity hashes verified). | ||
| run: npm ci --prefix studio --no-fund --no-audit | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This workflow now installs and verifies the Tauri CLI from Useful? React with 👍 / 👎. |
||
|
|
||
| - name: Verify pinned Tauri CLI version | ||
| run: | | ||
| out="$(npx --prefix studio tauri --version)" | ||
| echo "$out" | ||
| [ "$out" = "tauri-cli 2.10.1" ] || { echo "::error::expected tauri-cli 2.10.1, got $out"; exit 1; } | ||
|
|
||
| - name: Lockfile supply-chain audit (pre-install scan) | ||
| run: python3 scripts/lockfile_supply_chain_audit.py | ||
|
|
||
| - name: Frontend build (npm ci, vite) | ||
| working-directory: studio/frontend | ||
| # Lifecycle scripts (esbuild native-binary postinstall, etc.) are | ||
| # required for `vite build`. The pre-install lockfile structural | ||
| # audit (lockfile_supply_chain_audit.py) is the practical defence | ||
| # against the npm postinstall-dropper class -- it fires BEFORE any | ||
| # tarball runs, on the injection pattern itself rather than an | ||
| # advisory-DB lookup. | ||
| # Vite build needs esbuild's native-binary postinstall; the | ||
| # pre-install lockfile audit above is what gates that path | ||
| # against the npm postinstall-dropper class. | ||
| run: | | ||
| npm ci --no-fund --no-audit | ||
| npm run build | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This paths block now watches the new OXC npm project but still omits
studio/package.jsonandstudio/package-lock.json, even though the desktop release workflow now installs that project withnpm ci --prefix studio. A PR that changes only the Tauri CLI holder or its lockfile will not triggersecurity-audit.yml, so the lockfile structural audit, OSV scan, npm tarball scan, and install-script diff can all be skipped for the newly pinned release-time install surface.Useful? React with 👍 / 👎.