mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
fix(release): accept trusted extended-stable validation evidence (#119264)
* fix(release): accept trusted extended-stable validation evidence * fix(release): document trusted candidate promotion * docs(release): clarify validation evidence recovery
This commit is contained in:
@@ -32,6 +32,11 @@ on:
|
||||
description: Successful Plugin NPM Release run id for the exact extended-stable branch and release SHA
|
||||
required: false
|
||||
type: string
|
||||
release_candidate_branch:
|
||||
description: Canonical extended-stable branch when a trusted main workflow promotes its immutable tag
|
||||
required: false
|
||||
default: ""
|
||||
type: string
|
||||
npm_dist_tag:
|
||||
description: npm dist-tag to publish to
|
||||
required: true
|
||||
@@ -709,6 +714,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
ref: ${{ inputs.release_candidate_branch != '' && format('refs/tags/{0}', inputs.tag) || github.sha }}
|
||||
fetch-depth: 0
|
||||
filter: blob:none
|
||||
persist-credentials: false
|
||||
@@ -718,13 +724,14 @@ jobs:
|
||||
BYPASS_EXTENDED_STABLE_GUARD: ${{ inputs.bypass_extended_stable_guard }}
|
||||
RELEASE_NPM_DIST_TAG: ${{ inputs.npm_dist_tag }}
|
||||
RELEASE_TAG: ${{ inputs.tag }}
|
||||
NPM_WORKFLOW_REF: ${{ github.ref }}
|
||||
NPM_WORKFLOW_REF: ${{ inputs.release_candidate_branch != '' && format('refs/heads/{0}', inputs.release_candidate_branch) || github.ref }}
|
||||
run: node scripts/openclaw-npm-extended-stable-release.mjs validate-request
|
||||
|
||||
- name: Require trusted workflow ref for publish
|
||||
env:
|
||||
RELEASE_TAG: ${{ inputs.tag }}
|
||||
RELEASE_NPM_DIST_TAG: ${{ inputs.npm_dist_tag }}
|
||||
RELEASE_CANDIDATE_BRANCH: ${{ inputs.release_candidate_branch }}
|
||||
WORKFLOW_REF: ${{ github.ref }}
|
||||
WORKFLOW_SHA: ${{ github.workflow_sha }}
|
||||
run: |
|
||||
@@ -732,12 +739,29 @@ jobs:
|
||||
tideclaw_alpha_publish=false
|
||||
extended_stable_publish=false
|
||||
sha_pinned_release_publish=false
|
||||
release_candidate_branch="${RELEASE_CANDIDATE_BRANCH:-}"
|
||||
if [[ "${RELEASE_TAG}" == *"-alpha."* && "${RELEASE_NPM_DIST_TAG}" == "alpha" && "${WORKFLOW_REF}" =~ ^refs/heads/tideclaw/alpha/[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{4}Z$ ]]; then
|
||||
tideclaw_alpha_publish=true
|
||||
fi
|
||||
if [[ "${RELEASE_NPM_DIST_TAG}" == "extended-stable" && "${WORKFLOW_REF}" == refs/heads/extended-stable/* ]]; then
|
||||
extended_stable_publish=true
|
||||
fi
|
||||
if [[ -n "${release_candidate_branch}" ]]; then
|
||||
if [[ "${RELEASE_NPM_DIST_TAG}" != "extended-stable" || "${WORKFLOW_REF}" != "refs/heads/main" ]]; then
|
||||
echo "release_candidate_branch is only valid for an extended-stable publish dispatched from main." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! "${RELEASE_TAG}" =~ ^v([0-9]{4})\.([1-9][0-9]*)\.[1-9][0-9]*$ ]]; then
|
||||
echo "release_candidate_branch requires an exact final release tag." >&2
|
||||
exit 1
|
||||
fi
|
||||
expected_candidate_branch="extended-stable/${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.33"
|
||||
if [[ "${release_candidate_branch}" != "${expected_candidate_branch}" ]]; then
|
||||
echo "release_candidate_branch must be ${expected_candidate_branch} for ${RELEASE_TAG}." >&2
|
||||
exit 1
|
||||
fi
|
||||
extended_stable_publish=true
|
||||
fi
|
||||
if [[ "${WORKFLOW_REF}" =~ ^refs/tags/release-publish/([a-f0-9]{12})-[1-9][0-9]*$ ]]; then
|
||||
workflow_sha_prefix="${BASH_REMATCH[1]}"
|
||||
[[ "${WORKFLOW_SHA}" =~ ^[a-f0-9]{40}$ && "${WORKFLOW_SHA:0:12}" == "${workflow_sha_prefix}" ]] || {
|
||||
@@ -857,6 +881,16 @@ jobs:
|
||||
# tarball, so real publishes do not need the repository's full history.
|
||||
fetch-depth: ${{ inputs.preflight_run_id != '' && 1 || 0 }}
|
||||
|
||||
- name: Checkout trusted validation verifier
|
||||
if: ${{ inputs.full_release_validation_run_id != '' }}
|
||||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
ref: ${{ github.workflow_sha }}
|
||||
path: trusted-workflow
|
||||
fetch-depth: 0
|
||||
filter: blob:none
|
||||
persist-credentials: false
|
||||
|
||||
- name: Validate Tideclaw alpha publish target
|
||||
if: startsWith(github.ref, 'refs/heads/tideclaw/alpha/')
|
||||
env:
|
||||
@@ -902,7 +936,7 @@ jobs:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
PREFLIGHT_RUN_ID: ${{ inputs.preflight_run_id }}
|
||||
RELEASE_NPM_DIST_TAG: ${{ inputs.npm_dist_tag }}
|
||||
EXPECTED_EXTENDED_STABLE_BRANCH: ${{ github.ref_name }}
|
||||
EXPECTED_EXTENDED_STABLE_BRANCH: ${{ inputs.release_candidate_branch || github.ref_name }}
|
||||
RUN_KIND: preflight
|
||||
run: |
|
||||
set -euo pipefail
|
||||
@@ -911,37 +945,32 @@ jobs:
|
||||
RUN_JSON="$(gh run view "$PREFLIGHT_RUN_ID" --repo "$GITHUB_REPOSITORY" --json workflowName,headBranch,headSha,event,conclusion,url)"
|
||||
printf '%s' "$RUN_JSON" | node scripts/openclaw-npm-extended-stable-release.mjs verify-run
|
||||
|
||||
- name: Verify full release validation run metadata
|
||||
id: full_run
|
||||
- name: Download full release validation manifest
|
||||
if: ${{ inputs.full_release_validation_run_id != '' }}
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
with:
|
||||
name: full-release-validation-${{ inputs.full_release_validation_run_id }}-${{ inputs.full_release_validation_run_attempt }}
|
||||
path: full-release-validation
|
||||
repository: ${{ github.repository }}
|
||||
run-id: ${{ inputs.full_release_validation_run_id }}
|
||||
github-token: ${{ github.token }}
|
||||
|
||||
- name: Verify full release validation evidence
|
||||
if: ${{ inputs.full_release_validation_run_id != '' }}
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
FULL_RELEASE_VALIDATION_RUN_ID: ${{ inputs.full_release_validation_run_id }}
|
||||
FULL_RELEASE_VALIDATION_RUN_ATTEMPT: ${{ inputs.full_release_validation_run_attempt }}
|
||||
RELEASE_NPM_DIST_TAG: ${{ inputs.npm_dist_tag }}
|
||||
EXPECTED_EXTENDED_STABLE_BRANCH: ${{ github.ref_name }}
|
||||
RUN_KIND: validation
|
||||
EXPECTED_WORKFLOW_BRANCH: ${{ inputs.release_candidate_branch || github.ref_name }}
|
||||
STRICT_VALIDATOR_FILE: ${{ github.workspace }}/trusted-workflow/scripts/release-ci-summary.mjs
|
||||
run: |
|
||||
set -euo pipefail
|
||||
EXPECTED_RELEASE_SHA="$(git rev-parse HEAD)"
|
||||
export EXPECTED_RELEASE_SHA
|
||||
run_file="${RUNNER_TEMP}/full-release-validation-run.json"
|
||||
gh api "repos/${GITHUB_REPOSITORY}/actions/runs/${FULL_RELEASE_VALIDATION_RUN_ID}/attempts/${FULL_RELEASE_VALIDATION_RUN_ATTEMPT}" > "$run_file"
|
||||
jq '{
|
||||
workflowName: .name,
|
||||
headBranch: .head_branch,
|
||||
headSha: .head_sha,
|
||||
event,
|
||||
status,
|
||||
conclusion,
|
||||
url: .html_url
|
||||
}' "$run_file" | node scripts/openclaw-npm-extended-stable-release.mjs verify-run
|
||||
run_attempt="$(jq -r '.run_attempt // ""' "$run_file")"
|
||||
if [[ "$run_attempt" != "$FULL_RELEASE_VALIDATION_RUN_ATTEMPT" ]]; then
|
||||
echo "Full Release Validation run ${FULL_RELEASE_VALIDATION_RUN_ID} attempt mismatch: expected ${FULL_RELEASE_VALIDATION_RUN_ATTEMPT}, got ${run_attempt:-<missing>}." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "attempt=$run_attempt" >> "$GITHUB_OUTPUT"
|
||||
EXPECTED_SHA="$(git rev-parse HEAD)"
|
||||
MANIFEST_FILE="full-release-validation/full-release-validation-manifest.json"
|
||||
export EXPECTED_SHA MANIFEST_FILE
|
||||
timeout --signal=TERM --kill-after=10s 120s git fetch --no-tags origin +refs/heads/main:refs/remotes/origin/main
|
||||
gh api "repos/${GITHUB_REPOSITORY}/actions/runs/${FULL_RELEASE_VALIDATION_RUN_ID}/attempts/${FULL_RELEASE_VALIDATION_RUN_ATTEMPT}" | \
|
||||
node trusted-workflow/scripts/validate-full-release-validation-evidence.mjs
|
||||
|
||||
- name: Verify plugin npm release run metadata
|
||||
if: ${{ inputs.npm_dist_tag == 'extended-stable' }}
|
||||
@@ -949,7 +978,7 @@ jobs:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
PLUGIN_NPM_RUN_ID: ${{ inputs.plugin_npm_run_id }}
|
||||
RELEASE_NPM_DIST_TAG: ${{ inputs.npm_dist_tag }}
|
||||
EXPECTED_EXTENDED_STABLE_BRANCH: ${{ github.ref_name }}
|
||||
EXPECTED_EXTENDED_STABLE_BRANCH: ${{ inputs.release_candidate_branch || github.ref_name }}
|
||||
RUN_KIND: plugin
|
||||
run: |
|
||||
set -euo pipefail
|
||||
@@ -1011,16 +1040,6 @@ jobs:
|
||||
|
||||
download_preflight_artifact
|
||||
|
||||
- name: Download full release validation manifest
|
||||
if: ${{ inputs.full_release_validation_run_id != '' }}
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
with:
|
||||
name: full-release-validation-${{ inputs.full_release_validation_run_id }}-${{ steps.full_run.outputs.attempt }}
|
||||
path: full-release-validation
|
||||
repository: ${{ github.repository }}
|
||||
run-id: ${{ inputs.full_release_validation_run_id }}
|
||||
github-token: ${{ github.token }}
|
||||
|
||||
- name: Validate release tag and package metadata
|
||||
if: ${{ inputs.preflight_run_id == '' }}
|
||||
env:
|
||||
@@ -1167,20 +1186,14 @@ jobs:
|
||||
env:
|
||||
RELEASE_TAG: ${{ inputs.tag }}
|
||||
RELEASE_NPM_DIST_TAG: ${{ inputs.npm_dist_tag }}
|
||||
EXPECTED_WORKFLOW_REF: ${{ github.ref_name }}
|
||||
FULL_RELEASE_VALIDATION_RUN_ID: ${{ inputs.full_release_validation_run_id }}
|
||||
FULL_RELEASE_VALIDATION_RUN_ATTEMPT: ${{ steps.full_run.outputs.attempt }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
EXPECTED_RELEASE_SHA="$(git rev-parse HEAD)"
|
||||
MANIFEST_FILE="full-release-validation/full-release-validation-manifest.json"
|
||||
if [[ ! -f "$MANIFEST_FILE" ]]; then
|
||||
echo "Full release validation manifest is missing." >&2
|
||||
ls -la full-release-validation >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
export EXPECTED_RELEASE_SHA MANIFEST_FILE
|
||||
node scripts/openclaw-npm-extended-stable-release.mjs verify-manifest
|
||||
RERUN_GROUP="$(jq -r '.rerunGroup // ""' "$MANIFEST_FILE")"
|
||||
RUN_RELEASE_SOAK="$(jq -r '.runReleaseSoak // ""' "$MANIFEST_FILE")"
|
||||
PERFORMANCE_BLOCKING="$(jq -r '.controls.performanceBlocking // false' "$MANIFEST_FILE")"
|
||||
@@ -1202,7 +1215,7 @@ jobs:
|
||||
BYPASS_EXTENDED_STABLE_GUARD: ${{ inputs.bypass_extended_stable_guard }}
|
||||
RELEASE_NPM_DIST_TAG: ${{ inputs.npm_dist_tag }}
|
||||
RELEASE_TAG: ${{ inputs.tag }}
|
||||
NPM_WORKFLOW_REF: ${{ github.ref }}
|
||||
NPM_WORKFLOW_REF: ${{ inputs.release_candidate_branch != '' && format('refs/heads/{0}', inputs.release_candidate_branch) || github.ref }}
|
||||
run: node scripts/openclaw-npm-extended-stable-release.mjs validate-request
|
||||
|
||||
- name: Capture previous extended-stable selector
|
||||
@@ -1255,8 +1268,7 @@ jobs:
|
||||
env:
|
||||
BYPASS_EXTENDED_STABLE_GUARD: ${{ inputs.bypass_extended_stable_guard }}
|
||||
RELEASE_TAG: ${{ inputs.tag }}
|
||||
RELEASE_SHA: ${{ github.sha }}
|
||||
EXTENDED_STABLE_BRANCH: ${{ github.ref_name }}
|
||||
EXTENDED_STABLE_BRANCH: ${{ inputs.release_candidate_branch || github.ref_name }}
|
||||
PREFLIGHT_RUN_ID: ${{ inputs.preflight_run_id }}
|
||||
FULL_RELEASE_VALIDATION_RUN_ID: ${{ inputs.full_release_validation_run_id }}
|
||||
TARBALL_NAME: ${{ steps.preflight_provenance.outputs.tarball_name }}
|
||||
@@ -1270,13 +1282,14 @@ jobs:
|
||||
run: |
|
||||
set -euo pipefail
|
||||
release_version="${RELEASE_TAG#v}"
|
||||
release_sha="$(git rev-parse HEAD)"
|
||||
{
|
||||
echo "## npm extended-stable publication"
|
||||
echo "- Package: openclaw@${release_version}"
|
||||
echo "- Extended-stable guard bypass: ${BYPASS_EXTENDED_STABLE_GUARD}"
|
||||
echo "- Extended-stable branch: ${EXTENDED_STABLE_BRANCH}"
|
||||
echo "- Release tag: ${RELEASE_TAG}"
|
||||
echo "- Release SHA: ${RELEASE_SHA}"
|
||||
echo "- Release SHA: ${release_sha}"
|
||||
echo "- npm preflight run: ${PREFLIGHT_RUN_ID}"
|
||||
echo "- Full Release Validation run: ${FULL_RELEASE_VALIDATION_RUN_ID}"
|
||||
echo "- Tarball: ${TARBALL_NAME:-unavailable}"
|
||||
|
||||
Reference in New Issue
Block a user