Release: trim duplicate preflight work (#59117)

* Release: skip duplicate runtime-deps staging

* Release: trim public mac validation workflow

* Release: require promoted npm publish

* Release: verify promoted npm provenance

* Release: restore public mac validation build

* Release: skip pack check on npm promote

* Release: skip pack check on npm promote
This commit is contained in:
Onur
2026-04-01 19:24:37 +02:00
committed by GitHub
parent da64a978e5
commit f1f5a3fcf4
6 changed files with 140 additions and 48 deletions

View File

@@ -82,11 +82,12 @@ jobs:
{
echo "## Public macOS validation only"
echo
echo "This workflow no longer builds, signs, notarizes, or uploads macOS assets."
echo "This workflow validates the public release handoff and still builds JS artifacts needed for release checks."
echo "It does not sign, notarize, or upload macOS assets."
echo
echo "Next step:"
echo "- Run \`openclaw/releases-private/.github/workflows/openclaw-macos-publish.yml\` with tag \`${RELEASE_TAG}\`."
echo "- Use \`preflight_only=true\` there for the full private mac preflight."
echo "- For the real publish path, the private run uploads the packaged \`.zip\`, \`.dmg\`, and \`.dSYM.zip\` files to the existing GitHub release in \`openclaw/openclaw\` automatically."
echo "- Run \`openclaw/releases-private/.github/workflows/openclaw-macos-validate.yml\` with tag \`${RELEASE_TAG}\` and wait for the private mac validation lane to pass."
echo "- Run \`openclaw/releases-private/.github/workflows/openclaw-macos-publish.yml\` with tag \`${RELEASE_TAG}\` and \`preflight_only=true\` for the full private mac preflight."
echo "- For the real publish path, run the same private mac publish workflow from \`main\` with the successful private preflight \`preflight_run_id\` so it promotes the prepared artifacts instead of rebuilding them."
echo "- For stable releases, also download \`macos-appcast-${RELEASE_TAG}\` from the successful private run and commit \`appcast.xml\` back to \`main\` in \`openclaw/openclaw\`."
} >> "$GITHUB_STEP_SUMMARY"

View File

@@ -13,7 +13,7 @@ on:
default: false
type: boolean
preflight_run_id:
description: Existing preflight workflow run id to promote without rebuilding
description: Existing successful preflight workflow run id to promote without rebuilding
required: false
type: string
@@ -28,6 +28,7 @@ env:
jobs:
preflight_openclaw_npm:
if: ${{ inputs.preflight_only }}
runs-on: ubuntu-latest
permissions:
contents: read
@@ -42,6 +43,12 @@ jobs:
exit 1
fi
- name: Forbid preflight artifact promotion on validation-only runs
if: ${{ inputs.preflight_only && inputs.preflight_run_id != '' }}
run: |
echo "preflight_run_id is only valid for real publish runs."
exit 1
- name: Checkout
uses: actions/checkout@v6
with:
@@ -88,6 +95,7 @@ jobs:
- name: Validate release tag and package metadata
if: ${{ inputs.preflight_run_id == '' }}
env:
OPENCLAW_NPM_RELEASE_SKIP_PACK_CHECK: "1"
RELEASE_TAG: ${{ inputs.tag }}
RELEASE_MAIN_REF: origin/main
run: |
@@ -106,6 +114,7 @@ jobs:
id: packed_tarball
env:
OPENCLAW_PREPACK_PREPARED: "1"
RELEASE_TAG: ${{ inputs.tag }}
run: |
set -euo pipefail
PACK_JSON="$(npm pack --json)"
@@ -115,16 +124,23 @@ jobs:
echo "npm pack did not produce a tarball file." >&2
exit 1
fi
echo "path=$PACK_PATH" >> "$GITHUB_OUTPUT"
RELEASE_SHA="$(git rev-parse HEAD)"
ARTIFACT_DIR="$RUNNER_TEMP/openclaw-npm-preflight"
rm -rf "$ARTIFACT_DIR"
mkdir -p "$ARTIFACT_DIR"
cp "$PACK_PATH" "$ARTIFACT_DIR/"
printf '%s\n' "$RELEASE_TAG" > "$ARTIFACT_DIR/release-tag.txt"
printf '%s\n' "$RELEASE_SHA" > "$ARTIFACT_DIR/release-sha.txt"
echo "dir=$ARTIFACT_DIR" >> "$GITHUB_OUTPUT"
- name: Upload prepared npm tarball
- name: Upload prepared npm publish bundle
uses: actions/upload-artifact@v7
with:
name: openclaw-npm-preflight-${{ inputs.tag }}
path: ${{ steps.packed_tarball.outputs.path }}
path: ${{ steps.packed_tarball.outputs.dir }}
if-no-files-found: error
validate_publish_dispatch_ref:
validate_publish_request:
if: ${{ !inputs.preflight_only }}
runs-on: ubuntu-latest
permissions:
@@ -140,9 +156,19 @@ jobs:
exit 1
fi
- name: Require preflight artifact promotion on real publish
env:
PREFLIGHT_RUN_ID: ${{ inputs.preflight_run_id }}
run: |
set -euo pipefail
if [[ -z "${PREFLIGHT_RUN_ID}" ]]; then
echo "Real publish requires preflight_run_id from a successful npm preflight run." >&2
exit 1
fi
publish_openclaw_npm:
# npm trusted publishing + provenance requires a GitHub-hosted runner.
needs: [preflight_openclaw_npm, validate_publish_dispatch_ref]
needs: [validate_publish_request]
if: ${{ !inputs.preflight_only }}
runs-on: ubuntu-latest
environment: npm-release
@@ -187,8 +213,16 @@ jobs:
echo "Publishing openclaw@${PACKAGE_VERSION}"
- name: Verify preflight run metadata
env:
GH_TOKEN: ${{ github.token }}
PREFLIGHT_RUN_ID: ${{ inputs.preflight_run_id }}
run: |
set -euo pipefail
RUN_JSON="$(gh run view "$PREFLIGHT_RUN_ID" --repo "$GITHUB_REPOSITORY" --json workflowName,headBranch,event,conclusion,url)"
printf '%s' "$RUN_JSON" | node -e 'const fs = require("node:fs"); const run = JSON.parse(fs.readFileSync(0, "utf8")); const checks = [["workflowName", "OpenClaw NPM Release"], ["headBranch", "main"], ["event", "workflow_dispatch"], ["conclusion", "success"]]; for (const [key, expected] of checks) { if (run[key] !== expected) { console.error(`Referenced npm preflight run ${process.env.PREFLIGHT_RUN_ID} must have ${key}=${expected}, got ${run[key] ?? "<missing>"}.`); process.exit(1); } } console.log(`Using npm preflight run ${process.env.PREFLIGHT_RUN_ID}: ${run.url}`);'
- name: Download prepared npm tarball
if: ${{ inputs.preflight_run_id != '' }}
uses: actions/download-artifact@v8
with:
name: openclaw-npm-preflight-${{ inputs.tag }}
@@ -197,17 +231,10 @@ jobs:
run-id: ${{ inputs.preflight_run_id }}
github-token: ${{ github.token }}
- name: Build
if: ${{ inputs.preflight_run_id == '' }}
run: pnpm build
- name: Build Control UI
if: ${{ inputs.preflight_run_id == '' }}
run: pnpm ui:build
- name: Validate release tag and package metadata
if: ${{ inputs.preflight_run_id == '' }}
env:
OPENCLAW_NPM_RELEASE_SKIP_PACK_CHECK: "1"
RELEASE_TAG: ${{ inputs.tag }}
RELEASE_MAIN_REF: origin/main
run: |
@@ -219,12 +246,35 @@ jobs:
git fetch --no-tags origin +refs/heads/main:refs/remotes/origin/main
pnpm release:openclaw:npm:check
- name: Resolve publish tarball
id: publish_tarball
if: ${{ inputs.preflight_run_id != '' }}
- name: Verify prepared tarball provenance
env:
RELEASE_TAG: ${{ inputs.tag }}
run: |
set -euo pipefail
TARBALL_PATH="$(find preflight-tarball -maxdepth 1 -type f -name '*.tgz' -print | sort | tail -n 1)"
EXPECTED_RELEASE_SHA="$(git rev-parse HEAD)"
TAG_FILE="preflight-tarball/release-tag.txt"
SHA_FILE="preflight-tarball/release-sha.txt"
if [[ ! -f "$TAG_FILE" || ! -f "$SHA_FILE" ]]; then
echo "Prepared preflight metadata is missing." >&2
ls -la preflight-tarball >&2 || true
exit 1
fi
ARTIFACT_RELEASE_TAG="$(tr -d '\r\n' < "$TAG_FILE")"
ARTIFACT_RELEASE_SHA="$(tr -d '\r\n' < "$SHA_FILE")"
if [[ "$ARTIFACT_RELEASE_TAG" != "$RELEASE_TAG" ]]; then
echo "Prepared preflight tag mismatch: expected $RELEASE_TAG, got $ARTIFACT_RELEASE_TAG" >&2
exit 1
fi
if [[ "$ARTIFACT_RELEASE_SHA" != "$EXPECTED_RELEASE_SHA" ]]; then
echo "Prepared preflight SHA mismatch: expected $EXPECTED_RELEASE_SHA, got $ARTIFACT_RELEASE_SHA" >&2
exit 1
fi
- name: Resolve publish tarball
id: publish_tarball
run: |
set -euo pipefail
TARBALL_PATH="$(find preflight-tarball -type f -name '*.tgz' -print | sort | tail -n 1)"
if [[ -z "$TARBALL_PATH" ]]; then
echo "Prepared preflight tarball not found." >&2
ls -la preflight-tarball >&2 || true