name: macOS Release on: workflow_dispatch: inputs: tag: description: Existing release tag to validate for macOS release handoff (for example v2026.3.22, v2026.3.22-alpha.1, or v2026.3.22-beta.1) required: true type: string preflight_only: description: Retained for operator compatibility; this public workflow is validation-only required: true default: true type: boolean public_release_branch: description: Public branch that contains the release tag commit, usually main or release/YYYY.M.D required: false default: main type: string concurrency: group: macos-release-${{ inputs.tag }} cancel-in-progress: false env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" NODE_VERSION: "24.x" PNPM_VERSION: "10.32.1" jobs: validate_macos_release_request: runs-on: ubuntu-latest permissions: contents: read steps: - name: Validate 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]*((-(alpha|beta)\.[1-9][0-9]*)|(-[1-9][0-9]*))?$ ]]; then echo "Invalid release tag format: ${RELEASE_TAG}" exit 1 fi - name: Checkout selected tag uses: actions/checkout@v6 with: ref: refs/tags/${{ inputs.tag }} fetch-depth: 0 - name: Setup Node environment uses: ./.github/actions/setup-node-env with: node-version: ${{ env.NODE_VERSION }} pnpm-version: ${{ env.PNPM_VERSION }} install-bun: "false" - name: Ensure matching GitHub release exists env: GH_TOKEN: ${{ github.token }} RELEASE_TAG: ${{ inputs.tag }} run: gh release view "$RELEASE_TAG" --repo "$GITHUB_REPOSITORY" >/dev/null - name: Build run: pnpm build - name: Build Control UI run: pnpm ui:build - name: Validate release tag and package metadata env: RELEASE_TAG: ${{ inputs.tag }} PUBLIC_RELEASE_BRANCH: ${{ inputs.public_release_branch }} run: | set -euo pipefail if [[ "${PUBLIC_RELEASE_BRANCH}" != "main" && ! "${PUBLIC_RELEASE_BRANCH}" =~ ^release/[0-9]{4}\.[1-9][0-9]*\.[1-9][0-9]*$ ]]; then echo "public_release_branch must be main or release/YYYY.M.D, got ${PUBLIC_RELEASE_BRANCH}." >&2 exit 1 fi RELEASE_SHA=$(git rev-parse HEAD) RELEASE_MAIN_REF="refs/remotes/origin/${PUBLIC_RELEASE_BRANCH}" export RELEASE_SHA RELEASE_TAG RELEASE_MAIN_REF git fetch --no-tags origin "+refs/heads/${PUBLIC_RELEASE_BRANCH}:refs/remotes/origin/${PUBLIC_RELEASE_BRANCH}" pnpm release:openclaw:npm:check - name: Summarize next step env: RELEASE_TAG: ${{ inputs.tag }} run: | { echo "## Public macOS validation only" echo 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-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"