mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
ci(release): preserve direct repair publishes
This commit is contained in:
59
.github/workflows/full-release-validation.yml
vendored
59
.github/workflows/full-release-validation.yml
vendored
@@ -210,10 +210,36 @@ jobs:
|
||||
fi
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
docker_runtime_assets_preflight:
|
||||
name: Verify Docker runtime-assets prune path
|
||||
needs: [resolve_target]
|
||||
if: inputs.rerun_group == 'all'
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 45
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout target SHA
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ needs.resolve_target.outputs.sha }}
|
||||
fetch-depth: 1
|
||||
persist-credentials: false
|
||||
|
||||
- name: Verify Docker runtime-assets prune path
|
||||
env:
|
||||
DOCKER_BUILDKIT: "1"
|
||||
run: |
|
||||
set -euo pipefail
|
||||
timeout --foreground --kill-after=30s 35m docker build \
|
||||
--target runtime-assets \
|
||||
--build-arg OPENCLAW_EXTENSIONS="matrix" \
|
||||
.
|
||||
|
||||
normal_ci:
|
||||
name: Run normal full CI
|
||||
needs: [resolve_target]
|
||||
if: contains(fromJSON('["all","ci"]'), inputs.rerun_group)
|
||||
needs: [resolve_target, docker_runtime_assets_preflight]
|
||||
if: ${{ always() && contains(fromJSON('["all","ci"]'), inputs.rerun_group) && (inputs.rerun_group != 'all' || needs.docker_runtime_assets_preflight.result == 'success') }}
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: ${{ inputs.release_profile != 'minimum' && 240 || 60 }}
|
||||
outputs:
|
||||
@@ -312,8 +338,8 @@ jobs:
|
||||
|
||||
plugin_prerelease:
|
||||
name: Run plugin prerelease validation
|
||||
needs: [resolve_target]
|
||||
if: contains(fromJSON('["all","plugin-prerelease"]'), inputs.rerun_group)
|
||||
needs: [resolve_target, docker_runtime_assets_preflight]
|
||||
if: ${{ always() && contains(fromJSON('["all","plugin-prerelease"]'), inputs.rerun_group) && (inputs.rerun_group != 'all' || needs.docker_runtime_assets_preflight.result == 'success') }}
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: ${{ inputs.release_profile == 'full' && 300 || inputs.release_profile == 'stable' && 240 || 60 }}
|
||||
outputs:
|
||||
@@ -412,8 +438,8 @@ jobs:
|
||||
|
||||
release_checks:
|
||||
name: Run release/live/Docker/QA validation
|
||||
needs: [resolve_target]
|
||||
if: contains(fromJSON('["all","release-checks","install-smoke","cross-os","live-e2e","package","qa","qa-parity","qa-live"]'), inputs.rerun_group)
|
||||
needs: [resolve_target, docker_runtime_assets_preflight]
|
||||
if: ${{ always() && contains(fromJSON('["all","release-checks","install-smoke","cross-os","live-e2e","package","qa","qa-parity","qa-live"]'), inputs.rerun_group) && (inputs.rerun_group != 'all' || needs.docker_runtime_assets_preflight.result == 'success') }}
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: ${{ inputs.release_profile != 'minimum' && 240 || 60 }}
|
||||
outputs:
|
||||
@@ -565,8 +591,8 @@ jobs:
|
||||
|
||||
prepare_release_package:
|
||||
name: Prepare release package artifact
|
||||
needs: [resolve_target]
|
||||
if: ${{ inputs.npm_telegram_package_spec == '' && inputs.release_package_spec == '' && inputs.rerun_group == 'all' && inputs.release_profile == 'full' }}
|
||||
needs: [resolve_target, docker_runtime_assets_preflight]
|
||||
if: ${{ always() && inputs.npm_telegram_package_spec == '' && inputs.release_package_spec == '' && inputs.rerun_group == 'all' && inputs.release_profile == 'full' && needs.docker_runtime_assets_preflight.result == 'success' }}
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 15
|
||||
permissions:
|
||||
@@ -735,7 +761,7 @@ jobs:
|
||||
|
||||
summary:
|
||||
name: Verify full validation
|
||||
needs: [resolve_target, normal_ci, plugin_prerelease, release_checks, npm_telegram]
|
||||
needs: [resolve_target, docker_runtime_assets_preflight, normal_ci, plugin_prerelease, release_checks, npm_telegram]
|
||||
if: always()
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 5
|
||||
@@ -751,6 +777,8 @@ jobs:
|
||||
PLUGIN_PRERELEASE_RESULT: ${{ needs.plugin_prerelease.result }}
|
||||
RELEASE_CHECKS_RESULT: ${{ needs.release_checks.result }}
|
||||
NPM_TELEGRAM_RESULT: ${{ needs.npm_telegram.result }}
|
||||
DOCKER_RUNTIME_ASSETS_PREFLIGHT_RESULT: ${{ needs.docker_runtime_assets_preflight.result }}
|
||||
RERUN_GROUP: ${{ inputs.rerun_group }}
|
||||
TARGET_SHA: ${{ needs.resolve_target.outputs.sha }}
|
||||
CHILD_WORKFLOW_REF: ${{ github.ref_name }}
|
||||
run: |
|
||||
@@ -798,6 +826,7 @@ jobs:
|
||||
echo
|
||||
echo "| Child | Result | Minutes | Head SHA | Run |"
|
||||
echo "| --- | --- | ---: | --- | --- |"
|
||||
echo "| \`docker_runtime_assets_preflight\` | \`${DOCKER_RUNTIME_ASSETS_PREFLIGHT_RESULT}\` | | current workflow | |"
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
append_child_row() {
|
||||
@@ -933,23 +962,29 @@ jobs:
|
||||
}
|
||||
|
||||
failed=0
|
||||
required_after_preflight=1
|
||||
if [[ "$RERUN_GROUP" == "all" && "$DOCKER_RUNTIME_ASSETS_PREFLIGHT_RESULT" != "success" ]]; then
|
||||
echo "::error::Docker runtime-assets preflight ended with ${DOCKER_RUNTIME_ASSETS_PREFLIGHT_RESULT}."
|
||||
failed=1
|
||||
required_after_preflight=0
|
||||
fi
|
||||
|
||||
append_child_overview
|
||||
|
||||
if [[ "$NORMAL_CI_RESULT" == "skipped" && -z "${NORMAL_CI_RUN_ID// }" ]]; then
|
||||
check_child "normal_ci" "" 0 || failed=1
|
||||
check_child "normal_ci" "" "$required_after_preflight" || failed=1
|
||||
else
|
||||
check_child "normal_ci" "$NORMAL_CI_RUN_ID" 1 || failed=1
|
||||
fi
|
||||
|
||||
if [[ "$PLUGIN_PRERELEASE_RESULT" == "skipped" && -z "${PLUGIN_PRERELEASE_RUN_ID// }" ]]; then
|
||||
check_child "plugin_prerelease" "" 0 || failed=1
|
||||
check_child "plugin_prerelease" "" "$required_after_preflight" || failed=1
|
||||
else
|
||||
check_child "plugin_prerelease" "$PLUGIN_PRERELEASE_RUN_ID" 1 || failed=1
|
||||
fi
|
||||
|
||||
if [[ "$RELEASE_CHECKS_RESULT" == "skipped" && -z "${RELEASE_CHECKS_RUN_ID// }" ]]; then
|
||||
check_child "release_checks" "" 0 || failed=1
|
||||
check_child "release_checks" "" "$required_after_preflight" || failed=1
|
||||
else
|
||||
check_child "release_checks" "$RELEASE_CHECKS_RUN_ID" 1 || failed=1
|
||||
fi
|
||||
|
||||
22
.github/workflows/openclaw-npm-release.yml
vendored
22
.github/workflows/openclaw-npm-release.yml
vendored
@@ -337,16 +337,6 @@ jobs:
|
||||
PACKAGE_VERSION="$(node -p "require('./package.json').version")"
|
||||
node --import tsx scripts/openclaw-npm-prepublish-verify.ts "$TARBALL_PATH" "$PACKAGE_VERSION"
|
||||
|
||||
- name: Verify Docker runtime-assets prune path
|
||||
env:
|
||||
DOCKER_BUILDKIT: "1"
|
||||
run: |
|
||||
set -euo pipefail
|
||||
timeout --foreground --kill-after=30s 35m docker build \
|
||||
--target runtime-assets \
|
||||
--build-arg OPENCLAW_EXTENSIONS="matrix" \
|
||||
.
|
||||
|
||||
- name: Upload dependency release evidence
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
@@ -415,8 +405,8 @@ jobs:
|
||||
echo "Real publish requires full_release_validation_run_id from a successful Full Release Validation run." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z "${RELEASE_PUBLISH_RUN_ID// }" ]]; then
|
||||
echo "Real publish requires release_publish_run_id from the approved OpenClaw Release Publish workflow." >&2
|
||||
if [[ -z "${RELEASE_PUBLISH_RUN_ID// }" && "${GITHUB_ACTOR}" == "github-actions[bot]" ]]; then
|
||||
echo "Workflow-dispatched real publish requires release_publish_run_id from the approved OpenClaw Release Publish workflow." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -427,6 +417,14 @@ jobs:
|
||||
EXPECTED_WORKFLOW_BRANCH: ${{ github.ref_name }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [[ -z "${RELEASE_PUBLISH_RUN_ID// }" ]]; then
|
||||
if [[ "${GITHUB_ACTOR}" == "github-actions[bot]" ]]; then
|
||||
echo "OpenClaw npm publish dispatched by another workflow must include release_publish_run_id." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Direct OpenClaw npm publish; relying on this workflow's npm-release environment approval."
|
||||
exit 0
|
||||
fi
|
||||
if [[ "${GITHUB_ACTOR}" != "github-actions[bot]" ]]; then
|
||||
echo "OpenClaw npm publish must be dispatched by the OpenClaw Release Publish workflow, not directly by ${GITHUB_ACTOR}." >&2
|
||||
exit 1
|
||||
|
||||
8
.github/workflows/plugin-clawhub-release.yml
vendored
8
.github/workflows/plugin-clawhub-release.yml
vendored
@@ -217,8 +217,12 @@ jobs:
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [[ -z "${RELEASE_PUBLISH_RUN_ID// }" ]]; then
|
||||
echo "Plugin ClawHub publish must be dispatched by OpenClaw Release Publish after its npm-release gate." >&2
|
||||
exit 1
|
||||
if [[ "${GITHUB_ACTOR}" == "github-actions[bot]" ]]; then
|
||||
echo "Plugin ClawHub publish dispatched by another workflow must include release_publish_run_id." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Direct Plugin ClawHub Release dispatch; relying on this workflow's clawhub-plugin-release environment approval."
|
||||
exit 0
|
||||
fi
|
||||
if [[ "${GITHUB_ACTOR}" != "github-actions[bot]" ]]; then
|
||||
echo "Plugin ClawHub publish must be dispatched by the OpenClaw Release Publish workflow, not directly by ${GITHUB_ACTOR}." >&2
|
||||
|
||||
8
.github/workflows/plugin-npm-release.yml
vendored
8
.github/workflows/plugin-npm-release.yml
vendored
@@ -194,8 +194,12 @@ jobs:
|
||||
run: |
|
||||
set -euo pipefail
|
||||
if [[ -z "${RELEASE_PUBLISH_RUN_ID// }" ]]; then
|
||||
echo "Plugin npm publish must be dispatched by OpenClaw Release Publish after its npm-release gate." >&2
|
||||
exit 1
|
||||
if [[ "${GITHUB_ACTOR}" == "github-actions[bot]" ]]; then
|
||||
echo "Plugin npm publish dispatched by another workflow must include release_publish_run_id." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Direct Plugin NPM Release dispatch; relying on this workflow's npm-release environment approval."
|
||||
exit 0
|
||||
fi
|
||||
if [[ "${GITHUB_ACTOR}" != "github-actions[bot]" ]]; then
|
||||
echo "Plugin npm publish must be dispatched by the OpenClaw Release Publish workflow, not directly by ${GITHUB_ACTOR}." >&2
|
||||
|
||||
@@ -721,9 +721,12 @@ describe("package artifact reuse", () => {
|
||||
expect(workflow).toContain("CHILD_WORKFLOW_REF: ${{ github.ref_name }}");
|
||||
expect(workflow).toContain('gh workflow run "$workflow" --ref "$CHILD_WORKFLOW_REF" "$@"');
|
||||
expect(preparePackageJob.name).toBe("Prepare release package artifact");
|
||||
expect(preparePackageJob.needs).toEqual(["resolve_target"]);
|
||||
expect(preparePackageJob.needs).toEqual(["resolve_target", "docker_runtime_assets_preflight"]);
|
||||
expect(preparePackageJob.if).toContain("inputs.rerun_group == 'all'");
|
||||
expect(preparePackageJob.if).toContain("inputs.release_profile == 'full'");
|
||||
expect(preparePackageJob.if).toContain(
|
||||
"needs.docker_runtime_assets_preflight.result == 'success'",
|
||||
);
|
||||
expectTextToIncludeAll(
|
||||
workflowStep(preparePackageJob, "Resolve release package artifact").run,
|
||||
[
|
||||
@@ -883,6 +886,7 @@ describe("package artifact reuse", () => {
|
||||
it("keeps release publish creation compatible with gh api and prerelease notes", () => {
|
||||
const workflow = readFileSync(RELEASE_PUBLISH_WORKFLOW, "utf8");
|
||||
const npmWorkflow = readFileSync(".github/workflows/openclaw-npm-release.yml", "utf8");
|
||||
const fullReleaseWorkflow = readFileSync(FULL_RELEASE_VALIDATION_WORKFLOW, "utf8");
|
||||
|
||||
expect(workflow).toContain("timeout-minutes: 60");
|
||||
expect(workflow).toContain("environment: npm-release");
|
||||
@@ -898,12 +902,20 @@ describe("package artifact reuse", () => {
|
||||
expect(npmWorkflow).toContain("preflight-manifest.json");
|
||||
expect(npmWorkflow).toContain("Verify full release validation run metadata");
|
||||
expect(npmWorkflow).toContain("Verify full release validation target");
|
||||
expect(npmWorkflow).toContain("Verify Docker runtime-assets prune path");
|
||||
expect(npmWorkflow).toContain("--target runtime-assets");
|
||||
expect(npmWorkflow).not.toContain("Verify Docker runtime-assets prune path");
|
||||
expect(fullReleaseWorkflow).toContain("docker_runtime_assets_preflight");
|
||||
expect(fullReleaseWorkflow).toContain("Verify Docker runtime-assets prune path");
|
||||
expect(fullReleaseWorkflow).toContain("--target runtime-assets");
|
||||
expect(fullReleaseWorkflow).toContain("inputs.rerun_group == 'all'");
|
||||
expect(fullReleaseWorkflow).toContain(
|
||||
"needs.docker_runtime_assets_preflight.result == 'success'",
|
||||
);
|
||||
expect(npmWorkflow).toContain("full_release_validation_run_id");
|
||||
expect(npmWorkflow).toContain("release_publish_run_id");
|
||||
expect(npmWorkflow).toContain("Real publish requires full_release_validation_run_id");
|
||||
expect(npmWorkflow).toContain("Real publish requires release_publish_run_id");
|
||||
expect(npmWorkflow).toContain(
|
||||
"Workflow-dispatched real publish requires release_publish_run_id",
|
||||
);
|
||||
expect(npmWorkflow).toContain("tarballSha256");
|
||||
expect(workflow).toContain("Checkout release SHA");
|
||||
expect(workflow).toContain('git show "${TARGET_SHA}:CHANGELOG.md" > "${changelog_file}"');
|
||||
@@ -962,6 +974,9 @@ describe("package artifact reuse", () => {
|
||||
expect(pluginNpmWorkflow).toContain("Validate release publish approval run");
|
||||
expect(clawHubWorkflow).toContain("Validate release publish approval run");
|
||||
expect(openclawNpmWorkflow).toContain("Validate release publish approval run");
|
||||
expect(pluginNpmWorkflow).toContain("Direct Plugin NPM Release dispatch");
|
||||
expect(clawHubWorkflow).toContain("Direct Plugin ClawHub Release dispatch");
|
||||
expect(openclawNpmWorkflow).toContain("Direct OpenClaw npm publish");
|
||||
expect(pluginNpmWorkflow).toContain('GITHUB_ACTOR}" != "github-actions[bot]"');
|
||||
expect(clawHubWorkflow).toContain('GITHUB_ACTOR}" != "github-actions[bot]"');
|
||||
expect(openclawNpmWorkflow).toContain('GITHUB_ACTOR}" != "github-actions[bot]"');
|
||||
|
||||
@@ -481,6 +481,7 @@ describe("scripts/lib/plugin-prerelease-test-plan.mjs", () => {
|
||||
expect(releaseChecksWorkflow.jobs.summary["runs-on"]).toBe("ubuntu-24.04");
|
||||
for (const jobName of [
|
||||
"resolve_target",
|
||||
"docker_runtime_assets_preflight",
|
||||
"normal_ci",
|
||||
"plugin_prerelease",
|
||||
"release_checks",
|
||||
@@ -493,6 +494,18 @@ describe("scripts/lib/plugin-prerelease-test-plan.mjs", () => {
|
||||
expect(fullReleaseWorkflow.jobs.normal_ci["timeout-minutes"]).toBe(
|
||||
"${{ inputs.release_profile != 'minimum' && 240 || 60 }}",
|
||||
);
|
||||
expect(fullReleaseWorkflow.jobs.normal_ci.needs).toEqual([
|
||||
"resolve_target",
|
||||
"docker_runtime_assets_preflight",
|
||||
]);
|
||||
expect(fullReleaseWorkflow.jobs.docker_runtime_assets_preflight.if).toBe(
|
||||
"inputs.rerun_group == 'all'",
|
||||
);
|
||||
expect(
|
||||
fullReleaseWorkflow.jobs.docker_runtime_assets_preflight.steps.find(
|
||||
(step) => step.name === "Verify Docker runtime-assets prune path",
|
||||
).run,
|
||||
).toContain("--target runtime-assets");
|
||||
expect(fullReleaseWorkflow.jobs.plugin_prerelease["timeout-minutes"]).toBe(
|
||||
"${{ inputs.release_profile == 'full' && 300 || inputs.release_profile == 'stable' && 240 || 60 }}",
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user