fix release traceability validation target

This commit is contained in:
Haitao Pan 2026-04-12 17:41:43 +08:00
parent 78255baec1
commit 73da08f8ae
5 changed files with 81 additions and 3 deletions

View File

@ -47,7 +47,13 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: deploy needs: deploy
steps: steps:
- uses: actions/checkout@v4
- name: Verify traceability script cases
run: bash ./scripts/github-actions/test-validate-release-traceability.sh
- name: Validate runtime traceability - name: Validate runtime traceability
env: env:
SERVICE_IMAGE_REF: ${{ needs.build.outputs.service_image_ref }} SERVICE_IMAGE_REF: ${{ needs.build.outputs.service_image_ref }}
RUNTIME_PING_URL: https://accounts.svc.plus/api/ping
run: bash ./scripts/github-actions/validate-release-traceability.sh run: bash ./scripts/github-actions/validate-release-traceability.sh

View File

@ -9,6 +9,14 @@ upstream and downstream interfaces it depends on.
Returns the runtime image identity exposed by the running container. Returns the runtime image identity exposed by the running container.
Validation notes:
- release traceability checks this endpoint with `GET`, not `HEAD`
- `accounts.svc.plus/api/ping` is the current production validation target for
release identity
- empty `image`, `tag`, `commit`, or `version` means runtime image identity was
not injected correctly and should fail deployment validation
Example response: Example response:
```json ```json

View File

@ -16,12 +16,22 @@ release identity.
- Build must produce `service_image_ref` only from the full `GITHUB_SHA`. - Build must produce `service_image_ref` only from the full `GITHUB_SHA`.
- Deploy must consume `service_image_ref` and pass it through as the runtime - Deploy must consume `service_image_ref` and pass it through as the runtime
image identity. image identity.
- Validate must use `GET https://accounts.svc.plus/api/ping`.
- Validate must derive `tag` and `commit` from `service_image_ref` and compare - Validate must derive `tag` and `commit` from `service_image_ref` and compare
them against `/api/ping`. them against `/api/ping`.
- Validate must fail when runtime `image`, `tag`, `commit`, or `version` is
empty.
- Validate must compare `version` against the derived full commit, not a
synthetic fallback.
## External playbook alignment ## External playbook alignment
The external `playbooks/deploy_billing_service.yml` playbook should accept The external `playbooks/deploy_billing_service.yml` playbook should accept
`IMAGE_REF` (or an equivalent full image reference variable), derive any `IMAGE_REF` (or an equivalent full image reference variable), derive any
repo/tag helpers from it, and inject `IMAGE=<full image ref>` into the running repo/tag helpers from it, and inject `IMAGE=<full image ref>` into the running
container environment. container environment for the service exposed through
`https://accounts.svc.plus/api/ping`.
If `accounts.svc.plus/api/ping` keeps returning empty runtime metadata, treat
that as a deployment contract failure: the runtime did not receive the full
`IMAGE` value and release traceability is broken.

View File

@ -0,0 +1,44 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
script_path="${repo_root}/scripts/github-actions/validate-release-traceability.sh"
tmpdir="$(mktemp -d)"
trap 'rm -rf "${tmpdir}"' EXIT
service_image_ref="ghcr.io/x-evor/billing-service:sha-0123456789abcdef0123456789abcdef01234567"
run_success_case() {
local response_path="${tmpdir}/success.json"
cat > "${response_path}" <<'EOF'
{"image":"ghcr.io/x-evor/billing-service:sha-0123456789abcdef0123456789abcdef01234567","tag":"sha-0123456789abcdef0123456789abcdef01234567","commit":"0123456789abcdef0123456789abcdef01234567","version":"0123456789abcdef0123456789abcdef01234567","status":"ok"}
EOF
SERVICE_IMAGE_REF="${service_image_ref}" \
RUNTIME_PING_URL="file://${response_path}" \
bash "${script_path}"
}
run_failure_case() {
local name="$1"
local response_path="$2"
if SERVICE_IMAGE_REF="${service_image_ref}" \
RUNTIME_PING_URL="file://${response_path}" \
bash "${script_path}"; then
echo "expected ${name} to fail" >&2
exit 1
fi
}
cat > "${tmpdir}/empty.json" <<'EOF'
{"image":"","tag":"","commit":"","version":"","status":"ok"}
EOF
cat > "${tmpdir}/mismatch.json" <<'EOF'
{"image":"ghcr.io/x-evor/billing-service:sha-fedcba98765432100123456789abcdef01234567","tag":"sha-fedcba98765432100123456789abcdef01234567","commit":"fedcba98765432100123456789abcdef01234567","version":"fedcba98765432100123456789abcdef01234567","status":"ok"}
EOF
run_success_case
run_failure_case "empty runtime metadata" "${tmpdir}/empty.json"
run_failure_case "mismatched runtime metadata" "${tmpdir}/mismatch.json"

View File

@ -2,11 +2,21 @@
set -euo pipefail set -euo pipefail
service_image_ref="${SERVICE_IMAGE_REF:?SERVICE_IMAGE_REF is required}" service_image_ref="${SERVICE_IMAGE_REF:?SERVICE_IMAGE_REF is required}"
runtime_ping_url="${RUNTIME_PING_URL:?RUNTIME_PING_URL is required}"
tag="${service_image_ref##*:}" tag="${service_image_ref##*:}"
commit="${tag#sha-}" commit="${tag#sha-}"
curl -fsS "https://billing-service.example.com/api/ping" | jq -e \ curl -fsS "${runtime_ping_url}" | jq -e \
--arg image "${service_image_ref}" \ --arg image "${service_image_ref}" \
--arg tag "${tag}" \ --arg tag "${tag}" \
--arg commit "${commit}" \ --arg commit "${commit}" \
'.image == $image and .tag == $tag and .commit == $commit' '
(.image | type == "string" and length > 0) and
(.tag | type == "string" and length > 0) and
(.commit | type == "string" and length > 0) and
(.version | type == "string" and length > 0) and
.image == $image and
.tag == $tag and
.commit == $commit and
.version == $commit
' >/dev/null