diff --git a/.github/workflows/docker-cloud.yml b/.github/workflows/docker-cloud.yml index 62025d3a85..38fb18e2f7 100644 --- a/.github/workflows/docker-cloud.yml +++ b/.github/workflows/docker-cloud.yml @@ -3,6 +3,13 @@ name: Docker cloud on: workflow_dispatch: workflow_call: + inputs: + staging_artifact_base_url: + type: string + default: "" + staging_lock_sha256: + type: string + default: "" permissions: {} @@ -98,9 +105,16 @@ jobs: node-version: 24 - name: Refresh lockfile for Docker build context + env: + STAGING_ARTIFACT_BASE_URL: ${{ inputs.staging_artifact_base_url }} + EXPECTED_LOCK_SHA256: ${{ inputs.staging_lock_sha256 }} run: | set -euo pipefail pnpm install --resolution-only --ignore-scripts --no-frozen-lockfile + if [ -n "$STAGING_ARTIFACT_BASE_URL" ]; then + [[ "$EXPECTED_LOCK_SHA256" =~ ^[a-f0-9]{64}$ ]] + echo "$EXPECTED_LOCK_SHA256 pnpm-lock.yaml" | sha256sum --check --strict + fi changed="$(git status --porcelain)" if [ -z "$changed" ]; then diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 4656225960..d74f75fd1d 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -427,6 +427,9 @@ jobs: build-and-push-cloud: if: github.event_name != 'push' || github.ref != 'refs/heads/master' uses: ./.github/workflows/docker-cloud.yml + with: + staging_artifact_base_url: ${{ inputs.staging_artifact_base_url || '' }} + staging_lock_sha256: ${{ inputs.staging_lock_sha256 || '' }} permissions: contents: read packages: write diff --git a/server/src/__tests__/docker-build-stamp.test.ts b/server/src/__tests__/docker-build-stamp.test.ts index 61d7a4e017..26a4737957 100644 --- a/server/src/__tests__/docker-build-stamp.test.ts +++ b/server/src/__tests__/docker-build-stamp.test.ts @@ -89,7 +89,12 @@ describe("staging dependency integrity", () => { }); it("checks the same lock in both staging app build contexts", () => { - const contexts = workflow.split(" - name: Refresh lockfile for Docker build context").slice(1); + const caller = workflow.split(" build-and-push-cloud:")[1].split(" # Moves")[0]; + expect(caller).toContain("uses: ./.github/workflows/docker-cloud.yml"); + expect(caller).toContain("staging_artifact_base_url: ${{ inputs.staging_artifact_base_url || '' }}"); + expect(caller).toContain("staging_lock_sha256: ${{ inputs.staging_lock_sha256 || '' }}"); + const contexts = [workflow, cloudWorkflow].flatMap((source) => + source.split(" - name: Refresh lockfile for Docker build context").slice(1)); expect(contexts).toHaveLength(2); for (const context of contexts) { const refresh = context.split(" - name:")[0];