probe: ceremony CI at 9357f09, shellcheck installed, pins intact
Some checks failed
CI / test (push) Failing after 15s

This commit is contained in:
probe 2026-08-02 20:20:41 +00:00
parent 9357f09aea
commit 21ac9fd06f
6 changed files with 5 additions and 167 deletions

View file

@ -15,6 +15,8 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Install shellcheck
run: sudo apt-get update -qq && sudo apt-get install -y -qq shellcheck
- name: Shellcheck - name: Shellcheck
run: bash .github/scripts/shellcheck-all.sh run: bash .github/scripts/shellcheck-all.sh
- name: Install actionlint - name: Install actionlint
@ -50,110 +52,3 @@ jobs:
# push+refs/heads/main event — the merge door's exact gate — opening a # 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 # live door from CI. A pull_request event can never satisfy either
# door's `if:`. # 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

View file

@ -23,8 +23,7 @@ name: labels
# create workflow runs from GITHUB_TOKEN-triggered events. Agent writes use a # create workflow runs from GITHUB_TOKEN-triggered events. Agent writes use a
# PAT and therefore do trigger — exactly the asymmetry wanted. # PAT and therefore do trigger — exactly the asymmetry wanted.
on: on:
workflow_call: workflow_dispatch:
env: env:
# A called workflow arrives without its repository. Keep this literal pin # A called workflow arrives without its repository. Keep this literal pin
# aligned with the ceremony release consumed by callers (issue #9 D3). # aligned with the ceremony release consumed by callers (issue #9 D3).

View file

@ -28,8 +28,6 @@ name: release exercise
# rehearsal. # rehearsal.
on: on:
workflow_dispatch: workflow_dispatch:
workflow_call:
permissions: permissions:
contents: read contents: read

View file

@ -109,17 +109,7 @@ name: release
# via a local-path call) and by the #13 pilot's rehearsal. # via a local-path call) and by the #13 pilot's rehearsal.
on: on:
workflow_call: workflow_dispatch:
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
env: env:
# A called workflow arrives without its repository. This literal pin is # A called workflow arrives without its repository. This literal pin is
# stamped by ceremony's own release PR to the version being released — # stamped by ceremony's own release PR to the version being released —

View file

@ -5,45 +5,7 @@ name: labels
# unpinned — correct only for the repo that IS the source). Consumers write: # unpinned — correct only for the repo that IS the source). Consumers write:
# uses: heavy-duty/ceremony/.github/workflows/labels.yml@<pinned-tag> # uses: heavy-duty/ceremony/.github/workflows/labels.yml@<pinned-tag>
on: 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: 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: permissions:
contents: read contents: read
checks: read # mergeability/check-rollup read for PR state checks: read # mergeability/check-rollup read for PR state

View file

@ -9,13 +9,7 @@ name: release
# Consumers write: # Consumers write:
# uses: heavy-duty/ceremony/.github/workflows/release.yml@<pinned-tag> # uses: heavy-duty/ceremony/.github/workflows/release.yml@<pinned-tag>
on: on:
# ONE push key, both filters — YAML maps are last-key-wins; a second workflow_dispatch:
# 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]
permissions: permissions:
contents: write # tag ref create + release create + the bump push contents: write # tag ref create + release create + the bump push
pull-requests: write # decide's label read; the bump-fallback `gh pr create` pull-requests: write # decide's label read; the bump-fallback `gh pr create`