Skip to content

Commit b34ef0b

Browse files
authored
Merge pull request #859 from durable-workflow/fix/2116-published-verification-continuation
Continue release checks without rebuilding immutable images
2 parents f5399e8 + fbc2e05 commit b34ef0b

9 files changed

Lines changed: 438 additions & 12 deletions

‎.github/workflows/phpunit-feature.yml‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ jobs:
179179
180180
- name: Key the source-free PHP tool images
181181
id: php_tools_key
182-
run: echo "key=server-php-tools-v1-${{ runner.os }}-${{ runner.arch }}-$(date -u +%Y%m%d)-${{ hashFiles('Dockerfile', 'Dockerfile.dockerignore', '.dockerignore', 'docker/**') }}" >> "$GITHUB_OUTPUT"
182+
run: echo "key=server-php-tools-v2-${{ runner.os }}-${{ runner.arch }}-$(date -u +%Y%m%d)-${{ hashFiles('Dockerfile', 'Dockerfile.dockerignore', '.dockerignore', 'docker/**') }}" >> "$GITHUB_OUTPUT"
183183

184184
- name: Restore the source-free PHP tool images
185185
id: php_tools_cache
@@ -201,7 +201,7 @@ jobs:
201201
docker build -t durable-workflow-server-corpus-validator - <<'DOCKERFILE'
202202
FROM durable-workflow-server-phpunit-base
203203
RUN apt-get update \
204-
&& apt-get install -y --no-install-recommends git \
204+
&& apt-get install -y --no-install-recommends git jq \
205205
&& rm -rf /var/lib/apt/lists/* \
206206
&& server-verify-trust final
207207
DOCKERFILE
@@ -215,6 +215,8 @@ jobs:
215215
docker run --rm --network none --entrypoint server-verify-trust durable-workflow-server-phpunit-base
216216
docker run --rm --network none --entrypoint server-verify-trust durable-workflow-server-corpus-validator final
217217
docker run --rm --network none --entrypoint server-verify-brotli durable-workflow-server-corpus-validator
218+
docker run --rm --network none --entrypoint sh durable-workflow-server-corpus-validator \
219+
-c 'git --version && jq --version'
218220
219221
# Cache writes precede the dependency checkout and all application code.
220222
# These images contain only toolchains, qualified by the checks above.
@@ -353,7 +355,7 @@ jobs:
353355
-w /app \
354356
--entrypoint sh \
355357
durable-workflow-server-corpus-validator \
356-
-lc 'set -eu; tar --no-same-owner -xf - -C /app; cp -a /app/workflow-package /workflow; php scripts/ci/prepare-release-workflow-composer-metadata.php; composer update durable-workflow/workflow --with-dependencies --minimal-changes --no-install --no-scripts --no-autoloader --no-interaction --no-progress --prefer-dist; composer install --no-interaction --no-progress --prefer-dist; git --version; vendor/bin/phpunit --version; git rev-parse --verify "$CORPUS_BASE_REF^{commit}"; php scripts/ci/check-worker-openapi-evolution.php "$CORPUS_BASE_REF"; vendor/bin/phpunit tests/Feature tests/Unit/NexusContractTest.php tests/Unit/CodecRegressionCorpusTest.php tests/Unit/PhpunitFeatureWorkflowContractTest.php tests/Unit/OpenApiDocumentEvolutionTest.php tests/Unit/NamespaceConformanceRunnerContractTest.php tests/Unit/NamespaceRuntimeContractTest.php tests/Unit/SchedulesConformanceRunnerContractTest.php tests/Unit/SchedulesRuntimeContractTest.php tests/Unit/ServerParitySdkDirectionResponseSummaryTest.php tests/Unit/ServerParitySdkQueryTransportTest.php tests/Unit/ServerParitySdkUpdateTransportTest.php tests/Unit/ServerParityLockPressureRetryTest.php tests/Unit/ServerParityManyUpdatesRetryTest.php --no-progress --colors=never; vendor/bin/phpunit tests/Unit/ReleaseImageImmutabilityGuardTest.php --no-progress --colors=never; vendor/bin/phpunit tests/Unit/ReleaseImagePublishWorkflowContractTest.php --filter test_php_security_audits_fail_before_release_publication --no-progress --colors=never; python3 scripts/ci/validate-regression-corpus.py --base-ref "$CORPUS_BASE_REF" --verify-counterfactual'
358+
-lc 'set -eu; tar --no-same-owner -xf - -C /app; cp -a /app/workflow-package /workflow; php scripts/ci/prepare-release-workflow-composer-metadata.php; composer update durable-workflow/workflow --with-dependencies --minimal-changes --no-install --no-scripts --no-autoloader --no-interaction --no-progress --prefer-dist; composer install --no-interaction --no-progress --prefer-dist; git --version; vendor/bin/phpunit --version; git rev-parse --verify "$CORPUS_BASE_REF^{commit}"; php scripts/ci/check-worker-openapi-evolution.php "$CORPUS_BASE_REF"; vendor/bin/phpunit tests/Feature tests/Unit/NexusContractTest.php tests/Unit/CodecRegressionCorpusTest.php tests/Unit/PhpunitFeatureWorkflowContractTest.php tests/Unit/OpenApiDocumentEvolutionTest.php tests/Unit/NamespaceConformanceRunnerContractTest.php tests/Unit/NamespaceRuntimeContractTest.php tests/Unit/SchedulesConformanceRunnerContractTest.php tests/Unit/SchedulesRuntimeContractTest.php tests/Unit/ServerParitySdkDirectionResponseSummaryTest.php tests/Unit/ServerParitySdkQueryTransportTest.php tests/Unit/ServerParitySdkUpdateTransportTest.php tests/Unit/ServerParityLockPressureRetryTest.php tests/Unit/ServerParityManyUpdatesRetryTest.php --no-progress --colors=never; vendor/bin/phpunit tests/Unit/ReleaseImageContinuationTest.php tests/Unit/ReleaseImageImmutabilityGuardTest.php --no-progress --colors=never; vendor/bin/phpunit tests/Unit/ReleaseImagePublishWorkflowContractTest.php --filter test_php_security_audits_fail_before_release_publication --no-progress --colors=never; python3 scripts/ci/validate-regression-corpus.py --base-ref "$CORPUS_BASE_REF" --verify-counterfactual'
357359
358360
- name: Select production image qualification for changed build inputs
359361
id: image_inputs

‎.github/workflows/release.yml‎

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ on:
1414
release_commit:
1515
description: 'Full source commit for the existing immutable release tag'
1616
required: true
17+
existing_image_digest:
18+
description: 'Continue verification of this existing sha256 index without rebuilding images'
19+
required: false
20+
default: ''
21+
type: string
1722
permissions:
1823
contents: read
1924

@@ -104,6 +109,8 @@ jobs:
104109
id: release_publish
105110
env:
106111
INPUT_TAG: ${{ github.event.inputs.tag }}
112+
INPUT_RELEASE_COMMIT: ${{ inputs.release_commit }}
113+
INPUT_EXISTING_IMAGE_DIGEST: ${{ inputs.existing_image_digest }}
107114
SOURCE_RELEASE_VERSION: ${{ steps.source_release.outputs.version }}
108115
DOCKERHUB_IMAGE: ${{ env.DOCKERHUB_IMAGE }}
109116
GHCR_IMAGE: ${{ env.GHCR_IMAGE }}
@@ -179,6 +186,7 @@ jobs:
179186

180187
- name: Resolve shared release image cache
181188
id: cache
189+
if: ${{ steps.release_publish.outputs.verification_only != 'true' }}
182190
env:
183191
RELEASE_IMAGE_CACHE_ROOT: release-source
184192
RELEASE_SOURCE_COMMIT: ${{ steps.release_source.outputs.commit }}
@@ -188,16 +196,19 @@ jobs:
188196
run: node scripts/ci/resolve-release-image-cache.mjs
189197

190198
- name: Refuse replacement of published release images
199+
if: ${{ steps.release_publish.outputs.verification_only != 'true' }}
191200
env:
192201
RELEASE_TAG: ${{ steps.release_publish.outputs.tag }}
193202
run: sh scripts/ci/guard-unpublished-release-images.sh
194203

195204
- name: Start exact image build timer
196205
id: build_started
206+
if: ${{ steps.release_publish.outputs.verification_only != 'true' }}
197207
run: printf 'epoch_seconds=%s\n' "$(date +%s)" >> "$GITHUB_OUTPUT"
198208

199209
- name: Build and push exact image tags
200210
id: build
211+
if: ${{ steps.release_publish.outputs.verification_only != 'true' }}
201212
# Bound cold multi-architecture extension and application builds.
202213
timeout-minutes: 120
203214
continue-on-error: true
@@ -239,9 +250,11 @@ jobs:
239250
DOCKER_BUILD_OUTCOME: ${{ steps.build.outcome || 'skipped' }}
240251
BUILT_IMAGE_DIGEST: ${{ steps.build.outputs.digest }}
241252
BUILT_IMAGE_METADATA: ${{ steps.build.outputs.metadata }}
253+
RELEASE_IMAGE_VERIFICATION_ONLY: ${{ steps.release_publish.outputs.verification_only }}
254+
EXPECTED_IMAGE_DIGEST: ${{ steps.release_publish.outputs.existing_image_digest }}
242255
RELEASE_COMMIT: ${{ steps.release_source.outputs.commit }}
243-
RELEASE_RUN_ID: ${{ github.run_id }}
244-
RELEASE_RUN_ATTEMPT: ${{ github.run_attempt }}
256+
RELEASE_RUN_ID: ${{ steps.release_publish.outputs.verification_only != 'true' && github.run_id || '' }}
257+
RELEASE_RUN_ATTEMPT: ${{ steps.release_publish.outputs.verification_only != 'true' && github.run_attempt || '' }}
245258
WORKFLOW_PACKAGE_SOURCE: ${{ steps.workflow.outputs.source }}
246259
WORKFLOW_PACKAGE_REF: ${{ steps.workflow.outputs.ref }}
247260
WORKFLOW_PACKAGE_COMMIT: ${{ steps.workflow.outputs.commit }}
@@ -250,23 +263,27 @@ jobs:
250263
- name: Verify published image trust stores
251264
id: trust_stores
252265
if: ${{ always() && success() && steps.exact.outputs.exact_publish_outcome == 'success' }}
266+
timeout-minutes: 10
253267
env:
254-
RELEASE_IMAGE: ${{ env.DOCKERHUB_IMAGE }}:${{ steps.release_publish.outputs.tag }}
268+
RELEASE_IMAGE: ${{ env.DOCKERHUB_IMAGE }}@${{ steps.exact.outputs.image_digest }}
269+
DW_PULL_ATTEMPTS: "3"
270+
DW_PULL_BACKOFF_SECONDS: "2"
255271
run: |
256272
set -euo pipefail
257273
# GHSA-6q48-6c7w-9gw2: every published architecture's system, PHP,
258274
# Composer, Node and venv stores, checked offline in the image.
259275
IFS=',' read -ra platforms <<<"$RELEASE_IMAGE_PLATFORMS"
260276
for platform in "${platforms[@]}"; do
261-
docker run --rm --pull always --platform "$platform" --network none \
277+
DOCKER_DEFAULT_PLATFORM="$platform" bash scripts/ci/pull-images.sh "$RELEASE_IMAGE"
278+
docker run --rm --pull never --platform "$platform" --network none \
262279
--entrypoint server-verify-trust "$RELEASE_IMAGE"
263280
done
264281
265282
- name: Verify bare image first-run readiness
266283
id: first_run_readiness
267284
if: ${{ always() && success() && steps.exact.outputs.exact_publish_outcome == 'success' }}
268285
env:
269-
DW_SERVER_IMAGE: ${{ env.DOCKERHUB_IMAGE }}:${{ steps.release_publish.outputs.tag }}
286+
DW_SERVER_IMAGE: ${{ env.DOCKERHUB_IMAGE }}@${{ steps.exact.outputs.image_digest }}
270287
DW_FIRST_RUN_SCOPE: release-first-run-${{ github.run_id }}-${{ github.run_attempt }}-${{ github.job }}
271288
working-directory: release-source
272289
run: scripts/smoke-published-first-run.sh
@@ -275,7 +292,7 @@ jobs:
275292
id: source_free_compose
276293
if: ${{ always() && success() && steps.first_run_readiness.outcome == 'success' }}
277294
env:
278-
DW_SERVER_IMAGE: ${{ env.DOCKERHUB_IMAGE }}:${{ steps.release_publish.outputs.tag }}
295+
DW_SERVER_IMAGE: ${{ env.DOCKERHUB_IMAGE }}@${{ steps.exact.outputs.image_digest }}
279296
DW_SERVER_PLATFORM: linux/amd64
280297
DW_PUBLISHED_COMPOSE_PROFILE: local
281298
DW_PUBLISHED_COMPOSE_PROJECT: release-compose-${{ github.run_id }}-${{ github.run_attempt }}-${{ github.job }}
@@ -337,7 +354,7 @@ jobs:
337354
if: ${{ always() && success() && steps.exact.outputs.exact_publish_outcome == 'success' }}
338355
env:
339356
RELEASE_TAG: ${{ steps.release_publish.outputs.tag }}
340-
SERVER_IMAGE: ${{ env.DOCKERHUB_IMAGE }}:${{ steps.release_publish.outputs.tag }}
357+
SERVER_IMAGE: ${{ env.DOCKERHUB_IMAGE }}@${{ steps.exact.outputs.image_digest }}
341358
WORKFLOW_PACKAGE_SOURCE: ${{ steps.workflow.outputs.source }}
342359
WORKFLOW_PACKAGE_REF: ${{ steps.workflow.outputs.ref }}
343360
WORKFLOW_PACKAGE_COMMIT: ${{ steps.workflow.outputs.commit }}
@@ -357,6 +374,25 @@ jobs:
357374
docker volume rm -f "${RELEASE_PROTOCOL_CATALOG_SCOPE}-database" \
358375
>/dev/null 2>&1 || true
359376
377+
- name: Recheck immutable release identities before promotion
378+
env:
379+
GH_TOKEN: ${{ github.token }}
380+
RELEASE_TAG: ${{ steps.release_publish.outputs.tag }}
381+
RELEASE_COMMIT: ${{ steps.release_source.outputs.commit }}
382+
RELEASE_IMAGE_VERIFICATION_ONLY: "true"
383+
EXPECTED_IMAGE_DIGEST: ${{ steps.exact.outputs.image_digest }}
384+
DOCKER_BUILD_OUTCOME: skipped
385+
DOCKERHUB_IMAGE: ${{ env.DOCKERHUB_IMAGE }}
386+
GHCR_IMAGE: ${{ env.GHCR_IMAGE }}
387+
RELEASE_RUN_ID: ${{ steps.release_publish.outputs.verification_only != 'true' && github.run_id || '' }}
388+
RELEASE_RUN_ATTEMPT: ${{ steps.release_publish.outputs.verification_only != 'true' && github.run_attempt || '' }}
389+
WORKFLOW_PACKAGE_SOURCE: ${{ steps.workflow.outputs.source }}
390+
WORKFLOW_PACKAGE_REF: ${{ steps.workflow.outputs.ref }}
391+
WORKFLOW_PACKAGE_COMMIT: ${{ steps.workflow.outputs.commit }}
392+
run: |
393+
scripts/ci/verify-release-tag-source.sh
394+
scripts/ci/verify-release-exact-images.sh
395+
360396
- name: Resolve rolling image aliases
361397
id: rolling
362398
if: >-
@@ -380,6 +416,7 @@ jobs:
380416
DOCKERHUB_IMAGE: ${{ env.DOCKERHUB_IMAGE }}
381417
GHCR_IMAGE: ${{ env.GHCR_IMAGE }}
382418
ROLLING_SHOULD_PROMOTE: ${{ steps.rolling.outputs.rolling_should_promote }}
419+
VERIFIED_IMAGE_DIGEST: ${{ steps.exact.outputs.image_digest }}
383420
RELEASE_IMAGE_TAG_SOURCE_URL: ${{ github.server_url }}/${{ github.repository }}.git
384421
run: scripts/ci/promote-release-image-rolling-tags.sh
385422

@@ -445,6 +482,7 @@ jobs:
445482
needs: publish
446483
if: >-
447484
always() &&
485+
needs.publish.result == 'success' &&
448486
needs.publish.outputs.exact_publish_outcome == 'success' &&
449487
needs.publish.outputs.published_database_tls_outcome == 'success' &&
450488
github.repository == 'durable-workflow/server' &&

‎docs/helm-validation.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ TLS probes on the verified digest. It does not rebuild or replace an image.
2929
Both release paths require the TLS gate to pass before publishing the matching
3030
chart.
3131

32+
If exact images were uploaded but verification failed before the GitHub Release
33+
was created, dispatch the protected `Release` workflow from `main` with `tag`,
34+
the full `release_commit`, and `existing_image_digest` from the original upload.
35+
This explicit continuation skips image build and push. It verifies both
36+
registries and architectures against that index and source, then runs all normal
37+
trust-store, first-run, Compose, database TLS and protocol checks before the
38+
existing alias, GitHub Release and chart steps. The images retain their original
39+
publisher provenance. Do not rerun the image producer or replace immutable tags.
40+
3241
For a local repeat, set `TLS_TEST_MODE=published`, `TLS_TEST_IMAGE` to an
3342
immutable `repository@sha256:...` reference, and unique `TLS_TEST_PROJECT` and
3443
`TLS_TEST_ROOT` values, then run `scripts/ci/qualify-database-tls.sh`. The

‎scripts/ci/promote-release-image-rolling-tags.sh‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ dockerhub_image="${DOCKERHUB_IMAGE:-durableworkflow/server}"
77
ghcr_image="${GHCR_IMAGE:-ghcr.io/durable-workflow/server}"
88
docker_bin="${DOCKER:-docker}"
99
tag_source_url="${RELEASE_IMAGE_TAG_SOURCE_URL:-}"
10+
verified_image_digest="${VERIFIED_IMAGE_DIGEST:-}"
1011

1112
fail() {
1213
printf '::error title=%s::%s\n' "$1" "$2" >&2
@@ -82,6 +83,10 @@ if ! is_stable_semver_tag "$release_tag"; then
8283
fail "Stable semver tag required" "Rolling image aliases can only be promoted from stable semver tags; got '${release_tag}'."
8384
fi
8485

86+
if [ -n "$verified_image_digest" ] && ! printf '%s' "$verified_image_digest" | grep -Eq '^sha256:[0-9a-f]{64}$'; then
87+
fail "Invalid verified image digest" "Rolling aliases require an exact lowercase sha256 digest when VERIFIED_IMAGE_DIGEST is supplied."
88+
fi
89+
8590
major="${release_tag%%.*}"
8691
minor_patch="${release_tag#*.}"
8792
minor="${minor_patch%%.*}"
@@ -102,12 +107,16 @@ fi
102107

103108
promote_image() {
104109
image="$1"
110+
source_ref="${image}:${release_tag}"
111+
if [ -n "$verified_image_digest" ]; then
112+
source_ref="${image}@${verified_image_digest}"
113+
fi
105114

106115
"$docker_bin" buildx imagetools create \
107116
--tag "${image}:${minor_alias}" \
108117
--tag "${image}:${major_alias}" \
109118
--tag "${image}:latest" \
110-
"${image}:${release_tag}"
119+
"$source_ref"
111120
}
112121

113122
promote_image "$dockerhub_image"

‎scripts/ci/validate-release-image-publish.sh‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ dockerhub_image="${DOCKERHUB_IMAGE:-durableworkflow/server}"
66
ghcr_image="${GHCR_IMAGE:-ghcr.io/durable-workflow/server}"
77
release_tag=""
88
missing_credentials=""
9+
existing_image_digest="${INPUT_EXISTING_IMAGE_DIGEST:-}"
10+
verification_only=false
911

1012
fail() {
1113
title="$1"
@@ -79,6 +81,19 @@ if [ -n "$source_release_version" ]; then
7981
fi
8082
fi
8183

84+
if [ -n "$existing_image_digest" ]; then
85+
if [ "${GITHUB_EVENT_NAME:-}" != workflow_dispatch ] || [ "${GITHUB_REF:-}" != refs/heads/main ]; then
86+
fail "Invalid release continuation context" "Existing image verification requires workflow_dispatch from main."
87+
fi
88+
if ! printf '%s' "$existing_image_digest" | grep -Eq '^sha256:[0-9a-f]{64}$'; then
89+
fail "Invalid existing image digest" "Existing image verification requires an exact lowercase sha256 index digest."
90+
fi
91+
if ! printf '%s' "${INPUT_RELEASE_COMMIT:-}" | grep -Eq '^[0-9a-f]{40}$'; then
92+
fail "Invalid release continuation source" "Existing image verification requires the full lowercase source commit for the immutable tag."
93+
fi
94+
verification_only=true
95+
fi
96+
8297
if [ -z "${DOCKERHUB_USERNAME:-}" ]; then
8398
append_missing_credential "DOCKERHUB_USERNAME"
8499
fi
@@ -98,6 +113,8 @@ fi
98113
if [ -n "${GITHUB_OUTPUT:-}" ]; then
99114
{
100115
printf 'tag=%s\n' "$release_tag"
116+
printf 'verification_only=%s\n' "$verification_only"
117+
printf 'existing_image_digest=%s\n' "$existing_image_digest"
101118
if is_semver_tag "$release_tag"; then
102119
printf 'is_semver=true\n'
103120
else

‎scripts/ci/verify-release-exact-images.sh‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ docker_bin="${DOCKER:-docker}"
99
build_outcome="${DOCKER_BUILD_OUTCOME:-}"
1010
built_image_digest="${BUILT_IMAGE_DIGEST:-}"
1111
built_image_metadata="${BUILT_IMAGE_METADATA:-}"
12+
requested_image_digest="${EXPECTED_IMAGE_DIGEST:-}"
1213
release_commit="${RELEASE_COMMIT:-}"
1314
run_id="${RELEASE_RUN_ID:-}"
1415
run_attempt="${RELEASE_RUN_ATTEMPT:-}"
@@ -136,6 +137,19 @@ case "$verification_only" in
136137
;;
137138
esac
138139

140+
if [ -n "$requested_image_digest" ]; then
141+
if [ "$verification_only" != true ] || ! printf '%s' "$requested_image_digest" | grep -Eq '^sha256:[0-9a-f]{64}$'; then
142+
fail "Invalid release continuation digest" "An expected existing-image digest requires verification-only mode and an exact lowercase sha256 index." "exact_continuation_digest_invalid"
143+
fi
144+
if [ "${build_outcome:-skipped}" != skipped ] || [ -n "$built_image_digest" ] || [ -n "$built_image_metadata" ]; then
145+
fail "Release continuation must not build images" "Existing immutable-image continuation requires the producer to be skipped with no new build metadata." "exact_continuation_producer_ran"
146+
fi
147+
if [ -z "$workflow_package_source" ] || [ -z "$workflow_package_ref" ] \
148+
|| ! printf '%s' "$workflow_package_commit" | grep -Eq '^[0-9a-f]{40}$'; then
149+
fail "Release continuation package authority missing" "Existing immutable-image continuation requires the complete locked Workflow source, version and commit." "exact_continuation_package_authority_missing"
150+
fi
151+
fi
152+
139153
if ! printf '%s' "$release_tag" | grep -Eq '^[0-9A-Za-z._-]+$'; then
140154
fail "Invalid exact release image tag" "Release image tag '${release_tag}' contains characters that are not safe for Docker tags." "exact_release_tag_invalid"
141155
fi
@@ -190,6 +204,9 @@ if [ -n "$direct_build_digest" ]; then
190204
else
191205
expected_image_digest="$metadata_build_digest"
192206
fi
207+
if [ -n "$requested_image_digest" ]; then
208+
expected_image_digest="$requested_image_digest"
209+
fi
193210

194211
if [ -z "$expected_image_digest" ]; then
195212
if [ "$verify_published_metadata" != "true" ]; then
@@ -234,6 +251,9 @@ inspect_ref() {
234251
fi
235252

236253
if [ -n "$expected_image_digest" ] && [ "$expected_image_digest" != "$digest" ]; then
254+
if [ -n "$requested_image_digest" ]; then
255+
fail "Exact release continuation digest mismatch" "Published exact image manifest ${ref} has digest ${digest}, but continuation requires ${expected_image_digest}." "exact_continuation_digest_mismatch"
256+
fi
237257
fail "Exact release image build digest mismatch" "Published exact image manifest ${ref} has digest ${digest}, but this release build produced ${expected_image_digest}." "exact_manifest_build_digest_mismatch"
238258
fi
239259

0 commit comments

Comments
 (0)