diff --git a/.forgejo/workflows/labels-sweep.yml b/.forgejo/workflows/labels-sweep.yml new file mode 100644 index 0000000..908b429 --- /dev/null +++ b/.forgejo/workflows/labels-sweep.yml @@ -0,0 +1,49 @@ +name: labels-sweep +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 (no + # pull_request_review trigger on the labels caller), blocker:ci-red + # set/cleared, blocker:conflict when another PR merges under this one, and + # time-based stale / 48h claim-reclaim. The labels caller's events carry the + # rest in seconds, one trigger-job dispatch away. Hourly trades ≤1h of + # latency on those four while cutting nominal scheduled sweeps from four an + # hour to one at GitHub's 1-minute 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. A bare dispatch (input default "yes") also + # bootstraps the taxonomy on a fresh repo. The labels caller's trigger job + # wakes this workflow with bootstrap=no on every board event, so the + # declared input is part of the contract: a dispatch naming an undeclared + # input is refused, and the trigger job goes loudly red. + workflow_dispatch: + inputs: + bootstrap: + description: Bootstrap the label taxonomy before sweeping + type: choice + options: ["yes", "no"] + default: "yes" +permissions: + contents: read + checks: read # mergeability/check-rollup read for PR state + statuses: read # commit-status rollup read for PR state + actions: read # workflow-run nodes inside the check rollup — private repos do not imply it (incubator#60) + issues: write + pull-requests: write +jobs: + sweep: + uses: heavy-duty/ceremony/.github/workflows/labels-sweep.yml@0.6.1 + with: + # Pass the dispatch input through the workflow_call boundary + # explicitly — a called workflow must not rely on reading the caller's + # event inputs (ceremony#215 measured that failing). Empty (schedule) + # maps to "no" explicitly, so a cron-woken sweep never re-upserts the + # taxonomy. + bootstrap: ${{ inputs.bootstrap || 'no' }} + # If this repo's PR-facing labels caller is named anything but `labels`, + # pass that name alongside: `pr_workflow_name: `. The sweep exports + # it as SELF_WORKFLOW so the label machinery's own check entries (scope, + # trigger) never count toward blocker:ci-red — a red trigger means "fix + # the caller", which no PR edit can do (#208 reads it). diff --git a/.forgejo/workflows/labels.yml b/.forgejo/workflows/labels.yml new file mode 100644 index 0000000..4b4baa4 --- /dev/null +++ b/.forgejo/workflows/labels.yml @@ -0,0 +1,34 @@ +name: labels +on: + pull_request_target: + # Fork PRs; these carry the head/draft/review facts state:* derives from. + # labeled/unlabeled are the handoff wake (state:needs-human confirmed here); + # synchronize re-derives on every push. review_requested/review_request_removed + # (shipped in 0.3.0, ceremony#137) wake the sweep that clears + # blocker:unrequested when the panel is asked. + types: [opened, reopened, ready_for_review, converted_to_draft, synchronize, labeled, unlabeled, review_requested, review_request_removed] + # Available at 0.2.0 and later (the first tag carrying ceremony#32); a + # consumer pinned to 0.1.0 omits this block. + issues: + # Narrowed (#199) to the actions carrying a queue-state change the hourly + # cron cannot wait one cadence for: opened → the mint→needs-triage check, + # closed → the blocker-closes→ready self-heal, edited → a body rewrite of the + # `Blocked by #N` declaration the sweep parses, reopened → a closed issue + # re-entering the queue. Dropped: labeled/unlabeled/assigned/unassigned — + # validation + the 48h claim clock, caught within one cadence, and + # labeled/unlabeled were the issues-churn source. The handoff wake is + # pull_request_target:labeled, not issues, so this leaves it intact. + types: [opened, closed, edited, reopened] +permissions: + contents: read + checks: read # mergeability/check-rollup read for PR state + statuses: read # commit-status rollup read for PR state + actions: write # the trigger job's dispatch of the sweep caller (#209, #205) + issues: write + pull-requests: write +jobs: + labels: + uses: heavy-duty/ceremony/.github/workflows/labels.yml@0.6.1 + # If the sweep caller below is named anything but labels-sweep.yml, + # say so: `with: { sweep_workflow: }`. Ceremony's own + # dogfood does (self-labels-sweep.yml).