From 27dea58ae1a27b6c789a8c9148e5931386a64de0 Mon Sep 17 00:00:00 2001 From: claude Date: Sun, 26 Jul 2026 02:02:06 +0000 Subject: [PATCH] integration-macos: dispatch-only (drop push-to-main trigger) Make the advisory macOS Apple Container job run on workflow_dispatch only, removing the push-to-`main` trigger so a single non-redundant laptop never runs unattended on every push. Updates the job comment, docs/ci.md, README CI note, and the PRD accordingly. Co-Authored-By: Claude Opus 4.8 --- .gitea/workflows/test.yml | 15 +++++++-------- README.md | 2 +- docs/ci.md | 2 +- docs/prds/prd-new-macos-container-ci-runner.md | 14 ++++++++------ 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml index 93f5b243..184a6a16 100644 --- a/.gitea/workflows/test.yml +++ b/.gitea/workflows/test.yml @@ -217,11 +217,12 @@ jobs: # Container needs the host `container` CLI + virtualization framework and # cannot run inside a Linux container, so this cannot reuse the KVM runner. # - # Advisory only: push-to-main and workflow_dispatch, never pull_request. A - # single non-redundant laptop that sleeps/roams must not be able to block a - # PR merge, so this job is deliberately NOT in the `coverage` job's `needs` - # and its coverage never feeds the diff-coverage gate. Not gating on PRs also - # means no fork PR ever executes on the host-mode runner. + # Advisory only: workflow_dispatch (manual) exclusively — never push or + # pull_request. A single non-redundant laptop that sleeps/roams must not run + # unattended on every push to main, let alone block a PR merge, so this job is + # deliberately NOT in the `coverage` job's `needs` and its coverage never + # feeds the diff-coverage gate. Dispatch-only also means no fork PR (or any + # push) ever executes on the host-mode runner. # # The infra container is a singleton (`bot-bottle-mac-infra`); the # `concurrency` group serializes runs so two never collide on it (#425), and @@ -232,9 +233,7 @@ jobs: # Python >=3.11 with `coverage` importable on the launchd service PATH. integration-macos: runs-on: [self-hosted, macos] - if: >- - github.event_name == 'push' || - github.event_name == 'workflow_dispatch' + if: github.event_name == 'workflow_dispatch' concurrency: group: integration-macos-infra cancel-in-progress: false diff --git a/README.md b/README.md index f867308e..ed5d5477 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ On compatible macOS hosts, the default backend requires Apple's `container` CLI Use `BOT_BOTTLE_BACKEND=docker ./cli.py start ` on hosts where neither Apple Container nor KVM is available and Docker is the desired backend. -> **CI (macOS Apple Container):** the `integration-macos` job (`.gitea/workflows/test.yml`) runs the integration suite against `BOT_BOTTLE_BACKEND=macos-container` on a self-hosted macOS runner labelled `macos`, because Apple Container needs the host virtualization framework and cannot run in a Linux container (so it can't reuse the `kvm` runner). Provision an Apple Silicon host with the `container` CLI on `PATH` and `container system status` running, then register the runner in **host mode** (not docker mode) with the `macos` label — `brew install gitea-runner` (the `act_runner` rename). Give it a Python ≥ 3.11 with `coverage` importable on the launchd service's `PATH` (a launchd service doesn't inherit your shell profile, so pin `node` and the Python env explicitly). The job is **advisory** — push-to-main and `workflow_dispatch` only, never a required PR check — since a single laptop that sleeps/roams must not block merges; its coverage doesn't feed the gate. The infra container is a singleton (`bot-bottle-mac-infra`), so keep runner concurrency at 1. +> **CI (macOS Apple Container):** the `integration-macos` job (`.gitea/workflows/test.yml`) runs the integration suite against `BOT_BOTTLE_BACKEND=macos-container` on a self-hosted macOS runner labelled `macos`, because Apple Container needs the host virtualization framework and cannot run in a Linux container (so it can't reuse the `kvm` runner). Provision an Apple Silicon host with the `container` CLI on `PATH` and `container system status` running, then register the runner in **host mode** (not docker mode) with the `macos` label — `brew install gitea-runner` (the `act_runner` rename). Give it a Python ≥ 3.11 with `coverage` importable on the launchd service's `PATH` (a launchd service doesn't inherit your shell profile, so pin `node` and the Python env explicitly). The job is **advisory** — `workflow_dispatch` (manual) only, never triggered by push or PR — since a single laptop that sleeps/roams must not block merges or churn on every push to main; its coverage doesn't feed the gate. The infra container is a singleton (`bot-bottle-mac-infra`), so keep runner concurrency at 1. ### Containers inside a bottle diff --git a/docs/ci.md b/docs/ci.md index c43b94ee..64e96c5d 100644 --- a/docs/ci.md +++ b/docs/ci.md @@ -8,7 +8,7 @@ It runs the unit suite plus one integration job per backend - every push to `main`. `integration-macos` is the exception: it is **advisory**, running only on -push-to-`main` and `workflow_dispatch`, never on pull requests. It targets the +`workflow_dispatch` (manual dispatch), never on push or pull requests. It targets the Apple Container backend on a self-hosted macOS runner (label `macos`, registered in host mode — Apple Container can't run in a Linux container, so it can't reuse the `kvm` runner). A single non-redundant laptop must not be able diff --git a/docs/prds/prd-new-macos-container-ci-runner.md b/docs/prds/prd-new-macos-container-ci-runner.md index cc03a3bc..6aace8cc 100644 --- a/docs/prds/prd-new-macos-container-ci-runner.md +++ b/docs/prds/prd-new-macos-container-ci-runner.md @@ -57,10 +57,12 @@ plugs into; this PRD supplies the runner and the job. ## Non-goals -- Making `integration-macos` a **required** PR check. It runs on push-to-main - and `workflow_dispatch` only. A single non-redundant laptop that sleeps and - roams must never be able to block a PR merge, and it is deliberately kept out - of the `coverage` job's `needs` so the diff-coverage gate never depends on it. +- Making `integration-macos` a **required** PR check. It runs on + `workflow_dispatch` (manual dispatch) only — never on push or PRs. A single + non-redundant laptop that sleeps and roams must never be able to block a PR + merge or churn unattended on every push to main, and it is deliberately kept + out of the `coverage` job's `needs` so the diff-coverage gate never depends on + it. - Multi-machine or hosted macOS runners. Apple Container needs the host virtualization framework, so the runner must be a physical/VM macOS host on Apple Silicon — it cannot reuse the KVM runner or run in a Linux container. @@ -91,8 +93,8 @@ plugs into; this PRD supplies the runner and the job. Modeled on `integration-firecracker`: - `runs-on: [self-hosted, macos]`. -- `if:` push-to-main OR `workflow_dispatch` only (advisory; never PRs, so no - fork-PR exposure and no merge-blocking). +- `if:` `workflow_dispatch` only (advisory, manual dispatch; never push or PRs, + so no fork-PR exposure, no merge-blocking, and no unattended runs on push). - `concurrency: { group: integration-macos-infra, cancel-in-progress: false }` to serialize runs against the singleton. - **Preflight** — `command -v container`, `container system status`, then