chore(security): pin Actions to SHAs + enable Dependabot auto-bumps

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<N>` tags to a payload that exfiltrated
repository secrets. Repos that pinned to SHAs were unaffected.

The fix

Replace each `@v<N>` with `@<commit-sha> # v<N>`. 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) <noreply@anthropic.com>
This commit is contained in:
Hongming Wang 2026-04-28 15:37:06 -07:00
parent 81634e04d1
commit c77a88c247
24 changed files with 139 additions and 59 deletions

80
.github/dependabot.yml vendored Normal file
View File

@ -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<N>` 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

View File

@ -65,7 +65,7 @@ jobs:
echo "short=${FULL:0:7}" >> "$GITHUB_OUTPUT" echo "short=${FULL:0:7}" >> "$GITHUB_OUTPUT"
echo "full=${FULL}" >> "$GITHUB_OUTPUT" echo "full=${FULL}" >> "$GITHUB_OUTPUT"
- uses: imjasonh/setup-crane@v0.4 - uses: imjasonh/setup-crane@31b88efe9de28ae0ffa220711af4b60be9435f6e # v0.4
- name: GHCR login - name: GHCR login
run: | run: |

View File

@ -152,7 +152,7 @@ jobs:
- name: Checkout main - name: Checkout main
if: ${{ vars.AUTO_PROMOTE_ENABLED == 'true' || github.event.inputs.force == 'true' }} if: ${{ vars.AUTO_PROMOTE_ENABLED == 'true' || github.event.inputs.force == 'true' }}
uses: actions/checkout@v4 uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with: with:
ref: main ref: main
fetch-depth: 0 fetch-depth: 0

View File

@ -63,7 +63,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout staging - name: Checkout staging
uses: actions/checkout@v4 uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with: with:
fetch-depth: 0 fetch-depth: 0
ref: staging ref: staging

View File

@ -38,7 +38,7 @@ jobs:
tag: tag:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with: with:
fetch-depth: 0 # need full tag history for `git describe` / sort fetch-depth: 0 # need full tag history for `git describe` / sort

View File

@ -26,7 +26,7 @@ jobs:
name: Block forbidden paths name: Block forbidden paths
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with: with:
fetch-depth: 2 # need previous commit to diff against on push events fetch-depth: 2 # need previous commit to diff against on push events

View File

@ -66,7 +66,7 @@ jobs:
E2E_RUN_ID: "canary-${{ github.run_id }}" E2E_RUN_ID: "canary-${{ github.run_id }}"
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Verify admin token present - name: Verify admin token present
run: | run: |
@ -98,7 +98,7 @@ jobs:
# next deploy window. # next deploy window.
- name: Open issue on failure - name: Open issue on failure
if: failure() if: failure()
uses: actions/github-script@v7 uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
env: env:
# Inject the workflow path explicitly — context.workflow is # Inject the workflow path explicitly — context.workflow is
# the *name*, not the file path the actions API needs. # the *name*, not the file path the actions API needs.
@ -165,7 +165,7 @@ jobs:
- name: Auto-close canary issue on success - name: Auto-close canary issue on success
if: success() if: success()
uses: actions/github-script@v7 uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
with: with:
script: | script: |
const title = '🔴 Canary failing: staging SaaS smoke'; const title = '🔴 Canary failing: staging SaaS smoke';

View File

@ -40,7 +40,7 @@ jobs:
smoke_ran: ${{ steps.smoke.outputs.ran }} smoke_ran: ${{ steps.smoke.outputs.ran }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Compute sha - name: Compute sha
id: compute id: compute
@ -143,7 +143,7 @@ jobs:
if: ${{ needs.canary-smoke.result == 'success' && needs.canary-smoke.outputs.smoke_ran == 'true' }} if: ${{ needs.canary-smoke.result == 'success' && needs.canary-smoke.outputs.smoke_ran == 'true' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: imjasonh/setup-crane@v0.4 - uses: imjasonh/setup-crane@31b88efe9de28ae0ffa220711af4b60be9435f6e # v0.4
- name: GHCR login - name: GHCR login
run: | run: |

View File

@ -36,7 +36,7 @@ jobs:
permissions: permissions:
contents: read contents: read
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Verify merge_group trigger on required-check workflows - name: Verify merge_group trigger on required-check workflows
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -32,7 +32,7 @@ jobs:
python: ${{ steps.check.outputs.python }} python: ${{ steps.check.outputs.python }}
scripts: ${{ steps.check.outputs.scripts }} scripts: ${{ steps.check.outputs.scripts }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with: with:
fetch-depth: 0 fetch-depth: 0
- id: check - id: check
@ -72,8 +72,8 @@ jobs:
run: run:
working-directory: workspace-server working-directory: workspace-server
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-go@v5 - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with: with:
go-version: 'stable' go-version: 'stable'
- run: go mod download - run: go mod download
@ -187,8 +187,8 @@ jobs:
run: run:
working-directory: canvas working-directory: canvas
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@v4 - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with: with:
node-version: '22' node-version: '22'
- run: rm -f package-lock.json && npm install - run: rm -f package-lock.json && npm install
@ -210,7 +210,7 @@ jobs:
if: needs.changes.outputs.scripts == 'true' if: needs.changes.outputs.scripts == 'true'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Run shellcheck on tests/e2e/*.sh and infra/scripts/*.sh - name: Run shellcheck on tests/e2e/*.sh and infra/scripts/*.sh
# shellcheck is pre-installed on ubuntu-latest runners (via apt). # shellcheck is pre-installed on ubuntu-latest runners (via apt).
# infra/scripts/ is included because setup.sh + nuke.sh gate the # infra/scripts/ is included because setup.sh + nuke.sh gate the
@ -276,8 +276,8 @@ jobs:
run: run:
working-directory: workspace working-directory: workspace
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-python@v5 - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with: with:
python-version: '3.11' python-version: '3.11'
cache: pip cache: pip

View File

@ -53,14 +53,14 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Checkout sibling plugin repo - name: Checkout sibling plugin repo
# Same reasoning as publish-workspace-server-image.yml — the Go # Same reasoning as publish-workspace-server-image.yml — the Go
# module's replace directive needs the plugin source so # module's replace directive needs the plugin source so
# CodeQL's "go build" phase can resolve. # CodeQL's "go build" phase can resolve.
if: matrix.language == 'go' if: matrix.language == 'go'
uses: actions/checkout@v4 uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with: with:
repository: Molecule-AI/molecule-ai-plugin-github-app-auth repository: Molecule-AI/molecule-ai-plugin-github-app-auth
path: 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. # jq is pre-installed on ubuntu-latest — no setup step needed.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v3 uses: github/codeql-action/init@ce64ddcb0d8d890d2df4a9d1c04ff297367dea2a # v3
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# security-extended widens past the default to include the # security-extended widens past the default to include the
@ -77,11 +77,11 @@ jobs:
queries: security-extended queries: security-extended
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v3 uses: github/codeql-action/autobuild@ce64ddcb0d8d890d2df4a9d1c04ff297367dea2a # v3
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
id: analyze id: analyze
uses: github/codeql-action/analyze@v3 uses: github/codeql-action/analyze@ce64ddcb0d8d890d2df4a9d1c04ff297367dea2a # v3
with: with:
category: "/language:${{ matrix.language }}" category: "/language:${{ matrix.language }}"
# upload: never — GHAS isn't enabled on this repo, so the # 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 # 14-day retention — longer than default 3, short enough not
# to bloat quota. # to bloat quota.
if: always() if: always()
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with: with:
name: codeql-sarif-${{ matrix.language }} name: codeql-sarif-${{ matrix.language }}
path: sarif-results/${{ matrix.language }}/ path: sarif-results/${{ matrix.language }}/

View File

@ -36,8 +36,8 @@ jobs:
outputs: outputs:
api: ${{ steps.decide.outputs.api }} api: ${{ steps.decide.outputs.api }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: dorny/paths-filter@v3 - uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3
id: filter id: filter
with: with:
filters: | filters: |
@ -78,8 +78,8 @@ jobs:
PG_CONTAINER: molecule-ci-postgres PG_CONTAINER: molecule-ci-postgres
REDIS_CONTAINER: molecule-ci-redis REDIS_CONTAINER: molecule-ci-redis
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-go@v5 - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with: with:
go-version: 'stable' go-version: 'stable'
cache: true cache: true

View File

@ -46,8 +46,8 @@ jobs:
outputs: outputs:
canvas: ${{ steps.decide.outputs.canvas }} canvas: ${{ steps.decide.outputs.canvas }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: dorny/paths-filter@v3 - uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3
id: filter id: filter
with: with:
filters: | filters: |
@ -90,7 +90,7 @@ jobs:
working-directory: canvas working-directory: canvas
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Verify admin token present - name: Verify admin token present
run: | run: |
@ -100,7 +100,7 @@ jobs:
fi fi
- name: Set up Node - name: Set up Node
uses: actions/setup-node@v4 uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with: with:
node-version: '20' node-version: '20'
cache: 'npm' cache: 'npm'
@ -117,7 +117,7 @@ jobs:
- name: Upload Playwright report on failure - name: Upload Playwright report on failure
if: failure() if: failure()
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with: with:
name: playwright-report-staging name: playwright-report-staging
path: canvas/playwright-report-staging/ path: canvas/playwright-report-staging/
@ -125,7 +125,7 @@ jobs:
- name: Upload screenshots on failure - name: Upload screenshots on failure
if: failure() if: failure()
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with: with:
name: playwright-screenshots name: playwright-screenshots
path: canvas/test-results/ path: canvas/test-results/

View File

@ -92,7 +92,7 @@ jobs:
E2E_KEEP_ORG: ${{ github.event.inputs.keep_org && '1' || '0' }} E2E_KEEP_ORG: ${{ github.event.inputs.keep_org && '1' || '0' }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Verify admin token present - name: Verify admin token present
run: | run: |

View File

@ -50,7 +50,7 @@ jobs:
E2E_INTENTIONAL_FAILURE: "1" E2E_INTENTIONAL_FAILURE: "1"
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Verify admin token present - name: Verify admin token present
run: | run: |
@ -89,7 +89,7 @@ jobs:
- name: Open issue if safety net is broken - name: Open issue if safety net is broken
if: failure() if: failure()
uses: actions/github-script@v7 uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7
with: with:
script: | script: |
const title = "🚨 E2E teardown safety net broken"; const title = "🚨 E2E teardown safety net broken";

View File

@ -34,7 +34,7 @@ jobs:
promote: promote:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: imjasonh/setup-crane@v0.4 - uses: imjasonh/setup-crane@31b88efe9de28ae0ffa220711af4b60be9435f6e # v0.4
- name: GHCR login - name: GHCR login
run: | run: |

View File

@ -42,17 +42,17 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Log in to GHCR - name: Log in to GHCR
uses: docker/login-action@v3 uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
- name: Compute tags - name: Compute tags
id: tags id: tags
@ -85,7 +85,7 @@ jobs:
echo "ws_url=${WS_URL}" >> "$GITHUB_OUTPUT" echo "ws_url=${WS_URL}" >> "$GITHUB_OUTPUT"
- name: Build & push canvas image to GHCR - name: Build & push canvas image to GHCR
uses: docker/build-push-action@v6 uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with: with:
context: ./canvas context: ./canvas
file: ./canvas/Dockerfile file: ./canvas/Dockerfile

View File

@ -81,9 +81,9 @@ jobs:
version: ${{ steps.version.outputs.version }} version: ${{ steps.version.outputs.version }}
wheel_sha256: ${{ steps.wheel_hash.outputs.wheel_sha256 }} wheel_sha256: ${{ steps.wheel_hash.outputs.wheel_sha256 }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-python@v5 - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with: with:
python-version: "3.11" python-version: "3.11"
cache: pip cache: pip

View File

@ -27,7 +27,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Checkout sibling plugin repo - name: Checkout sibling plugin repo
# workspace-server/Dockerfile expects # workspace-server/Dockerfile expects
@ -42,21 +42,21 @@ jobs:
# The PAT needs Contents:Read on Molecule-AI/molecule-ai-plugin- # The PAT needs Contents:Read on Molecule-AI/molecule-ai-plugin-
# github-app-auth. Falls back to the default token for the (rare) # github-app-auth. Falls back to the default token for the (rare)
# case where an operator made the plugin repo public. # case where an operator made the plugin repo public.
uses: actions/checkout@v4 uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with: with:
repository: Molecule-AI/molecule-ai-plugin-github-app-auth repository: Molecule-AI/molecule-ai-plugin-github-app-auth
path: molecule-ai-plugin-github-app-auth path: molecule-ai-plugin-github-app-auth
token: ${{ secrets.PLUGIN_REPO_PAT || secrets.GITHUB_TOKEN }} token: ${{ secrets.PLUGIN_REPO_PAT || secrets.GITHUB_TOKEN }}
- name: Log in to GHCR - name: Log in to GHCR
uses: docker/login-action@v3 uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
- name: Compute tags - name: Compute tags
id: tags id: tags
@ -87,7 +87,7 @@ jobs:
# applyRuntimeModelEnv and caused every E2E to route hermes+openai # applyRuntimeModelEnv and caused every E2E to route hermes+openai
# through openrouter → 401). See issue filed with this PR. # through openrouter → 401). See issue filed with this PR.
- name: Build & push platform image to GHCR (staging-<sha> + staging-latest) - name: Build & push platform image to GHCR (staging-<sha> + staging-latest)
uses: docker/build-push-action@v6 uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with: with:
context: . context: .
file: ./workspace-server/Dockerfile file: ./workspace-server/Dockerfile
@ -104,7 +104,7 @@ jobs:
org.opencontainers.image.description=Molecule AI platform (Go API server) — pending canary verify org.opencontainers.image.description=Molecule AI platform (Go API server) — pending canary verify
- name: Build & push tenant image to GHCR (staging-<sha> + staging-latest) - name: Build & push tenant image to GHCR (staging-<sha> + staging-latest)
uses: docker/build-push-action@v6 uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with: with:
context: . context: .
file: ./workspace-server/Dockerfile.tenant file: ./workspace-server/Dockerfile.tenant

View File

@ -60,8 +60,8 @@ jobs:
name: PyPI-latest install + import smoke name: PyPI-latest install + import smoke
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-python@v5 - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with: with:
python-version: '3.11' python-version: '3.11'
cache: pip cache: pip

View File

@ -61,8 +61,8 @@ jobs:
name: PR-built wheel + import smoke name: PR-built wheel + import smoke
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-python@v5 - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with: with:
python-version: '3.11' python-version: '3.11'
cache: pip cache: pip

View File

@ -40,7 +40,7 @@ jobs:
name: Scan diff for credential-shaped strings name: Scan diff for credential-shaped strings
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with: with:
fetch-depth: 2 # need previous commit to diff against on push events fetch-depth: 2 # need previous commit to diff against on push events

View File

@ -78,7 +78,7 @@ jobs:
MAX_DELETE_PCT: ${{ github.event.inputs.max_delete_pct || '50' }} MAX_DELETE_PCT: ${{ github.event.inputs.max_delete_pct || '50' }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Verify required secrets present - name: Verify required secrets present
id: verify id: verify

View File

@ -27,8 +27,8 @@ jobs:
name: Ops scripts (unittest) name: Ops scripts (unittest)
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-python@v5 - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with: with:
python-version: '3.11' python-version: '3.11'
- name: Run unittest - name: Run unittest