From 7f97b8c9681f81c64a8b9ee4817ddc832ff2b8c9 Mon Sep 17 00:00:00 2001 From: CHOU MING HUA Date: Thu, 6 Aug 2026 00:58:34 +0800 Subject: [PATCH] fix: preserve trusted recovery release context --- .github/workflows/preview-packages.yml | 4 ++++ packaging/resolve-metadata.sh | 13 +++++++++++-- packaging/validate-release-tag.sh | 6 ++++-- tests/PackagingAudit/Program.cs | 6 +++++- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/.github/workflows/preview-packages.yml b/.github/workflows/preview-packages.yml index 9d0b6e4..cc37f65 100644 --- a/.github/workflows/preview-packages.yml +++ b/.github/workflows/preview-packages.yml @@ -72,6 +72,7 @@ jobs: REF_NAME: ${{ github.ref_name }} PR_NUMBER: ${{ github.event.pull_request.number }} RUN_NUMBER: ${{ github.run_number }} + RELEASE_TAG: ${{ needs.release-gate.outputs.tag }} run: bash packaging/resolve-metadata.sh - name: Run the complete Windows regression and packaging audits run: | @@ -128,6 +129,7 @@ jobs: REF_NAME: ${{ github.ref_name }} PR_NUMBER: ${{ github.event.pull_request.number }} RUN_NUMBER: ${{ github.run_number }} + RELEASE_TAG: ${{ needs.release-gate.outputs.tag }} run: bash packaging/resolve-metadata.sh - name: Run shared and packaging audits run: | @@ -199,6 +201,7 @@ jobs: REF_NAME: ${{ github.ref_name }} PR_NUMBER: ${{ github.event.pull_request.number }} RUN_NUMBER: ${{ github.run_number }} + RELEASE_TAG: ${{ needs.release-gate.outputs.tag }} run: bash packaging/resolve-metadata.sh - name: Run shared and packaging audits run: | @@ -270,6 +273,7 @@ jobs: REF_NAME: ${{ github.ref_name }} PR_NUMBER: ${{ github.event.pull_request.number }} RUN_NUMBER: ${{ github.run_number }} + RELEASE_TAG: ${{ needs.release-gate.outputs.tag }} run: bash packaging/resolve-metadata.sh - name: Run shared and packaging audits run: | diff --git a/packaging/resolve-metadata.sh b/packaging/resolve-metadata.sh index 97c11c2..06b839c 100755 --- a/packaging/resolve-metadata.sh +++ b/packaging/resolve-metadata.sh @@ -10,7 +10,15 @@ if [[ ! "${project_version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+([-.][0-9A-Za-z.-]+)?$ ]] exit 2 fi -case "${REF_TYPE:-}:${EVENT_NAME:-}" in +if [[ -n "${RELEASE_TAG:-}" ]]; then + [[ "${RELEASE_TAG}" =~ ^v1\.1\.0-rc\.([1-9][0-9]*)$ ]] || { + echo "Recovery release tag must match v1.1.0-rc.N: ${RELEASE_TAG}" >&2 + exit 3 + } + package_label="${RELEASE_TAG}" + app_version="${package_label#v}" +else + case "${REF_TYPE:-}:${EVENT_NAME:-}" in tag:*) package_label="${REF_NAME:?REF_NAME is required for tag builds}" app_version="${package_label#v}" @@ -23,7 +31,8 @@ case "${REF_TYPE:-}:${EVENT_NAME:-}" in package_label="v${project_version}-preview.build${RUN_NUMBER:?RUN_NUMBER is required}" app_version="${project_version}" ;; -esac + esac +fi if [[ ! "${app_version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+([-.][0-9A-Za-z.-]+)?$ ]]; then echo "Resolved tag version is not valid semantic version text: ${app_version}" >&2 diff --git a/packaging/validate-release-tag.sh b/packaging/validate-release-tag.sh index 4c8f892..a4e4e52 100644 --- a/packaging/validate-release-tag.sh +++ b/packaging/validate-release-tag.sh @@ -8,6 +8,7 @@ input_tag="${INPUT_TAG:-}" tag_commit="${TAG_COMMIT:?TAG_COMMIT is required}" main_ref="${MAIN_REF:-origin/main}" publish="false" +release_tag="" resolved_commit="$(git rev-parse "${tag_commit}^{commit}")" if [[ "${event_name}" == "workflow_dispatch" && -n "${input_tag}" ]]; then @@ -29,12 +30,13 @@ if [[ ( "${event_name}" == "push" || "${event_name}" == "workflow_dispatch" ) && exit 3 fi publish="true" + release_tag="${ref_name}" fi if [[ -n "${GITHUB_OUTPUT:-}" ]]; then printf 'publish=%s\n' "${publish}" >> "${GITHUB_OUTPUT}" - printf 'tag=%s\n' "${ref_name}" >> "${GITHUB_OUTPUT}" + printf 'tag=%s\n' "${release_tag}" >> "${GITHUB_OUTPUT}" printf 'build_commit=%s\n' "${resolved_commit}" >> "${GITHUB_OUTPUT}" else - printf 'publish=%s\ntag=%s\nbuild_commit=%s\n' "${publish}" "${ref_name}" "${resolved_commit}" + printf 'publish=%s\ntag=%s\nbuild_commit=%s\n' "${publish}" "${release_tag}" "${resolved_commit}" fi diff --git a/tests/PackagingAudit/Program.cs b/tests/PackagingAudit/Program.cs index f567e41..3e5b19b 100644 --- a/tests/PackagingAudit/Program.cs +++ b/tests/PackagingAudit/Program.cs @@ -70,7 +70,9 @@ void Check(bool condition, string name) Check(metadataScript.Contains("REF_TYPE", StringComparison.Ordinal) && metadataScript.Contains("PR-${PR_NUMBER", StringComparison.Ordinal) && - metadataScript.Contains("preview.build", StringComparison.Ordinal), + metadataScript.Contains("preview.build", StringComparison.Ordinal) && + metadataScript.Contains("RELEASE_TAG", StringComparison.Ordinal) && + Regex.Matches(workflow, @"RELEASE_TAG: \$\{\{ needs\.release-gate\.outputs\.tag \}\}").Count >= 4, "Artifact labels distinguish tags, PR validation, and main-branch preview builds"); Check(sbomScript.Contains("Microsoft.Sbom.DotNetTool", StringComparison.Ordinal) && sbomScript.Contains("tool_version=\"4.1.5\"", StringComparison.Ordinal) && @@ -79,6 +81,8 @@ void Check(bool condition, string name) Check(releaseGateScript.Contains("^v1\\.1\\.0-rc\\.([1-9][0-9]*)$", StringComparison.Ordinal) && releaseGateScript.Contains("git merge-base --is-ancestor", StringComparison.Ordinal) && + releaseGateScript.Contains("release_tag=\"\"", StringComparison.Ordinal) && + releaseGateScript.Contains("release_tag=\"${ref_name}\"", StringComparison.Ordinal) && releaseGateScript.Contains("build_commit=%s", StringComparison.Ordinal) && workflow.Contains("+refs/heads/main:refs/remotes/origin/main", StringComparison.Ordinal), "Release authority requires an exact positive RC tag whose commit is contained in origin/main");