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/packages/paperclip-runner/runner/crates/runner-core/src/codex_provider.rs b/packages/paperclip-runner/runner/crates/runner-core/src/codex_provider.rs index e98d120278..42bc7fd9c7 100644 --- a/packages/paperclip-runner/runner/crates/runner-core/src/codex_provider.rs +++ b/packages/paperclip-runner/runner/crates/runner-core/src/codex_provider.rs @@ -4186,7 +4186,17 @@ done #[test] fn github_credentials_cross_only_the_bounded_provider_environment() { assert_eq!(GITHUB_CREDENTIAL_ENVIRONMENT_KEYS.len(), 95); + assert_eq!( + GITHUB_CREDENTIAL_ENVIRONMENT_KEYS + .iter() + .collect::>() + .len(), + GITHUB_CREDENTIAL_ENVIRONMENT_KEYS.len(), + "provider environment keys must be unique", + ); for key in [ + "ZDOTDIR", + "BASH_ENV", "PAPERCLIP_RUNNER_NETWORK_ACCESS", "PAPERCLIP_RUNNER_NETWORK_ROOTS", "PAPERCLIP_GITHUB_AUTH_MODE", diff --git a/packages/paperclip-runner/runner/crates/runner-core/src/process_supervisor.rs b/packages/paperclip-runner/runner/crates/runner-core/src/process_supervisor.rs index 4df34e74d4..6e3ebe83ff 100644 --- a/packages/paperclip-runner/runner/crates/runner-core/src/process_supervisor.rs +++ b/packages/paperclip-runner/runner/crates/runner-core/src/process_supervisor.rs @@ -41,8 +41,6 @@ pub(crate) const GITHUB_CREDENTIAL_ENVIRONMENT_KEYS: &[&str] = &[ "GIT_SSH", "ZDOTDIR", "BASH_ENV", - "ZDOTDIR", - "BASH_ENV", "PAPERCLIP_GITHUB_BROKER_URL", "PAPERCLIP_GITHUB_BROKER_TOKEN", "PAPERCLIP_GITHUB_LAUNCHER_DIR", 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];