mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:20:43 +00:00
ci: add stable npm dist-tag sync
This commit is contained in:
@@ -120,6 +120,10 @@ node --import tsx scripts/openclaw-npm-postpublish-verify.ts <published-version>
|
||||
`.github/workflows/openclaw-npm-release.yml`, but it still needs a valid
|
||||
`NPM_TOKEN` because `npm dist-tag` management is separate from trusted
|
||||
publishing.
|
||||
- Direct stable publishes can also run the same workflow with
|
||||
`sync_stable_dist_tags=true` to point both `latest` and `beta` at the
|
||||
already-published stable version. This also needs the `npm-release`
|
||||
environment approval and `NPM_TOKEN`.
|
||||
- The publish run must be started manually with `workflow_dispatch`.
|
||||
- The npm workflow and the private mac publish workflow accept
|
||||
`preflight_only=true` to run validation/build/package steps without uploading
|
||||
@@ -248,19 +252,25 @@ node --import tsx scripts/openclaw-npm-postpublish-verify.ts <published-version>
|
||||
passes with the same stable tag, `promote_beta_to_latest=true`,
|
||||
`preflight_only=false`, empty `preflight_run_id`, and `npm_dist_tag=beta`,
|
||||
then verify `latest` now points at that version.
|
||||
17. Start
|
||||
17. If the stable release was published directly to `latest` and `beta` should
|
||||
follow it, start `.github/workflows/openclaw-npm-release.yml` again with
|
||||
the same stable tag, `sync_stable_dist_tags=true`,
|
||||
`promote_beta_to_latest=false`, `preflight_only=false`, empty
|
||||
`preflight_run_id`, and `npm_dist_tag=latest`, then verify both `latest`
|
||||
and `beta` point at that version.
|
||||
18. Start
|
||||
`openclaw/releases-private/.github/workflows/openclaw-macos-publish.yml`
|
||||
for the real publish with the successful private mac `preflight_run_id` and
|
||||
wait for success.
|
||||
18. Verify the successful real private mac run uploaded the `.zip`, `.dmg`,
|
||||
19. Verify the successful real private mac run uploaded the `.zip`, `.dmg`,
|
||||
and `.dSYM.zip` artifacts to the existing GitHub release in
|
||||
`openclaw/openclaw`.
|
||||
19. For stable releases, download `macos-appcast-<tag>` from the successful
|
||||
20. For stable releases, download `macos-appcast-<tag>` from the successful
|
||||
private mac run, update `appcast.xml` on `main`, and verify the feed.
|
||||
20. For beta releases, publish the mac assets but expect no shared production
|
||||
21. For beta releases, publish the mac assets but expect no shared production
|
||||
`appcast.xml` artifact and do not update the shared production feed unless a
|
||||
separate beta feed exists.
|
||||
21. After publish, verify npm and the attached release artifacts.
|
||||
22. After publish, verify npm and the attached release artifacts.
|
||||
|
||||
## GHSA advisory work
|
||||
|
||||
|
||||
113
.github/workflows/openclaw-npm-release.yml
vendored
113
.github/workflows/openclaw-npm-release.yml
vendored
@@ -29,9 +29,14 @@ on:
|
||||
required: true
|
||||
default: false
|
||||
type: boolean
|
||||
sync_stable_dist_tags:
|
||||
description: Skip publish and point both latest and beta at an already-published stable version
|
||||
required: true
|
||||
default: false
|
||||
type: boolean
|
||||
|
||||
concurrency:
|
||||
group: openclaw-npm-release-${{ github.event_name == 'workflow_dispatch' && format('{0}-{1}-{2}', inputs.tag, inputs.npm_dist_tag, inputs.promote_beta_to_latest) || github.ref }}
|
||||
group: openclaw-npm-release-${{ github.event_name == 'workflow_dispatch' && format('{0}-{1}-{2}-{3}', inputs.tag, inputs.npm_dist_tag, inputs.promote_beta_to_latest, inputs.sync_stable_dist_tags) || github.ref }}
|
||||
cancel-in-progress: false
|
||||
|
||||
env:
|
||||
@@ -44,7 +49,7 @@ jobs:
|
||||
# KEEP THIS WORKFLOW SHORT AND DETERMINISTIC OR IT CAN GET STUCK AND JEOPARDIZE THE RELEASE.
|
||||
# RELEASE-TIME LIVE OR END-TO-END VALIDATION BELONGS IN openclaw-release-checks.yml.
|
||||
preflight_openclaw_npm:
|
||||
if: ${{ inputs.preflight_only && !inputs.promote_beta_to_latest }}
|
||||
if: ${{ inputs.preflight_only && !inputs.promote_beta_to_latest && !inputs.sync_stable_dist_tags }}
|
||||
runs-on: blacksmith-32vcpu-ubuntu-2404
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -241,7 +246,7 @@ jobs:
|
||||
if-no-files-found: error
|
||||
|
||||
validate_publish_request:
|
||||
if: ${{ !inputs.preflight_only && !inputs.promote_beta_to_latest }}
|
||||
if: ${{ !inputs.preflight_only && !inputs.promote_beta_to_latest && !inputs.sync_stable_dist_tags }}
|
||||
runs-on: blacksmith-32vcpu-ubuntu-2404
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -270,7 +275,7 @@ jobs:
|
||||
# KEEP THE REAL RELEASE/PUBLISH PATH ON A GITHUB-HOSTED RUNNER.
|
||||
# npm trusted publishing + provenance requires this to stay on ubuntu-latest.
|
||||
needs: [validate_publish_request]
|
||||
if: ${{ !inputs.preflight_only && !inputs.promote_beta_to_latest }}
|
||||
if: ${{ !inputs.preflight_only && !inputs.promote_beta_to_latest && !inputs.sync_stable_dist_tags }}
|
||||
runs-on: ubuntu-latest
|
||||
environment: npm-release
|
||||
permissions:
|
||||
@@ -411,7 +416,7 @@ jobs:
|
||||
# KEEP THE MUTATING RELEASE PATH ON A GITHUB-HOSTED RUNNER TOO.
|
||||
# This job changes the public npm dist-tags, so we keep it aligned with the
|
||||
# real release path instead of moving it onto the larger Blacksmith runners.
|
||||
if: ${{ inputs.promote_beta_to_latest }}
|
||||
if: ${{ inputs.promote_beta_to_latest && !inputs.sync_stable_dist_tags }}
|
||||
runs-on: ubuntu-latest
|
||||
environment: npm-release
|
||||
permissions:
|
||||
@@ -506,3 +511,101 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
echo "Promoted openclaw@${RELEASE_VERSION} from beta to latest."
|
||||
|
||||
sync_stable_dist_tags:
|
||||
# This mode is for direct stable publishes where latest is correct but beta
|
||||
# should also point at the same stable build after release.
|
||||
if: ${{ inputs.sync_stable_dist_tags && !inputs.promote_beta_to_latest }}
|
||||
runs-on: ubuntu-latest
|
||||
environment: npm-release
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Require main workflow ref for dist-tag sync
|
||||
env:
|
||||
WORKFLOW_REF: ${{ github.ref }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [[ "${WORKFLOW_REF}" != "refs/heads/main" ]]; then
|
||||
echo "Dist-tag sync runs must be dispatched from main."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Validate sync inputs
|
||||
env:
|
||||
PREFLIGHT_ONLY: ${{ inputs.preflight_only }}
|
||||
PREFLIGHT_RUN_ID: ${{ inputs.preflight_run_id }}
|
||||
RELEASE_NPM_DIST_TAG: ${{ inputs.npm_dist_tag }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [[ "${PREFLIGHT_ONLY}" == "true" ]]; then
|
||||
echo "Dist-tag sync mode cannot run with preflight_only=true."
|
||||
exit 1
|
||||
fi
|
||||
if [[ -n "${PREFLIGHT_RUN_ID}" ]]; then
|
||||
echo "Dist-tag sync mode does not use preflight_run_id."
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${RELEASE_NPM_DIST_TAG}" != "latest" ]]; then
|
||||
echo "Dist-tag sync mode expects npm_dist_tag=latest because it points latest and beta at the stable version."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Validate stable tag input format
|
||||
env:
|
||||
RELEASE_TAG: ${{ inputs.tag }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [[ ! "${RELEASE_TAG}" =~ ^v[0-9]{4}\.[1-9][0-9]*\.[1-9][0-9]*(-[1-9][0-9]*)?$ ]]; then
|
||||
echo "Invalid stable release tag format: ${RELEASE_TAG}" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "RELEASE_VERSION=${RELEASE_TAG#v}" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Node environment
|
||||
uses: ./.github/actions/setup-node-env
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
pnpm-version: ${{ env.PNPM_VERSION }}
|
||||
install-bun: "false"
|
||||
use-sticky-disk: "false"
|
||||
install-deps: "false"
|
||||
|
||||
- name: Validate published stable version
|
||||
env:
|
||||
RELEASE_VERSION: ${{ env.RELEASE_VERSION }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if ! npm view "openclaw@${RELEASE_VERSION}" version >/dev/null 2>&1; then
|
||||
echo "openclaw@${RELEASE_VERSION} is not published on npm." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Current latest dist-tag: $(npm view openclaw dist-tags.latest)"
|
||||
echo "Current beta dist-tag: $(npm view openclaw dist-tags.beta)"
|
||||
|
||||
- name: Sync stable dist-tags
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
RELEASE_VERSION: ${{ env.RELEASE_VERSION }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
printf '//registry.npmjs.org/:_authToken=%s\n' "${NODE_AUTH_TOKEN}" > "${HOME}/.npmrc"
|
||||
npm whoami >/dev/null
|
||||
npm dist-tag add "openclaw@${RELEASE_VERSION}" latest
|
||||
npm dist-tag add "openclaw@${RELEASE_VERSION}" beta
|
||||
|
||||
synced_latest="$(npm view openclaw dist-tags.latest)"
|
||||
synced_beta="$(npm view openclaw dist-tags.beta)"
|
||||
if [[ "${synced_latest}" != "${RELEASE_VERSION}" ]]; then
|
||||
echo "npm latest points at ${synced_latest}, expected ${RELEASE_VERSION} after sync." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ "${synced_beta}" != "${RELEASE_VERSION}" ]]; then
|
||||
echo "npm beta points at ${synced_beta}, expected ${RELEASE_VERSION} after sync." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Synced openclaw@${RELEASE_VERSION} to npm latest and beta."
|
||||
|
||||
@@ -75,7 +75,9 @@ OpenClaw has three public release lanes:
|
||||
- stable npm releases default to `beta`
|
||||
- stable npm publish can target `latest` explicitly via workflow input
|
||||
- stable npm promotion from `beta` to `latest` is still available as an explicit manual mode on the trusted `OpenClaw NPM Release` workflow
|
||||
- that promotion mode still needs a valid `NPM_TOKEN` in the `npm-release` environment because npm `dist-tag` management is separate from trusted publishing
|
||||
- direct stable publishes can also run an explicit dist-tag sync mode that
|
||||
points both `latest` and `beta` at the already-published stable version
|
||||
- those dist-tag modes still need a valid `NPM_TOKEN` in the `npm-release` environment because npm `dist-tag` management is separate from trusted publishing
|
||||
- public `macOS Release` is validation-only
|
||||
- real private mac publish must pass successful private mac
|
||||
`preflight_run_id` and `validate_run_id`
|
||||
@@ -113,6 +115,8 @@ OpenClaw has three public release lanes:
|
||||
- `npm_dist_tag`: npm target tag for the publish path; defaults to `beta`
|
||||
- `promote_beta_to_latest`: `true` to skip publish and move an already-published
|
||||
stable `beta` build onto `latest`
|
||||
- `sync_stable_dist_tags`: `true` to skip publish and point both `latest` and
|
||||
`beta` at an already-published stable version
|
||||
|
||||
`OpenClaw Release Checks` accepts these operator-controlled inputs:
|
||||
|
||||
@@ -129,8 +133,12 @@ Rules:
|
||||
the workflow verifies that metadata before publish continues
|
||||
- Promotion mode must use a stable or correction tag, `preflight_only=false`,
|
||||
an empty `preflight_run_id`, and `npm_dist_tag=beta`
|
||||
- Promotion mode also requires a valid `NPM_TOKEN` in the `npm-release`
|
||||
environment because `npm dist-tag add` still needs regular npm auth
|
||||
- Dist-tag sync mode must use a stable or correction tag,
|
||||
`preflight_only=false`, an empty `preflight_run_id`, `npm_dist_tag=latest`,
|
||||
and `promote_beta_to_latest=false`
|
||||
- Promotion and dist-tag sync modes also require a valid `NPM_TOKEN` in the
|
||||
`npm-release` environment because `npm dist-tag add` still needs regular npm
|
||||
auth
|
||||
|
||||
## Stable npm release sequence
|
||||
|
||||
@@ -152,9 +160,13 @@ When cutting a stable npm release:
|
||||
same stable `tag`, `promote_beta_to_latest=true`, `preflight_only=false`,
|
||||
`preflight_run_id` empty, and `npm_dist_tag=beta` when you want to move that
|
||||
published build to `latest`
|
||||
7. If the release intentionally published directly to `latest` and `beta`
|
||||
should follow the same stable build, run `OpenClaw NPM Release` with the same
|
||||
stable `tag`, `sync_stable_dist_tags=true`, `promote_beta_to_latest=false`,
|
||||
`preflight_only=false`, `preflight_run_id` empty, and `npm_dist_tag=latest`
|
||||
|
||||
The promotion mode still requires the `npm-release` environment approval and a
|
||||
valid `NPM_TOKEN` in that environment.
|
||||
The promotion and dist-tag sync modes still require the `npm-release`
|
||||
environment approval and a valid `NPM_TOKEN` in that environment.
|
||||
|
||||
That keeps the direct publish path and the beta-first promotion path both
|
||||
documented and operator-visible.
|
||||
|
||||
Reference in New Issue
Block a user