diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a03b43f..19152bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,6 +46,18 @@ jobs: exit 1 fi + historical_sha="$(git rev-parse HEAD~1)" + git tag v0.0.0-m11.5b "$historical_sha" + if sh scripts/verify-release-ref.sh v0.0.0-m11.5b "$historical_sha"; then + echo "historical release unexpectedly accepted in strict mode" >&2 + exit 1 + fi + sh scripts/verify-release-ref.sh v0.0.0-m11.5b "$historical_sha" --allow-head-mismatch-for-audit + if sh scripts/verify-release-ref.sh v0.0.0-m11.5b "$historical_sha" --unknown-mode; then + echo "unknown verification mode unexpectedly accepted" >&2 + exit 1 + fi + - name: Verify exact-digest policy run: | digest="sha256:$(printf '%064d' 0)" diff --git a/.github/workflows/post-release-audit.yml b/.github/workflows/post-release-audit.yml index 326614b..e8b6fad 100644 --- a/.github/workflows/post-release-audit.yml +++ b/.github/workflows/post-release-audit.yml @@ -53,7 +53,11 @@ jobs: fi [[ -n "$tag" ]] tag_commit="$(git rev-list -n 1 "$tag")" - sh scripts/verify-release-ref.sh "$tag" "$tag_commit" + if [[ -n "$INPUT_TAG" ]]; then + sh scripts/verify-release-ref.sh "$tag" "$tag_commit" --allow-head-mismatch-for-audit + else + sh scripts/verify-release-ref.sh "$tag" "$tag_commit" + fi release_json="$(gh release view "$tag" --repo "$GITHUB_REPOSITORY" --json tagName,isDraft,isPrerelease)" jq -e --arg tag "$tag" '.tagName == $tag and .isDraft == false' <<<"$release_json" >/dev/null if [[ -n "$PRODUCER_SHA" ]]; then diff --git a/scripts/verify-release-ref.sh b/scripts/verify-release-ref.sh index 1c6c644..c374c6a 100644 --- a/scripts/verify-release-ref.sh +++ b/scripts/verify-release-ref.sh @@ -3,12 +3,21 @@ set -eu tag=${1:-${GITHUB_REF_NAME:-}} expected_sha=${2:-${GITHUB_SHA:-}} +mode=${3:-strict} if [ -z "$tag" ] || [ -z "$expected_sha" ]; then - echo "usage: verify-release-ref.sh " >&2 + echo "usage: verify-release-ref.sh [--allow-head-mismatch-for-audit]" >&2 exit 2 fi +case "$mode" in + strict|--allow-head-mismatch-for-audit) ;; + *) + echo "invalid verification mode: $mode" >&2 + exit 2 + ;; +esac + if ! printf '%s\n' "$tag" | grep -Eq '^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$'; then echo "invalid release tag: $tag" >&2 exit 1 @@ -24,10 +33,12 @@ if [ "$actual_sha" != "$expected_sha" ]; then exit 1 fi -head_sha=$(git rev-parse HEAD) -if [ "$head_sha" != "$expected_sha" ]; then - echo "checkout/commit mismatch: HEAD=$head_sha expected=$expected_sha" >&2 - exit 1 +if [ "$mode" = "strict" ]; then + head_sha=$(git rev-parse HEAD) + if [ "$head_sha" != "$expected_sha" ]; then + echo "checkout/commit mismatch: HEAD=$head_sha expected=$expected_sha" >&2 + exit 1 + fi fi -printf 'release ref verified: tag=%s commit=%s\n' "$tag" "$expected_sha" +printf 'release ref verified: tag=%s commit=%s mode=%s\n' "$tag" "$expected_sha" "$mode"