diff --git a/.github/workflows/main-branch-flow.md b/.github/workflows/main-branch-flow.md index 8fb539d33..094314107 100644 --- a/.github/workflows/main-branch-flow.md +++ b/.github/workflows/main-branch-flow.md @@ -13,11 +13,10 @@ Use this with: | Event | Main workflows | | --- | --- | | PR activity (`pull_request_target`) | `pr-intake-checks.yml`, `pr-labeler.yml`, `pr-auto-response.yml` | -| PR activity (`pull_request`) | `ci-run.yml`, `feature-matrix.yml` (Rust/workflow paths), `sec-audit.yml`, `sec-codeql.yml` (when Rust/codeql paths change), `main-promotion-gate.yml` (for `main` PRs), plus path-scoped workflows | -| Push to `dev`/`main` | `ci-run.yml`, `feature-matrix.yml` (Rust/workflow paths), `sec-audit.yml`, `sec-codeql.yml` (when Rust/codeql paths change), plus path-scoped workflows | -| Merge queue (`merge_group`) | `ci-run.yml`, `feature-matrix.yml`, `sec-audit.yml`, `sec-codeql.yml` | -| Tag push (`v*`) | `pub-release.yml` publish mode, `pub-docker-img.yml` publish job, `pub-prerelease.yml` (for `v*-alpha.*`, `v*-beta.*`, `v*-rc.*`) | -| Scheduled/manual | `pub-release.yml` verification mode, `pub-prerelease.yml` (manual), `ci-canary-gate.yml`, `pub-homebrew-core.yml` (manual), `sec-codeql.yml`, `ci-connectivity-probes.yml`, `ci-provider-connectivity.yml`, `ci-reproducible-build.yml`, `ci-supply-chain-provenance.yml`, `ci-change-audit.yml` (manual), `ci-rollback.yml` (weekly/manual), `feature-matrix.yml`, `nightly-all-features.yml`, `docs-deploy.yml` (manual), `test-fuzz.yml`, `pr-check-stale.yml`, `pr-check-status.yml`, `sync-contributors.yml`, `test-benchmarks.yml`, `test-e2e.yml` | +| PR activity (`pull_request`) | `ci-run.yml`, `sec-audit.yml`, `main-promotion-gate.yml` (for `main` PRs), plus path-scoped workflows | +| Push to `dev`/`main` | `ci-run.yml`, `sec-audit.yml`, plus path-scoped workflows | +| Tag push (`v*`) | `pub-release.yml` publish mode, `pub-docker-img.yml` publish job | +| Scheduled/manual | `pub-release.yml` verification mode, `sec-codeql.yml`, `feature-matrix.yml`, `test-fuzz.yml`, `pr-check-stale.yml`, `pr-check-status.yml`, `sync-contributors.yml`, `test-benchmarks.yml`, `test-e2e.yml` | ## Runtime and Docker Matrix @@ -35,7 +34,6 @@ Observed averages below are from recent completed runs (sampled from GitHub Acti | `pub-docker-img.yml` (`pull_request`) | Docker build-input PR changes | 240.4s | Yes | Yes | No | | `pub-docker-img.yml` (`push`) | tag push `v*` | 139.9s | Yes | No | Yes | | `pub-release.yml` | Tag push `v*` (publish) + manual/scheduled verification (no publish) | N/A in recent sample | No | No | No | -| `pub-homebrew-core.yml` | Manual workflow dispatch only | N/A in recent sample | No | No | No | Notes: @@ -204,12 +202,6 @@ Canary policy lane: 2. `scripts/ci/canary_guard.py` evaluates metrics against `.github/release/canary-policy.json`. 3. Decision output is explicit (`promote`, `hold`, `abort`) with auditable artifacts and optional dispatch signal. -Manual Homebrew formula flow: - -1. Run `.github/workflows/pub-homebrew-core.yml` with `release_tag=vX.Y.Z`. -2. Use `dry_run=true` first to validate formula patch and metadata. -3. Use `dry_run=false` to push from bot fork and open `homebrew-core` PR. - ## Merge/Policy Notes 1. Workflow-file changes (`.github/workflows/**`) activate owner-approval gate in `ci-run.yml`. diff --git a/.github/workflows/pub-homebrew-core.yml b/.github/workflows/pub-homebrew-core.yml deleted file mode 100644 index ec7eb2209..000000000 --- a/.github/workflows/pub-homebrew-core.yml +++ /dev/null @@ -1,221 +0,0 @@ -name: Pub Homebrew Core - -on: - workflow_dispatch: - inputs: - release_tag: - description: "Existing release tag to publish (vX.Y.Z)" - required: true - type: string - dry_run: - description: "Patch formula only (no push/PR)" - required: false - default: true - type: boolean - -concurrency: - group: homebrew-core-${{ github.run_id }} - cancel-in-progress: false - -permissions: - contents: read - -jobs: - publish-homebrew-core: - name: Publish Homebrew Core PR - runs-on: blacksmith-2vcpu-ubuntu-2404 - env: - UPSTREAM_REPO: Homebrew/homebrew-core - FORMULA_PATH: Formula/z/zeroclaw.rb - RELEASE_TAG: ${{ inputs.release_tag }} - DRY_RUN: ${{ inputs.dry_run }} - BOT_FORK_REPO: ${{ vars.HOMEBREW_CORE_BOT_FORK_REPO }} - BOT_EMAIL: ${{ vars.HOMEBREW_CORE_BOT_EMAIL }} - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - with: - fetch-depth: 0 - - - name: Validate release tag and version alignment - id: release_meta - shell: bash - run: | - set -euo pipefail - - semver_pattern='^v[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z.-]+)?$' - if [[ ! "$RELEASE_TAG" =~ $semver_pattern ]]; then - echo "::error::release_tag must match semver-like format (vX.Y.Z[-suffix])." - exit 1 - fi - - if ! git rev-parse "refs/tags/${RELEASE_TAG}" >/dev/null 2>&1; then - git fetch --tags origin - fi - - tag_version="${RELEASE_TAG#v}" - cargo_version="$(git show "${RELEASE_TAG}:Cargo.toml" | sed -n 's/^version = "\([^"]*\)"/\1/p' | head -n1)" - if [[ -z "$cargo_version" ]]; then - echo "::error::Unable to read Cargo.toml version from tag ${RELEASE_TAG}." - exit 1 - fi - if [[ "$cargo_version" != "$tag_version" ]]; then - echo "::error::Tag ${RELEASE_TAG} does not match Cargo.toml version (${cargo_version})." - echo "::error::Bump Cargo.toml first, then publish Homebrew." - exit 1 - fi - - tarball_url="https://github.com/${GITHUB_REPOSITORY}/archive/refs/tags/${RELEASE_TAG}.tar.gz" - tarball_sha="$(curl -fsSL "$tarball_url" | sha256sum | awk '{print $1}')" - - { - echo "tag_version=$tag_version" - echo "tarball_url=$tarball_url" - echo "tarball_sha=$tarball_sha" - } >> "$GITHUB_OUTPUT" - - { - echo "### Release Metadata" - echo "- release_tag: ${RELEASE_TAG}" - echo "- cargo_version: ${cargo_version}" - echo "- tarball_sha256: ${tarball_sha}" - echo "- dry_run: ${DRY_RUN}" - } >> "$GITHUB_STEP_SUMMARY" - - - name: Patch Homebrew formula - id: patch_formula - shell: bash - env: - HOMEBREW_CORE_BOT_TOKEN: ${{ secrets.HOMEBREW_UPSTREAM_PR_TOKEN || secrets.HOMEBREW_CORE_BOT_TOKEN }} - GH_TOKEN: ${{ secrets.HOMEBREW_UPSTREAM_PR_TOKEN || secrets.HOMEBREW_CORE_BOT_TOKEN }} - run: | - set -euo pipefail - - tmp_repo="$(mktemp -d)" - echo "tmp_repo=$tmp_repo" >> "$GITHUB_OUTPUT" - - if [[ "$DRY_RUN" == "true" ]]; then - git clone --depth=1 "https://github.com/${UPSTREAM_REPO}.git" "$tmp_repo/homebrew-core" - else - if [[ -z "${BOT_FORK_REPO}" ]]; then - echo "::error::Repository variable HOMEBREW_CORE_BOT_FORK_REPO is required when dry_run=false." - exit 1 - fi - if [[ -z "${HOMEBREW_CORE_BOT_TOKEN}" ]]; then - echo "::error::Repository secret HOMEBREW_CORE_BOT_TOKEN is required when dry_run=false." - exit 1 - fi - if [[ "$BOT_FORK_REPO" != */* ]]; then - echo "::error::HOMEBREW_CORE_BOT_FORK_REPO must be in owner/repo format." - exit 1 - fi - if ! command -v gh >/dev/null 2>&1; then - echo "::error::gh CLI is required on the runner." - exit 1 - fi - if [[ -z "${GH_TOKEN:-}" ]]; then - echo "::error::Repository secret HOMEBREW_CORE_BOT_TOKEN is missing." - exit 1 - fi - if ! gh api "repos/${BOT_FORK_REPO}" >/dev/null 2>&1; then - echo "::error::HOMEBREW_CORE_BOT_TOKEN cannot access ${BOT_FORK_REPO}." - exit 1 - fi - gh repo clone "${BOT_FORK_REPO}" "$tmp_repo/homebrew-core" -- --depth=1 - fi - - repo_dir="$tmp_repo/homebrew-core" - formula_file="$repo_dir/$FORMULA_PATH" - if [[ ! -f "$formula_file" ]]; then - echo "::error::Formula file not found: $FORMULA_PATH" - exit 1 - fi - - if [[ "$DRY_RUN" == "false" ]]; then - if git -C "$repo_dir" remote get-url upstream >/dev/null 2>&1; then - git -C "$repo_dir" remote set-url upstream "https://github.com/${UPSTREAM_REPO}.git" - else - git -C "$repo_dir" remote add upstream "https://github.com/${UPSTREAM_REPO}.git" - fi - if git -C "$repo_dir" ls-remote --exit-code --heads upstream main >/dev/null 2>&1; then - upstream_ref="main" - else - upstream_ref="master" - fi - git -C "$repo_dir" fetch --depth=1 upstream "$upstream_ref" - branch_name="zeroclaw-${RELEASE_TAG}-${GITHUB_RUN_ID}" - git -C "$repo_dir" checkout -B "$branch_name" "upstream/$upstream_ref" - echo "branch_name=$branch_name" >> "$GITHUB_OUTPUT" - fi - - tarball_url="${{ steps.release_meta.outputs.tarball_url }}" - tarball_sha="${{ steps.release_meta.outputs.tarball_sha }}" - - perl -0pi -e "s|^ url \".*\"| url \"${tarball_url}\"|m" "$formula_file" - perl -0pi -e "s|^ sha256 \".*\"| sha256 \"${tarball_sha}\"|m" "$formula_file" - perl -0pi -e "s|^ license \".*\"| license \"Apache-2.0 OR MIT\"|m" "$formula_file" - perl -0pi -e 's|^ head "https://github\.com/zeroclaw-labs/zeroclaw\.git".*| head "https://github.com/zeroclaw-labs/zeroclaw.git"|m' "$formula_file" - - git -C "$repo_dir" diff -- "$FORMULA_PATH" > "$tmp_repo/formula.diff" - if [[ ! -s "$tmp_repo/formula.diff" ]]; then - echo "::error::No formula changes generated. Nothing to publish." - exit 1 - fi - - { - echo "### Formula Diff" - echo '```diff' - cat "$tmp_repo/formula.diff" - echo '```' - } >> "$GITHUB_STEP_SUMMARY" - - - name: Push branch and open Homebrew PR - if: ${{ inputs.dry_run == false }} - shell: bash - env: - GH_TOKEN: ${{ secrets.HOMEBREW_UPSTREAM_PR_TOKEN || secrets.HOMEBREW_CORE_BOT_TOKEN }} - run: | - set -euo pipefail - - repo_dir="${{ steps.patch_formula.outputs.tmp_repo }}/homebrew-core" - branch_name="${{ steps.patch_formula.outputs.branch_name }}" - tag_version="${{ steps.release_meta.outputs.tag_version }}" - fork_owner="${BOT_FORK_REPO%%/*}" - bot_email="${BOT_EMAIL:-${fork_owner}@users.noreply.github.com}" - - git -C "$repo_dir" config user.name "$fork_owner" - git -C "$repo_dir" config user.email "$bot_email" - git -C "$repo_dir" add "$FORMULA_PATH" - git -C "$repo_dir" commit -m "zeroclaw ${tag_version}" - if [[ -z "${GH_TOKEN:-}" ]]; then - echo "::error::Repository secret HOMEBREW_CORE_BOT_TOKEN is missing." - exit 1 - fi - gh auth setup-git - git -C "$repo_dir" push --set-upstream origin "$branch_name" - - pr_title="zeroclaw ${tag_version}" - pr_body=$(cat <