mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
perf(release): make publish reruns resumable and promote assets concurrently
The 2026.7.1 retro measured ~13h tag-to-published for beta.2 and stable 2026.6.11; any post-npm failure previously hard-aborted retries because the already-published guard refused the whole run. - resolve_openclaw_npm_publish_state replaces the abort guard: an already-published core version skips the core npm dispatch and resumes the remaining stages; verify_published_release still proves the registry state matches the tag before the page leaves draft. - Windows and Android promotion runs concurrently with the core npm publish (their only shared prerequisite is the draft release page, which is now created before the dispatch) and each promotion short-circuits when the release already carries its verified asset contract, so retries only redo failed stages. - The release proof cites the core npm run only when this run dispatched one; resumed publishes rely on the registry package check.
This commit is contained in:
@@ -916,9 +916,10 @@ jobs:
|
||||
exit 1
|
||||
}
|
||||
|
||||
guard_openclaw_npm_not_already_published() {
|
||||
local release_version release_url
|
||||
resolve_openclaw_npm_publish_state() {
|
||||
local release_version
|
||||
|
||||
openclaw_npm_already_published="false"
|
||||
if [[ "${PUBLISH_OPENCLAW_NPM}" != "true" ]]; then
|
||||
return 0
|
||||
fi
|
||||
@@ -928,14 +929,12 @@ jobs:
|
||||
return 0
|
||||
fi
|
||||
|
||||
release_url="https://github.com/${GITHUB_REPOSITORY}/releases/tag/${RELEASE_TAG}"
|
||||
{
|
||||
echo "openclaw@${release_version} is already published on npm."
|
||||
echo "Refusing to dispatch publish child workflows for an already-published version."
|
||||
echo "If this is recovery from a failed postpublish evidence or draft-release step, repair/finalize the existing draft or create a correction tag; do not rerun the publish workflow for the same npm version."
|
||||
echo "Release page, if present: ${release_url}"
|
||||
} >&2
|
||||
exit 1
|
||||
# A published core package means a prior publish run already got
|
||||
# that far; resume the remaining stages instead of refusing.
|
||||
# verify_published_release still proves the published artifact
|
||||
# matches this tag before the release page leaves draft.
|
||||
openclaw_npm_already_published="true"
|
||||
echo "openclaw@${release_version} is already published on npm; skipping the core npm dispatch and resuming the remaining publish stages."
|
||||
}
|
||||
|
||||
resolve_clawhub_release_plan() {
|
||||
@@ -1262,11 +1261,21 @@ jobs:
|
||||
echo "Stable release is missing prevalidated Windows installer digests." >&2
|
||||
return 1
|
||||
fi
|
||||
# Retry-safe: the asset contract is the done-condition, so a prior
|
||||
# publish run's verified promotion is reused instead of re-running
|
||||
# the Windows child workflow.
|
||||
if verify_windows_release_asset_contract >/dev/null 2>&1; then
|
||||
echo "- Windows Hub promotion: assets already promoted and verified; skipping dispatch" >> "$GITHUB_STEP_SUMMARY"
|
||||
return 0
|
||||
fi
|
||||
|
||||
windows_node_run_id="$(dispatch_workflow windows-node-release.yml \
|
||||
-f tag="${RELEASE_TAG}" \
|
||||
-f windows_node_tag="${WINDOWS_NODE_TAG}" \
|
||||
-f expected_installer_digests="${WINDOWS_NODE_INSTALLER_DIGESTS}")"
|
||||
# Promotion runs in a background subshell; hand the run id to the
|
||||
# parent shell for the release proof links.
|
||||
printf '%s' "${windows_node_run_id}" > "${RUNNER_TEMP}/windows-node-run-id.txt"
|
||||
echo "- Windows Node release run ID: \`${windows_node_run_id}\`" >> "$GITHUB_STEP_SUMMARY"
|
||||
wait_for_run windows-node-release.yml "${windows_node_run_id}"
|
||||
}
|
||||
@@ -1275,6 +1284,13 @@ jobs:
|
||||
if ! is_android_release; then
|
||||
return 0
|
||||
fi
|
||||
# Retry-safe: the asset contract is the done-condition, so a prior
|
||||
# publish run's verified APK promotion is reused instead of
|
||||
# re-running the Android child workflow.
|
||||
if verify_android_release_asset_contract >/dev/null 2>&1; then
|
||||
echo "- Android APK: assets already promoted and verified; skipping dispatch" >> "${GITHUB_STEP_SUMMARY}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
android_release_run_id="$(dispatch_workflow_at_ref "${RELEASE_TAG}" android-release.yml \
|
||||
-f tag="${RELEASE_TAG}" \
|
||||
@@ -1282,6 +1298,9 @@ jobs:
|
||||
-f release_publish_branch="${CHILD_WORKFLOW_REF}" \
|
||||
-f release_target_sha="${TARGET_SHA}" \
|
||||
-f direct_release_recovery=false)"
|
||||
# Promotion runs in a background subshell; hand the run id to the
|
||||
# parent shell for the release proof links.
|
||||
printf '%s' "${android_release_run_id}" > "${RUNNER_TEMP}/android-release-run-id.txt"
|
||||
echo "- Android release run ID: \`${android_release_run_id}\`" >> "${GITHUB_STEP_SUMMARY}"
|
||||
wait_for_run android-release.yml "${android_release_run_id}"
|
||||
}
|
||||
@@ -1397,10 +1416,14 @@ jobs:
|
||||
--clawhub-workflow-ref "${clawhub_workflow_ref}"
|
||||
--full-release-validation-run "${FULL_RELEASE_VALIDATION_RUN_ID}"
|
||||
--plugin-npm-run "${plugin_npm_run_id}"
|
||||
--openclaw-npm-run "${openclaw_npm_run_id}"
|
||||
--evidence-out "${evidence_path}"
|
||||
--skip-github-release
|
||||
)
|
||||
# Resumed publishes have no core npm run of their own; the
|
||||
# registry package check still verifies the published state.
|
||||
if [[ -n "${openclaw_npm_run_id// }" ]]; then
|
||||
verify_args+=(--openclaw-npm-run "${openclaw_npm_run_id}")
|
||||
fi
|
||||
clawhub_runtime_state_path="${RUNNER_TEMP}/openclaw-release-clawhub-runtime-state-verify.json"
|
||||
write_clawhub_runtime_state "${skip_clawhub}" "${clawhub_runtime_state_path}"
|
||||
while IFS= read -r arg; do
|
||||
@@ -1492,7 +1515,13 @@ jobs:
|
||||
`- plugin npm publish: https://github.com/${process.env.RELEASE_REPO}/actions/runs/${process.env.PLUGIN_NPM_RUN_ID}`,
|
||||
process.env.CLAWHUB_LINE,
|
||||
process.env.CLAWHUB_BOOTSTRAP_LINE,
|
||||
`- OpenClaw npm publish: https://github.com/${process.env.RELEASE_REPO}/actions/runs/${process.env.OPENCLAW_NPM_RUN_ID}`,
|
||||
// Resumed publishes reuse the already-published npm package and
|
||||
// have no core npm run of their own to cite.
|
||||
...(process.env.OPENCLAW_NPM_RUN_ID
|
||||
? [
|
||||
`- OpenClaw npm publish: https://github.com/${process.env.RELEASE_REPO}/actions/runs/${process.env.OPENCLAW_NPM_RUN_ID}`,
|
||||
]
|
||||
: []),
|
||||
process.env.TELEGRAM_LINE,
|
||||
...(process.env.ANDROID_LINE ? [process.env.ANDROID_LINE] : []),
|
||||
...(process.env.WINDOWS_LINE ? [process.env.WINDOWS_LINE] : []),
|
||||
@@ -1526,10 +1555,10 @@ jobs:
|
||||
echo "- OpenClaw npm publish: skipped by input"
|
||||
fi
|
||||
if is_android_release && [[ "${PUBLISH_OPENCLAW_NPM}" == "true" ]]; then
|
||||
echo "- Android APK: required before the GitHub release can be published"
|
||||
echo "- Android APK: promoted concurrently with the OpenClaw npm publish; required before the GitHub release can be published"
|
||||
fi
|
||||
if is_stable_release && [[ "${PUBLISH_OPENCLAW_NPM}" == "true" ]]; then
|
||||
echo "- Windows Hub promotion: required before the GitHub release can be published"
|
||||
echo "- Windows Hub promotion: promoted concurrently with the OpenClaw npm publish; required before the GitHub release can be published"
|
||||
fi
|
||||
if [[ "${WAIT_FOR_CLAWHUB}" == "true" ]]; then
|
||||
echo "- Workflow completion waits for ClawHub"
|
||||
@@ -1547,8 +1576,8 @@ jobs:
|
||||
"" \
|
||||
"${prepared_release_notes_metadata_file}"
|
||||
guard_existing_public_release
|
||||
guard_openclaw_npm_not_already_published
|
||||
fi
|
||||
resolve_openclaw_npm_publish_state
|
||||
resolve_clawhub_release_plan
|
||||
|
||||
npm_args=(-f publish_scope="${PLUGIN_PUBLISH_SCOPE}" -f ref="${TARGET_SHA}" -f release_publish_run_id="${GITHUB_RUN_ID}")
|
||||
@@ -1611,14 +1640,22 @@ jobs:
|
||||
|
||||
openclaw_npm_run_id=""
|
||||
if [[ "${PUBLISH_OPENCLAW_NPM}" == "true" ]]; then
|
||||
openclaw_npm_run_id="$(dispatch_workflow openclaw-npm-release.yml \
|
||||
-f tag="${RELEASE_TAG}" \
|
||||
-f preflight_only=false \
|
||||
-f preflight_run_id="${PREFLIGHT_RUN_ID}" \
|
||||
-f full_release_validation_run_id="${FULL_RELEASE_VALIDATION_RUN_ID}" \
|
||||
-f release_publish_run_id="${GITHUB_RUN_ID}" \
|
||||
-f npm_dist_tag="${RELEASE_NPM_DIST_TAG}")"
|
||||
echo "- OpenClaw npm run ID: \`${openclaw_npm_run_id}\`" >> "$GITHUB_STEP_SUMMARY"
|
||||
# The draft release page is the only shared prerequisite for the
|
||||
# Windows/Android promotions and the core npm publish; create it
|
||||
# first so those stages can run concurrently.
|
||||
create_or_update_github_release
|
||||
if [[ "${openclaw_npm_already_published}" == "true" ]]; then
|
||||
echo "- OpenClaw npm publish: already on npm; resuming postpublish stages" >> "$GITHUB_STEP_SUMMARY"
|
||||
else
|
||||
openclaw_npm_run_id="$(dispatch_workflow openclaw-npm-release.yml \
|
||||
-f tag="${RELEASE_TAG}" \
|
||||
-f preflight_only=false \
|
||||
-f preflight_run_id="${PREFLIGHT_RUN_ID}" \
|
||||
-f full_release_validation_run_id="${FULL_RELEASE_VALIDATION_RUN_ID}" \
|
||||
-f release_publish_run_id="${GITHUB_RUN_ID}" \
|
||||
-f npm_dist_tag="${RELEASE_NPM_DIST_TAG}")"
|
||||
echo "- OpenClaw npm run ID: \`${openclaw_npm_run_id}\`" >> "$GITHUB_STEP_SUMMARY"
|
||||
fi
|
||||
else
|
||||
echo "- OpenClaw npm publish: skipped by input" >> "$GITHUB_STEP_SUMMARY"
|
||||
fi
|
||||
@@ -1682,10 +1719,35 @@ jobs:
|
||||
openclaw_pid="${wait_run_pid}"
|
||||
fi
|
||||
|
||||
# Windows/Android promotion only needs the draft release page, so it
|
||||
# runs concurrently with the core npm publish instead of after it.
|
||||
android_promote_result=""
|
||||
android_promote_pid=""
|
||||
windows_promote_result=""
|
||||
windows_promote_pid=""
|
||||
if [[ "${PUBLISH_OPENCLAW_NPM}" == "true" ]]; then
|
||||
android_promote_result="$RUNNER_TEMP/android-promote-result.txt"
|
||||
(
|
||||
if promote_android_release_asset; then
|
||||
echo "success" > "${android_promote_result}"
|
||||
else
|
||||
echo "failed" > "${android_promote_result}"
|
||||
fi
|
||||
) &
|
||||
android_promote_pid=$!
|
||||
windows_promote_result="$RUNNER_TEMP/windows-promote-result.txt"
|
||||
(
|
||||
if promote_windows_release_assets; then
|
||||
echo "success" > "${windows_promote_result}"
|
||||
else
|
||||
echo "failed" > "${windows_promote_result}"
|
||||
fi
|
||||
) &
|
||||
windows_promote_pid=$!
|
||||
fi
|
||||
|
||||
failed=0
|
||||
openclaw_failed=0
|
||||
windows_node_run_id=""
|
||||
android_release_run_id=""
|
||||
if [[ -n "${openclaw_pid}" ]] && ! wait "${openclaw_pid}"; then
|
||||
failed=1
|
||||
openclaw_failed=1
|
||||
@@ -1708,21 +1770,29 @@ jobs:
|
||||
failed=1
|
||||
fi
|
||||
|
||||
if [[ -n "${openclaw_npm_run_id}" && "${openclaw_failed}" == "0" ]]; then
|
||||
if [[ -n "${android_promote_pid}" ]]; then
|
||||
wait "${android_promote_pid}" || true
|
||||
if [[ ! -f "${android_promote_result}" || "$(cat "${android_promote_result}")" != "success" ]]; then
|
||||
failed=1
|
||||
fi
|
||||
fi
|
||||
if [[ -n "${windows_promote_pid}" ]]; then
|
||||
wait "${windows_promote_pid}" || true
|
||||
if [[ ! -f "${windows_promote_result}" || "$(cat "${windows_promote_result}")" != "success" ]]; then
|
||||
failed=1
|
||||
fi
|
||||
fi
|
||||
windows_node_run_id="$(cat "${RUNNER_TEMP}/windows-node-run-id.txt" 2>/dev/null || true)"
|
||||
android_release_run_id="$(cat "${RUNNER_TEMP}/android-release-run-id.txt" 2>/dev/null || true)"
|
||||
|
||||
if [[ ( -n "${openclaw_npm_run_id}" && "${openclaw_failed}" == "0" ) || "${openclaw_npm_already_published}" == "true" ]]; then
|
||||
if [[ "${failed}" == "0" ]]; then
|
||||
verify_published_release
|
||||
else
|
||||
verify_published_release true
|
||||
fi
|
||||
create_or_update_github_release
|
||||
if ! promote_android_release_asset; then
|
||||
failed=1
|
||||
fi
|
||||
upload_dependency_evidence_release_asset
|
||||
upload_release_evidence_assets
|
||||
if ! promote_windows_release_assets; then
|
||||
failed=1
|
||||
fi
|
||||
append_release_proof_to_github_release
|
||||
if [[ "${failed}" == "0" ]]; then
|
||||
publish_github_release
|
||||
|
||||
@@ -168,7 +168,7 @@ This checklist is the public shape of the release flow. Private credentials, sig
|
||||
8. If validation fails, fix on the release branch and rerun the smallest failed file, lane, workflow job, package profile, provider, or model allowlist that proves the fix. Rerun the full umbrella only when the changed surface makes prior evidence stale.
|
||||
9. For a tagged beta candidate, run `pnpm release:candidate -- --tag vYYYY.M.PATCH-beta.N` from the matching `release/YYYY.M.PATCH` branch. For stable, also pass the required Windows source release: `pnpm release:candidate -- --tag vYYYY.M.PATCH --windows-node-tag vX.Y.Z`. Before it dispatches the full validation matrix, the helper deterministically renders the exact tag's GitHub release body and rejects a missing version heading, an over-limit body that cannot use the canonical compact form, or contribution-record base/target provenance that is not reachable from the tag. It also validates any explicit shipped-baseline exclusion metadata against the referenced cumulative tag records. It then runs the local generated-release checks, dispatches or verifies full release validation and npm preflight evidence, runs Parallels fresh/update proof against the exact prepared tarball plus Telegram package proof, records plugin npm and ClawHub plans, and prints the exact `OpenClaw Release Publish` command only after the evidence bundle is green.
|
||||
|
||||
`OpenClaw Release Publish` dispatches the selected or all-publishable plugin packages to npm and the same set to ClawHub in parallel, then promotes the prepared OpenClaw npm preflight artifact with the matching dist-tag once plugin npm publish succeeds. Before any publish child starts, it renders and caches the exact GitHub release body. When the complete matching `CHANGELOG.md` section fits GitHub's 125,000-character limit and the renderer's matching 125,000-byte safety ceiling, the page contains that exact `## YYYY.M.PATCH` section including its heading. When the source section does not fit, the page keeps the exact grouped editorial notes and replaces the oversized contribution record with a stable link to the full record in the tag-pinned `CHANGELOG.md`; partial records and truncated bullets are never published. The workflow chooses that full or compact body before adding `### Release verification`; if the proof tail would exceed the limit, it keeps the canonical body and relies on the immutable attached evidence instead. Stable releases published to npm `latest` become the GitHub latest release, while stable maintenance releases kept on npm `beta` are created with GitHub `latest=false`. The workflow also uploads the preflight dependency evidence, the full-validation manifest, and postpublish registry verification evidence to the GitHub release for post-release incident response. It prints child run IDs immediately, auto-approves release environment gates the workflow token is allowed to approve, summarizes failed child jobs with log tails, closes out the GitHub release and dependency evidence as soon as OpenClaw npm publish succeeds, waits for ClawHub whenever OpenClaw npm is being published, then runs `pnpm release:verify-beta` and uploads postpublish evidence for the GitHub release, npm package, selected plugin npm packages, selected ClawHub packages, child workflow run IDs, and optional NPM Telegram run ID. The ClawHub path retries transient CLI dependency install failures, publishes preview-passing plugins even when one preview cell flakes, and ends with registry verification for every expected plugin version so partial publishes stay visible and retryable.
|
||||
`OpenClaw Release Publish` dispatches the selected or all-publishable plugin packages to npm and the same set to ClawHub in parallel, then promotes the prepared OpenClaw npm preflight artifact with the matching dist-tag once plugin npm publish succeeds. Before any publish child starts, it renders and caches the exact GitHub release body. When the complete matching `CHANGELOG.md` section fits GitHub's 125,000-character limit and the renderer's matching 125,000-byte safety ceiling, the page contains that exact `## YYYY.M.PATCH` section including its heading. When the source section does not fit, the page keeps the exact grouped editorial notes and replaces the oversized contribution record with a stable link to the full record in the tag-pinned `CHANGELOG.md`; partial records and truncated bullets are never published. The workflow chooses that full or compact body before adding `### Release verification`; if the proof tail would exceed the limit, it keeps the canonical body and relies on the immutable attached evidence instead. Stable releases published to npm `latest` become the GitHub latest release, while stable maintenance releases kept on npm `beta` are created with GitHub `latest=false`. The workflow also uploads the preflight dependency evidence, the full-validation manifest, and postpublish registry verification evidence to the GitHub release for post-release incident response. It prints child run IDs immediately, auto-approves release environment gates the workflow token is allowed to approve, summarizes failed child jobs with log tails, creates the draft GitHub release page up front and promotes Windows and Android assets concurrently with the OpenClaw npm publish, closes out the release page and dependency evidence once those stages succeed, waits for ClawHub whenever OpenClaw npm is being published, then runs `pnpm release:verify-beta` and uploads postpublish evidence for the GitHub release, npm package, selected plugin npm packages, selected ClawHub packages, child workflow run IDs, and optional NPM Telegram run ID. The ClawHub path retries transient CLI dependency install failures, publishes preview-passing plugins even when one preview cell flakes, and ends with registry verification for every expected plugin version so partial publishes stay visible and retryable.
|
||||
|
||||
Then run the post-publish package acceptance against the published `openclaw@YYYY.M.PATCH-beta.N` or `openclaw@beta` package. If a pushed or published prerelease needs a fix, cut the next matching prerelease number; never delete or rewrite the old one.
|
||||
|
||||
@@ -236,7 +236,7 @@ A legacy fallback correction tag may reuse base-package evidence only when the c
|
||||
- Run `pnpm qa:observability:smoke` for the source-checkout OpenTelemetry and Prometheus smoke lanes back to back.
|
||||
- Run `pnpm release:check` before every tagged release.
|
||||
- `OpenClaw NPM Release` preflight generates dependency release evidence before it packs the npm tarball. The npm advisory vulnerability gate is release-blocking. The transitive manifest risk, dependency ownership/install surface, and dependency change reports are release evidence only. The dependency change report compares the release candidate with the previous reachable release tag. The preflight uploads dependency evidence as `openclaw-release-dependency-evidence-<tag>` and also embeds it under `dependency-evidence/` inside the prepared npm preflight artifact. The real publish path reuses that preflight artifact, then attaches the same evidence to the GitHub release as `openclaw-<version>-dependency-evidence.zip`.
|
||||
- Run `OpenClaw Release Publish` for the mutating publish sequence after the tag exists. Dispatch it from `release/YYYY.M.PATCH` (or `main` when publishing a main-reachable tag), pass the release tag, successful OpenClaw npm `preflight_run_id`, and successful `full_release_validation_run_id`, and keep the default plugin publish scope `all-publishable` unless you are deliberately running a focused repair. The workflow serializes plugin npm publish, plugin ClawHub publish, and OpenClaw npm publish so the core package is not published before its externalized plugins.
|
||||
- Run `OpenClaw Release Publish` for the mutating publish sequence after the tag exists. Dispatch it from `release/YYYY.M.PATCH` (or `main` when publishing a main-reachable tag), pass the release tag, successful OpenClaw npm `preflight_run_id`, and successful `full_release_validation_run_id`, and keep the default plugin publish scope `all-publishable` unless you are deliberately running a focused repair. The workflow serializes plugin npm publish, plugin ClawHub publish, and OpenClaw npm publish so the core package is not published before its externalized plugins; Windows and Android promotion runs concurrently with the core npm publish against the draft release page. Publish reruns are resumable: an already-published core npm version skips the core dispatch, and Windows/Android promotion is skipped when the release already carries the verified asset contract, so a retry only redoes the failed stages.
|
||||
- Stable `OpenClaw Release Publish` requires an exact `windows_node_tag` after the matching non-prerelease `openclaw/openclaw-windows-node` release exists, plus the candidate-approved `windows_node_installer_digests` map. Before dispatching any publish child, it verifies that source release is published, non-prerelease, contains the required x64/ARM64 installers, and still matches that approved map. It then dispatches `Windows Node Release` while the OpenClaw release is still a draft, carrying the pinned installer digest map unchanged. The child workflow downloads the signed Windows Hub installers from that exact tag, matches them against the pinned digests, verifies their Authenticode signatures use the expected OpenClaw Foundation signer on a Windows runner, writes a SHA-256 manifest, and uploads the installers plus manifest onto the canonical OpenClaw GitHub release, then re-downloads the promoted assets and verifies manifest membership and hashes. The parent verifies the current x64, ARM64, and checksum asset contract before publication. Direct recovery rejects unexpected `OpenClawCompanion-*` asset names before replacing the expected contract assets with the pinned source bytes.
|
||||
|
||||
Manually dispatch `Windows Node Release` only for recovery, and always pass an exact tag, never `latest`, plus the explicit `expected_installer_digests` JSON map from the approved source release. Website download links should target exact OpenClaw release asset URLs for the current stable release, or `releases/latest/download/...` only after verifying GitHub's latest redirect points at that same release; do not link only to the companion repo release page.
|
||||
|
||||
@@ -2348,7 +2348,7 @@ describe("package artifact reuse", () => {
|
||||
"\n create_or_update_github_release\n",
|
||||
);
|
||||
const promoteWindowsCall = releaseWorkflow.lastIndexOf(
|
||||
"\n if ! promote_windows_release_assets; then\n",
|
||||
"\n if promote_windows_release_assets; then\n",
|
||||
);
|
||||
const publishReleaseCall = releaseWorkflow.lastIndexOf(
|
||||
"\n publish_github_release\n",
|
||||
@@ -2484,7 +2484,7 @@ describe("package artifact reuse", () => {
|
||||
"\n create_or_update_github_release\n",
|
||||
);
|
||||
const promoteAndroidCall = releaseWorkflow.lastIndexOf(
|
||||
"\n if ! promote_android_release_asset; then\n",
|
||||
"\n if promote_android_release_asset; then\n",
|
||||
);
|
||||
const publishReleaseCall = releaseWorkflow.lastIndexOf(
|
||||
"\n publish_github_release\n",
|
||||
@@ -2705,6 +2705,13 @@ describe("package artifact reuse", () => {
|
||||
expect(releaseWorkflow).toContain(
|
||||
"already has a public GitHub release page without complete postpublish evidence",
|
||||
);
|
||||
expect(releaseWorkflow).toContain("resolve_openclaw_npm_publish_state");
|
||||
expect(releaseWorkflow).toContain(
|
||||
"already published on npm; skipping the core npm dispatch and resuming the remaining publish stages",
|
||||
);
|
||||
expect(
|
||||
releaseWorkflow.match(/assets already promoted and verified; skipping dispatch/g),
|
||||
).toHaveLength(2);
|
||||
expect(releaseWorkflow).toContain("registry tarball");
|
||||
expect(releaseWorkflow).toContain("openclawNpmTarball");
|
||||
expect(releaseWorkflow).not.toContain('npm view "openclaw@${release_version}" dist.tarball');
|
||||
@@ -2833,12 +2840,15 @@ describe("package artifact reuse", () => {
|
||||
expect(releaseWorkflow).toContain(
|
||||
"has failed jobs before the workflow completed: https://github.com/${GITHUB_REPOSITORY}/actions/runs/${run_id}",
|
||||
);
|
||||
expect(releaseWorkflow.lastIndexOf("verify_published_release")).toBeLessThan(
|
||||
releaseWorkflow.lastIndexOf("create_or_update_github_release"),
|
||||
);
|
||||
expect(releaseWorkflow.lastIndexOf("create_or_update_github_release")).toBeLessThan(
|
||||
releaseWorkflow.lastIndexOf("verify_published_release"),
|
||||
);
|
||||
expect(releaseWorkflow.lastIndexOf("verify_published_release")).toBeLessThan(
|
||||
releaseWorkflow.lastIndexOf("append_release_proof_to_github_release"),
|
||||
);
|
||||
expect(releaseWorkflow.lastIndexOf("append_release_proof_to_github_release")).toBeLessThan(
|
||||
releaseWorkflow.lastIndexOf("publish_github_release"),
|
||||
);
|
||||
expect(releaseWorkflow).toContain("finished with ${conclusion} in ${duration_label}");
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user