diff --git a/.github/workflows/packer-gcp.yml b/.github/workflows/packer-gcp.yml index 1624baaee..4af588878 100644 --- a/.github/workflows/packer-gcp.yml +++ b/.github/workflows/packer-gcp.yml @@ -443,15 +443,19 @@ jobs: esac PACKAGE="ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/shifter-gce-${IMAGE_TYPE}" TAG="gce-${GCE_IMAGE_ID}" - DISK_PATH="$(mktemp "${RUNNER_TEMP}/${IMAGE_TYPE}.XXXXXX.tar.gz")" - trap 'rm -f "${DISK_PATH}"' EXIT + DISK_DIR="$(mktemp -d "${RUNNER_TEMP}/gce-disk.XXXXXX")" + DISK_FILE="${IMAGE_TYPE}.tar.gz" + trap 'rm -f "${DISK_DIR}/${DISK_FILE}"; rmdir "${DISK_DIR}"' EXIT # ORAS hashes a file before upload. Keep the disk out of the checkout # and clean it even when the registry upload fails. - gcloud storage cp --quiet "${GCE_BASE_DISK_URI}" "${DISK_PATH}" + gcloud storage cp --quiet "${GCE_BASE_DISK_URI}" "${DISK_DIR}/${DISK_FILE}" printf '%s' "${GH_TOKEN}" | oras login ghcr.io --username "${GITHUB_ACTOR}" --password-stdin # Provenance annotations bind the artifact to its protected build so the # tenant bootstrap can validate it before importing (issue #2309). The # digest-pinned reference (never the mutable tag) is the deploy input. + # ORAS rejects absolute file paths, so push the file by its relative + # name from its own directory. + cd "${DISK_DIR}" DIGEST="$(oras push --format json \ --artifact-type application/vnd.shifter.gce-image.v1 \ --annotation "org.opencontainers.image.revision=${GITHUB_SHA}" \ @@ -459,7 +463,7 @@ jobs: --annotation "com.shifter.image.gce-image-id=${GCE_IMAGE_ID}" \ --annotation "com.shifter.build.run-id=${GITHUB_RUN_ID}" \ --annotation "com.shifter.build.repository=${GITHUB_REPOSITORY}" \ - "${PACKAGE}:${TAG}" "${DISK_PATH}:application/vnd.shifter.gce-image.tar.gz" | jq -er '.digest')" + "${PACKAGE}:${TAG}" "${DISK_FILE}:application/vnd.shifter.gce-image.tar.gz" | jq -er '.digest')" case "${DIGEST}" in sha256:[0-9a-f][0-9a-f]*) ;; *) echo "::error::ORAS did not return an OCI manifest digest." exit 1 diff --git a/scripts/adr_guard/tests/test_deploy_workflow.py b/scripts/adr_guard/tests/test_deploy_workflow.py index 2813d6503..814d0f327 100644 --- a/scripts/adr_guard/tests/test_deploy_workflow.py +++ b/scripts/adr_guard/tests/test_deploy_workflow.py @@ -714,6 +714,9 @@ def test_gcp_base_image_publish_uses_gce_native_contract_and_protected_ref_gate( self.assertIn("oras-project/setup-oras@", build) self.assertIn("application/vnd.shifter.gce-image.tar.gz", build) self.assertIn("application/vnd.shifter.gce-image.v1", build) + # ORAS rejects absolute file paths: the disk is pushed by relative name. + self.assertIn('cd "${DISK_DIR}"', build) + self.assertIn('"${DISK_FILE}:application/vnd.shifter.gce-image.tar.gz"', build) self.assertIn("ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/shifter-gce-${IMAGE_TYPE}", build) self.assertIn("oci://${PACKAGE}@${DIGEST}", build) # Provenance annotations bind the artifact to its protected build.