From 21ac9fd06fdc53db47176646964148881ee0d2a9 Mon Sep 17 00:00:00 2001 From: probe Date: Sun, 2 Aug 2026 20:20:41 +0000 Subject: [PATCH] probe: ceremony CI at 9357f09, shellcheck installed, pins intact --- .github/workflows/ci.yml | 109 +------------------------ .github/workflows/labels.yml | 3 +- .github/workflows/release-exercise.yml | 2 - .github/workflows/release.yml | 12 +-- .github/workflows/self-labels.yml | 38 --------- .github/workflows/self-release.yml | 8 +- 6 files changed, 5 insertions(+), 167 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 37a6882..a349291 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,8 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 + - name: Install shellcheck + run: sudo apt-get update -qq && sudo apt-get install -y -qq shellcheck - name: Shellcheck run: bash .github/scripts/shellcheck-all.sh - name: Install actionlint @@ -50,110 +52,3 @@ jobs: # push+refs/heads/main event — the merge door's exact gate — opening a # live door from CI. A pull_request event can never satisfy either # door's `if:`. - release-exercise: - if: github.event_name == 'pull_request' - uses: ./.github/workflows/release-exercise.yml - - # The self-guards (issue #11): this repo eats exactly what it serves. The - # guard actions run against the REAL tree — VERSION, CHANGELOG.md, - # drills/, .github/workflows/ — through the same `uses:` steps every - # consumer's CI carries. - # These steps are also the composite-action wiring proof (issue #5's - # acceptance criterion: action.yml resolving, $GITHUB_ACTION_PATH, the - # relative lib sourcing) that action-exercise carried with scratch files - # while this repo had no tree of its own to guard; the armed and - # drill-recorded scratch steps moved here per the armed step's own - # eviction note — the file backend hardcodes the VERSION name, so a - # scratch write would SHADOW the real file, not sit beside it. - self-guards: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - # The monotonic guard compares HEAD against the merge base; a - # shallow checkout cannot resolve it, and in CI that is a hard - # failure, not a skip (the action's description). - fetch-depth: 0 - - uses: ./actions/changelog-armed - - uses: ./actions/changelog-monotonic - - uses: ./actions/changelog-assembled - - uses: ./actions/drill-recorded - - uses: ./actions/runner-isolated - - # Exercises changelog-monotonic the way a consumer does, against a - # CONSTRUCTED history. The self-guards job above runs the same action on - # the real tree, but there its containment half is only as interesting as - # the PR's own diff; this job commits a known base and an insert-above - # edit on top, so a real, non-vacuous containment run is standing - # evidence on every PR. (Armed and drill-recorded moved to self-guards — - # the real tree now exercises them; monotonic stays because it reads no - # version source, so it is immune to the VERSION-shadowing problem that - # evicted the other two.) - action-exercise: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Construct a scratch history for the monotonic guard - # The monotonic guard's input is a DIFF, so its exercise needs - # history, not just a file: commit a scratch changelog, mark that - # commit as the fixture base, then commit an insert-above edit on - # top — a real containment run, not just an action.yml parse. The - # base ref is the in-job branch, passed explicitly, because this - # job's shallow PR checkout carries no origin/main for the input's - # default to resolve (consumers get that via fetch-depth: 0, per - # the action's description). Scratch-named file so the real - # CHANGELOG.md is never shadowed; the commits live only in this - # job's checkout and are never pushed. - run: | - git config user.name ceremony-ci - git config user.email ceremony-ci@users.noreply.github.com - printf '# Changelog\n\n## Unreleased\n\n## 0.1.0 — 2026-07-01\n\n- Shipped entry.\n' > CHANGELOG.monotonic.scratch.md - git add CHANGELOG.monotonic.scratch.md - git commit -m 'fixture: monotonic base' - git branch monotonic-fixture-base - printf '# Changelog\n\n## Unreleased\n\n- Entry inserted above.\n\n## 0.1.0 — 2026-07-01\n\n- Shipped entry.\n' > CHANGELOG.monotonic.scratch.md - git commit -am 'fixture: insert above' - - uses: ./actions/changelog-monotonic - with: - changelog: CHANGELOG.monotonic.scratch.md - base-ref: monotonic-fixture-base - - # Exercises actions/docs-sync the way a consumer does (issue #19's - # acceptance criterion). Its own job, unlike the exercises above: the - # composite reads the CONSUMER's tree at the workspace root, and a - # `uses:` step cannot change directory — so the fixture consumer must BE - # the workspace root, with ceremony itself checked out to a subdirectory - # (that path also serves as the action reference and the --source - # override; no ref carrying docs/VENDORED.txt exists to fetch until this - # lands, and the exercised bytes should be THIS PR's anyway). - docs-sync-exercise: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - path: ceremony-src - - name: Construct a fixture consumer at the workspace root - # The pin ref is scratch — --source overrides the fetch, but the - # pin line itself is still parsed and required (one pin governs - # machinery and doctrine; a consumer without one has nothing for - # the mirror to be verified against). - run: | - mkdir -p .github/workflows - printf '%s\n' \ - 'name: release' \ - 'on:' \ - ' push:' \ - ' branches: [main]' \ - 'jobs:' \ - ' release:' \ - ' uses: heavy-duty/ceremony/.github/workflows/release.yml@0.0.0-fixture' \ - > .github/workflows/release.yml - - name: Bootstrap the mirror (--fix) - uses: ./ceremony-src/actions/docs-sync - with: - mode: fix - source: ceremony-src - - name: Verify the mirror (--check, the mode consumers run) - uses: ./ceremony-src/actions/docs-sync - with: - source: ceremony-src diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index 86328ae..c0069b8 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -23,8 +23,7 @@ name: labels # create workflow runs from GITHUB_TOKEN-triggered events. Agent writes use a # PAT and therefore do trigger — exactly the asymmetry wanted. on: - workflow_call: - + workflow_dispatch: env: # A called workflow arrives without its repository. Keep this literal pin # aligned with the ceremony release consumed by callers (issue #9 D3). diff --git a/.github/workflows/release-exercise.yml b/.github/workflows/release-exercise.yml index 90201c4..6bd5097 100644 --- a/.github/workflows/release-exercise.yml +++ b/.github/workflows/release-exercise.yml @@ -28,8 +28,6 @@ name: release exercise # rehearsal. on: workflow_dispatch: - workflow_call: - permissions: contents: read diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d604f0e..84fa100 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -109,17 +109,7 @@ name: release # via a local-path call) and by the #13 pilot's rehearsal. on: - workflow_call: - inputs: - version-source: - description: >- - Where the tree's version lives: "file" (a VERSION file — box, rig, - incubator) or "package-json" (the version field, lockfile kept in - sync on bump — cast) - type: string - required: false - default: file - + workflow_dispatch: env: # A called workflow arrives without its repository. This literal pin is # stamped by ceremony's own release PR to the version being released — diff --git a/.github/workflows/self-labels.yml b/.github/workflows/self-labels.yml index 272f429..d673d7d 100644 --- a/.github/workflows/self-labels.yml +++ b/.github/workflows/self-labels.yml @@ -5,45 +5,7 @@ name: labels # unpinned — correct only for the repo that IS the source). Consumers write: # uses: heavy-duty/ceremony/.github/workflows/labels.yml@ on: - # The consumer owns this cadence (#203). Hourly is the recommended default - # when no other engine drives board state: the cron is then the sweep's ONLY - # wake for four transition classes — a review verdict landing (there is no - # pull_request_review trigger here), blocker:ci-red set or cleared (no - # check_suite/check_run/workflow_run), a blocker:conflict when ANOTHER PR - # merges under this one, and the time-based stale / 48h claim-reclaim. The - # events below carry the rest in seconds. Hourly trades ≤1h of latency on - # those four while cutting nominal scheduled sweeps from four an hour to one - # at GitHub's 1-minute billing floor. Do not delete the cron: it is their - # discovery path. If another engine writes some of those transitions, only - # the classes with no other writer bound the cadence; relax it only as that - # list shrinks. - schedule: [{cron: "0 * * * *"}] - # A manual full-board sweep, including taxonomy bootstrap on a fresh repo. workflow_dispatch: - # Narrowed (#199) to the actions that carry a queue-state change the hourly - # cron cannot wait one cadence for — dropping only labeled/unlabeled/assigned/ - # unassigned, which feed validation and the 48h claim clock (caught within one - # cadence) and were the dominant issues-churn source. Kept: `opened` (the - # mint→needs-triage check, issueflow's opened-only path), `closed` (the - # blocker-closes→ready self-heal, crew#96/#98), `edited` (a body rewrite of the - # `Blocked by #N` declaration the sweep parses — issueflow-reconcile.sh:179), - # `reopened` (a closed issue re-entering the queue wearing labels derived when - # it closed). The must-fail in #199 is exactly "a queue-state transition waits - # on the schedule when an event could have carried it", so edited/reopened stay - # on events. The PR handoff wake is pull_request_target:labeled, NOT issues, so - # this does not touch the handoff. - issues: - types: [opened, closed, edited, reopened] - pull_request_target: - # Every PR arrives from a fork, so these carry the head/draft/review facts - # the sweep derives state:* from. labeled/unlabeled are the handoff wake — - # the author's optimistic state:needs-human write, confirmed or corrected - # here in seconds (#11); synchronize re-derives on every push; - # review_requested/review_request_removed wake the sweep that clears (or - # restores) blocker:unrequested — without them the one event that makes - # the label false could not clear it, and a quiet repo wore the red flag - # until the advisory cron (#137). - types: [opened, reopened, ready_for_review, converted_to_draft, synchronize, labeled, unlabeled, review_requested, review_request_removed] permissions: contents: read checks: read # mergeability/check-rollup read for PR state diff --git a/.github/workflows/self-release.yml b/.github/workflows/self-release.yml index b9cf91c..68345b3 100644 --- a/.github/workflows/self-release.yml +++ b/.github/workflows/self-release.yml @@ -9,13 +9,7 @@ name: release # Consumers write: # uses: heavy-duty/ceremony/.github/workflows/release.yml@ on: - # ONE push key, both filters — YAML maps are last-key-wins; a second - # sibling `push:` silently replaces the first and kills a door (rig's - # review catch). - push: - tags: ["**"] # every tag — a wrong tag must FAIL the assert loudly, - # never be skipped by a shape filter that didn't match - branches: [main] + workflow_dispatch: permissions: contents: write # tag ref create + release create + the bump push pull-requests: write # decide's label read; the bump-fallback `gh pr create`