From c77a88c247b511986bb4bd18ce1045ce2032f904 Mon Sep 17 00:00:00 2001 From: Hongming Wang Date: Tue, 28 Apr 2026 15:37:06 -0700 Subject: [PATCH] chore(security): pin Actions to SHAs + enable Dependabot auto-bumps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Supply-chain hardening for the CI pipeline. 23 workflow files modified, 59 mutable-tag refs replaced with commit SHAs. The risk Every `uses:` reference in .github/workflows/*.yml was pinned to a mutable tag (e.g., `actions/checkout@v4`). A maintainer of an action — or a compromised maintainer account — can repoint that tag to malicious code, and our pipelines silently pull it on the next run. The tj-actions/changed-files compromise of March 2025 is the canonical example: maintainer credential leak, attacker repointed several `@v` tags to a payload that exfiltrated repository secrets. Repos that pinned to SHAs were unaffected. The fix Replace each `@v` with `@ # v`. The trailing comment preserves human readability ("ah, this is v4"); the SHA makes the reference immutable. Actions covered (10 distinct): actions/{checkout,setup-go,setup-python,setup-node,upload-artifact,github-script} docker/{login-action,setup-buildx-action,build-push-action} github/codeql-action/{init,autobuild,analyze} dorny/paths-filter imjasonh/setup-crane pnpm/action-setup (already pinned in molecule-app, listed here for completeness) Excluded: Molecule-AI/molecule-ci/.github/workflows/disable-auto-merge-on-push.yml@main — internal org reusable workflow; we control its repo, threat model is different from third-party actions. Conventional to pin to @main rather than SHA for internal reusables. The maintenance cost SHA pinning means upstream fixes require manual SHA bumps. Without automation, pinned SHAs go stale. So this PR also enables Dependabot across four ecosystems: - github-actions (workflows) - gomod (workspace-server) - npm (canvas) - pip (workspace runtime requirements) Weekly cadence — the supply-chain attack window is "minutes between repoint and pull"; weekly auto-bumps don't help with zero-days regardless. The point is to pull in non-zero-day fixes without operator effort. Aligns with user-stated principle: "long-term, robust, fully- automated, eliminate human error." Companion PR: Molecule-AI/molecule-controlplane#308 (same pattern, smaller surface). Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/dependabot.yml | 80 +++++++++++++++++++ .github/workflows/auto-promote-on-e2e.yml | 2 +- .github/workflows/auto-promote-staging.yml | 2 +- .../workflows/auto-sync-main-to-staging.yml | 2 +- .github/workflows/auto-tag-runtime.yml | 2 +- .github/workflows/block-internal-paths.yml | 2 +- .github/workflows/canary-staging.yml | 6 +- .github/workflows/canary-verify.yml | 4 +- .../workflows/check-merge-group-trigger.yml | 2 +- .github/workflows/ci.yml | 16 ++-- .github/workflows/codeql.yml | 12 +-- .github/workflows/e2e-api.yml | 8 +- .github/workflows/e2e-staging-canvas.yml | 12 +-- .github/workflows/e2e-staging-saas.yml | 2 +- .github/workflows/e2e-staging-sanity.yml | 4 +- .github/workflows/promote-latest.yml | 2 +- .github/workflows/publish-canvas-image.yml | 8 +- .github/workflows/publish-runtime.yml | 4 +- .../publish-workspace-server-image.yml | 12 +-- .github/workflows/runtime-pin-compat.yml | 4 +- .github/workflows/runtime-prbuild-compat.yml | 4 +- .github/workflows/secret-scan.yml | 2 +- .github/workflows/sweep-cf-orphans.yml | 2 +- .github/workflows/test-ops-scripts.yml | 4 +- 24 files changed, 139 insertions(+), 59 deletions(-) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..0647a0e2 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,80 @@ +# Dependabot — auto-bump pinned dependencies. +# +# Why this exists: +# +# All `uses:` references in .github/workflows/*.yml are pinned to commit +# SHAs (with `# v` comments for human readability) instead of mutable +# tags like `@v4`. Tag pinning is a known supply-chain risk: a maintainer +# (or compromised maintainer account) can repoint `@v4` to malicious code +# and our pipelines silently pull it. SHA pinning closes that risk. +# +# But SHA pinning has a maintenance cost: each upstream legitimate fix +# requires manually finding + bumping the SHA. Dependabot for Actions +# closes that gap by opening PRs to bump pinned SHAs whenever upstream +# tags a new version. Reviewer evaluates the bump like any other +# dependency PR. +# +# Combined: SHA pinning gives us security, Dependabot keeps us current. + +version: 2 +updates: + # GitHub Actions — every workflow file under .github/workflows/. + # Weekly cadence is enough for a CI surface this size; the supply- + # chain attack window is "minutes between repoint and pull," and + # weekly auto-bumps don't help with zero-days regardless. The point + # is to pull in non-zero-day fixes without operator effort, not to + # be real-time. + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly + open-pull-requests-limit: 5 + labels: + - dependencies + - github-actions + commit-message: + prefix: chore(deps) + include: scope + + # Go module — workspace-server. Bumps go.mod deps via PR weekly. + - package-ecosystem: gomod + directory: "/workspace-server" + schedule: + interval: weekly + open-pull-requests-limit: 5 + labels: + - dependencies + - go + commit-message: + prefix: chore(deps) + include: scope + + # npm — canvas (Next.js bundle). Largest dep tree in this repo; + # weekly cadence keeps the security surface fresh without flooding + # the queue. open-pull-requests-limit: 10 because npm churns more + # than the others. + - package-ecosystem: npm + directory: "/canvas" + schedule: + interval: weekly + open-pull-requests-limit: 10 + labels: + - dependencies + - npm + commit-message: + prefix: chore(deps) + include: scope + + # Python — workspace runtime requirements. Pip/requirements.txt- + # backed rather than pyproject.toml; Dependabot supports both. + - package-ecosystem: pip + directory: "/workspace" + schedule: + interval: weekly + open-pull-requests-limit: 5 + labels: + - dependencies + - python + commit-message: + prefix: chore(deps) + include: scope diff --git a/.github/workflows/auto-promote-on-e2e.yml b/.github/workflows/auto-promote-on-e2e.yml index 21f901e9..ef10c80f 100644 --- a/.github/workflows/auto-promote-on-e2e.yml +++ b/.github/workflows/auto-promote-on-e2e.yml @@ -65,7 +65,7 @@ jobs: echo "short=${FULL:0:7}" >> "$GITHUB_OUTPUT" echo "full=${FULL}" >> "$GITHUB_OUTPUT" - - uses: imjasonh/setup-crane@v0.4 + - uses: imjasonh/setup-crane@31b88efe9de28ae0ffa220711af4b60be9435f6e # v0.4 - name: GHCR login run: | diff --git a/.github/workflows/auto-promote-staging.yml b/.github/workflows/auto-promote-staging.yml index 118d0c83..53946c95 100644 --- a/.github/workflows/auto-promote-staging.yml +++ b/.github/workflows/auto-promote-staging.yml @@ -152,7 +152,7 @@ jobs: - name: Checkout main if: ${{ vars.AUTO_PROMOTE_ENABLED == 'true' || github.event.inputs.force == 'true' }} - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: ref: main fetch-depth: 0 diff --git a/.github/workflows/auto-sync-main-to-staging.yml b/.github/workflows/auto-sync-main-to-staging.yml index 278c3428..b119712e 100644 --- a/.github/workflows/auto-sync-main-to-staging.yml +++ b/.github/workflows/auto-sync-main-to-staging.yml @@ -63,7 +63,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout staging - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 ref: staging diff --git a/.github/workflows/auto-tag-runtime.yml b/.github/workflows/auto-tag-runtime.yml index 2b9070bc..9c1a0222 100644 --- a/.github/workflows/auto-tag-runtime.yml +++ b/.github/workflows/auto-tag-runtime.yml @@ -38,7 +38,7 @@ jobs: tag: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 # need full tag history for `git describe` / sort diff --git a/.github/workflows/block-internal-paths.yml b/.github/workflows/block-internal-paths.yml index da56a090..02f14c64 100644 --- a/.github/workflows/block-internal-paths.yml +++ b/.github/workflows/block-internal-paths.yml @@ -26,7 +26,7 @@ jobs: name: Block forbidden paths runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 2 # need previous commit to diff against on push events diff --git a/.github/workflows/canary-staging.yml b/.github/workflows/canary-staging.yml index 65b304aa..30691a82 100644 --- a/.github/workflows/canary-staging.yml +++ b/.github/workflows/canary-staging.yml @@ -66,7 +66,7 @@ jobs: E2E_RUN_ID: "canary-${{ github.run_id }}" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Verify admin token present run: | @@ -98,7 +98,7 @@ jobs: # next deploy window. - name: Open issue on failure if: failure() - uses: actions/github-script@v7 + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 env: # Inject the workflow path explicitly — context.workflow is # the *name*, not the file path the actions API needs. @@ -165,7 +165,7 @@ jobs: - name: Auto-close canary issue on success if: success() - uses: actions/github-script@v7 + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 with: script: | const title = '🔴 Canary failing: staging SaaS smoke'; diff --git a/.github/workflows/canary-verify.yml b/.github/workflows/canary-verify.yml index 6e560969..c81ae8f3 100644 --- a/.github/workflows/canary-verify.yml +++ b/.github/workflows/canary-verify.yml @@ -40,7 +40,7 @@ jobs: smoke_ran: ${{ steps.smoke.outputs.ran }} steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Compute sha id: compute @@ -143,7 +143,7 @@ jobs: if: ${{ needs.canary-smoke.result == 'success' && needs.canary-smoke.outputs.smoke_ran == 'true' }} runs-on: ubuntu-latest steps: - - uses: imjasonh/setup-crane@v0.4 + - uses: imjasonh/setup-crane@31b88efe9de28ae0ffa220711af4b60be9435f6e # v0.4 - name: GHCR login run: | diff --git a/.github/workflows/check-merge-group-trigger.yml b/.github/workflows/check-merge-group-trigger.yml index 77f4c7b3..4345e8b6 100644 --- a/.github/workflows/check-merge-group-trigger.yml +++ b/.github/workflows/check-merge-group-trigger.yml @@ -36,7 +36,7 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Verify merge_group trigger on required-check workflows env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a9902658..d83f4a0c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,7 @@ jobs: python: ${{ steps.check.outputs.python }} scripts: ${{ steps.check.outputs.scripts }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 0 - id: check @@ -72,8 +72,8 @@ jobs: run: working-directory: workspace-server steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5 with: go-version: 'stable' - run: go mod download @@ -187,8 +187,8 @@ jobs: run: working-directory: canvas steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: '22' - run: rm -f package-lock.json && npm install @@ -210,7 +210,7 @@ jobs: if: needs.changes.outputs.scripts == 'true' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Run shellcheck on tests/e2e/*.sh and infra/scripts/*.sh # shellcheck is pre-installed on ubuntu-latest runners (via apt). # infra/scripts/ is included because setup.sh + nuke.sh gate the @@ -276,8 +276,8 @@ jobs: run: working-directory: workspace steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: python-version: '3.11' cache: pip diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 22d095b4..c18b41e9 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -53,14 +53,14 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Checkout sibling plugin repo # Same reasoning as publish-workspace-server-image.yml — the Go # module's replace directive needs the plugin source so # CodeQL's "go build" phase can resolve. if: matrix.language == 'go' - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: repository: Molecule-AI/molecule-ai-plugin-github-app-auth path: molecule-ai-plugin-github-app-auth @@ -69,7 +69,7 @@ jobs: # jq is pre-installed on ubuntu-latest — no setup step needed. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@ce64ddcb0d8d890d2df4a9d1c04ff297367dea2a # v3 with: languages: ${{ matrix.language }} # security-extended widens past the default to include the @@ -77,11 +77,11 @@ jobs: queries: security-extended - name: Autobuild - uses: github/codeql-action/autobuild@v3 + uses: github/codeql-action/autobuild@ce64ddcb0d8d890d2df4a9d1c04ff297367dea2a # v3 - name: Perform CodeQL Analysis id: analyze - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@ce64ddcb0d8d890d2df4a9d1c04ff297367dea2a # v3 with: category: "/language:${{ matrix.language }}" # upload: never — GHAS isn't enabled on this repo, so the @@ -121,7 +121,7 @@ jobs: # 14-day retention — longer than default 3, short enough not # to bloat quota. if: always() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: codeql-sarif-${{ matrix.language }} path: sarif-results/${{ matrix.language }}/ diff --git a/.github/workflows/e2e-api.yml b/.github/workflows/e2e-api.yml index d7d6ea09..cb7b4607 100644 --- a/.github/workflows/e2e-api.yml +++ b/.github/workflows/e2e-api.yml @@ -36,8 +36,8 @@ jobs: outputs: api: ${{ steps.decide.outputs.api }} steps: - - uses: actions/checkout@v4 - - uses: dorny/paths-filter@v3 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3 id: filter with: filters: | @@ -78,8 +78,8 @@ jobs: PG_CONTAINER: molecule-ci-postgres REDIS_CONTAINER: molecule-ci-redis steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5 with: go-version: 'stable' cache: true diff --git a/.github/workflows/e2e-staging-canvas.yml b/.github/workflows/e2e-staging-canvas.yml index 310e16f3..41e2448c 100644 --- a/.github/workflows/e2e-staging-canvas.yml +++ b/.github/workflows/e2e-staging-canvas.yml @@ -46,8 +46,8 @@ jobs: outputs: canvas: ${{ steps.decide.outputs.canvas }} steps: - - uses: actions/checkout@v4 - - uses: dorny/paths-filter@v3 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3 id: filter with: filters: | @@ -90,7 +90,7 @@ jobs: working-directory: canvas steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Verify admin token present run: | @@ -100,7 +100,7 @@ jobs: fi - name: Set up Node - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 with: node-version: '20' cache: 'npm' @@ -117,7 +117,7 @@ jobs: - name: Upload Playwright report on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: playwright-report-staging path: canvas/playwright-report-staging/ @@ -125,7 +125,7 @@ jobs: - name: Upload screenshots on failure if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: playwright-screenshots path: canvas/test-results/ diff --git a/.github/workflows/e2e-staging-saas.yml b/.github/workflows/e2e-staging-saas.yml index 39ee38a2..1c6d04bf 100644 --- a/.github/workflows/e2e-staging-saas.yml +++ b/.github/workflows/e2e-staging-saas.yml @@ -92,7 +92,7 @@ jobs: E2E_KEEP_ORG: ${{ github.event.inputs.keep_org && '1' || '0' }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Verify admin token present run: | diff --git a/.github/workflows/e2e-staging-sanity.yml b/.github/workflows/e2e-staging-sanity.yml index 6eacac36..e645a58f 100644 --- a/.github/workflows/e2e-staging-sanity.yml +++ b/.github/workflows/e2e-staging-sanity.yml @@ -50,7 +50,7 @@ jobs: E2E_INTENTIONAL_FAILURE: "1" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Verify admin token present run: | @@ -89,7 +89,7 @@ jobs: - name: Open issue if safety net is broken if: failure() - uses: actions/github-script@v7 + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 with: script: | const title = "🚨 E2E teardown safety net broken"; diff --git a/.github/workflows/promote-latest.yml b/.github/workflows/promote-latest.yml index 896f216c..2be7e023 100644 --- a/.github/workflows/promote-latest.yml +++ b/.github/workflows/promote-latest.yml @@ -34,7 +34,7 @@ jobs: promote: runs-on: ubuntu-latest steps: - - uses: imjasonh/setup-crane@v0.4 + - uses: imjasonh/setup-crane@31b88efe9de28ae0ffa220711af4b60be9435f6e # v0.4 - name: GHCR login run: | diff --git a/.github/workflows/publish-canvas-image.yml b/.github/workflows/publish-canvas-image.yml index e957169d..b7a34aeb 100644 --- a/.github/workflows/publish-canvas-image.yml +++ b/.github/workflows/publish-canvas-image.yml @@ -42,17 +42,17 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Log in to GHCR - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Compute tags id: tags @@ -85,7 +85,7 @@ jobs: echo "ws_url=${WS_URL}" >> "$GITHUB_OUTPUT" - name: Build & push canvas image to GHCR - uses: docker/build-push-action@v6 + uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 with: context: ./canvas file: ./canvas/Dockerfile diff --git a/.github/workflows/publish-runtime.yml b/.github/workflows/publish-runtime.yml index 516f8f98..83f87df3 100644 --- a/.github/workflows/publish-runtime.yml +++ b/.github/workflows/publish-runtime.yml @@ -81,9 +81,9 @@ jobs: version: ${{ steps.version.outputs.version }} wheel_sha256: ${{ steps.wheel_hash.outputs.wheel_sha256 }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: python-version: "3.11" cache: pip diff --git a/.github/workflows/publish-workspace-server-image.yml b/.github/workflows/publish-workspace-server-image.yml index c7f3127f..d47a887d 100644 --- a/.github/workflows/publish-workspace-server-image.yml +++ b/.github/workflows/publish-workspace-server-image.yml @@ -27,7 +27,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Checkout sibling plugin repo # workspace-server/Dockerfile expects @@ -42,21 +42,21 @@ jobs: # The PAT needs Contents:Read on Molecule-AI/molecule-ai-plugin- # github-app-auth. Falls back to the default token for the (rare) # case where an operator made the plugin repo public. - uses: actions/checkout@v4 + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: repository: Molecule-AI/molecule-ai-plugin-github-app-auth path: molecule-ai-plugin-github-app-auth token: ${{ secrets.PLUGIN_REPO_PAT || secrets.GITHUB_TOKEN }} - name: Log in to GHCR - uses: docker/login-action@v3 + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Compute tags id: tags @@ -87,7 +87,7 @@ jobs: # applyRuntimeModelEnv and caused every E2E to route hermes+openai # through openrouter → 401). See issue filed with this PR. - name: Build & push platform image to GHCR (staging- + staging-latest) - uses: docker/build-push-action@v6 + uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 with: context: . file: ./workspace-server/Dockerfile @@ -104,7 +104,7 @@ jobs: org.opencontainers.image.description=Molecule AI platform (Go API server) — pending canary verify - name: Build & push tenant image to GHCR (staging- + staging-latest) - uses: docker/build-push-action@v6 + uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 with: context: . file: ./workspace-server/Dockerfile.tenant diff --git a/.github/workflows/runtime-pin-compat.yml b/.github/workflows/runtime-pin-compat.yml index 2672f355..919ddd70 100644 --- a/.github/workflows/runtime-pin-compat.yml +++ b/.github/workflows/runtime-pin-compat.yml @@ -60,8 +60,8 @@ jobs: name: PyPI-latest install + import smoke runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: python-version: '3.11' cache: pip diff --git a/.github/workflows/runtime-prbuild-compat.yml b/.github/workflows/runtime-prbuild-compat.yml index 41f8332a..0c8a14c4 100644 --- a/.github/workflows/runtime-prbuild-compat.yml +++ b/.github/workflows/runtime-prbuild-compat.yml @@ -61,8 +61,8 @@ jobs: name: PR-built wheel + import smoke runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: python-version: '3.11' cache: pip diff --git a/.github/workflows/secret-scan.yml b/.github/workflows/secret-scan.yml index cebf89e9..b5ffd550 100644 --- a/.github/workflows/secret-scan.yml +++ b/.github/workflows/secret-scan.yml @@ -40,7 +40,7 @@ jobs: name: Scan diff for credential-shaped strings runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 2 # need previous commit to diff against on push events diff --git a/.github/workflows/sweep-cf-orphans.yml b/.github/workflows/sweep-cf-orphans.yml index 7fb35328..c1033b26 100644 --- a/.github/workflows/sweep-cf-orphans.yml +++ b/.github/workflows/sweep-cf-orphans.yml @@ -78,7 +78,7 @@ jobs: MAX_DELETE_PCT: ${{ github.event.inputs.max_delete_pct || '50' }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Verify required secrets present id: verify diff --git a/.github/workflows/test-ops-scripts.yml b/.github/workflows/test-ops-scripts.yml index 9a3a5fa3..6a3bee85 100644 --- a/.github/workflows/test-ops-scripts.yml +++ b/.github/workflows/test-ops-scripts.yml @@ -27,8 +27,8 @@ jobs: name: Ops scripts (unittest) runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: python-version: '3.11' - name: Run unittest