GitNexus/.github/release-drafter.yml
Gergő Magyar 109a3c6946
ci: standardize workflow concurrency and automate release-note labeling (#837)
* ci: standardize workflow concurrency and automate release-note labeling

Concurrency — prevent racing CI jobs
 - Every top-level workflow now declares an explicit concurrency block.
 - PR runs cancel-in-progress on supersede; main/push/workflow_call/publish
   runs queue instead of cancelling so every commit and every release is
   validated end-to-end.
 - ci.yml uses a literal `CI-` prefix (not `${{ github.workflow }}`) and a
   per-run nested group for workflow_call invocations, avoiding a potential
   deadlock with publish.yml and release-candidate.yml callers whose own
   concurrency groups could otherwise collide with the called workflow.
 - ci-report.yml falls back to `<head-repo>/<head-branch>` for fork PRs
   (stable across reruns) instead of the per-run-unique workflow_run.id
   which did not actually serialize anything.
 - ci-quality.yml enforces the convention: fails CI if any non-reusable
   workflow lacks a concurrency block or a reusable workflow declares one.

Release-note automation
 - New pr-labeler.yml: amannn/action-semantic-pull-request enforces
   conventional-commit PR titles on pull_request (fork-safe, read-only);
   release-drafter/release-drafter with disable-releaser: true applies the
   matching label under pull_request_target (write-scoped). sync-labels in
   .github/release-drafter.yml removes managed autolabels that no longer
   match (e.g. when `!` or `BREAKING CHANGE:` is dropped from a PR).
 - .github/release.yml (unchanged) continues to map labels to categorized
   release-notes sections.
 - dependabot.yml added for the github-actions ecosystem so pinned SHAs
   auto-refresh on a weekly cadence.

Docs
 - CONTRIBUTING.md documents the concurrency convention, the
   conventional-commit PR-title rules, and the reusable-workflow exception.

Follow-up to verify before relying on the labeler in anger
 - gh api repos/amannn/action-semantic-pull-request/git/refs/tags/v5.5.3
 - gh api repos/release-drafter/release-drafter/git/refs/tags/v6.0.0
 - Confirm release-drafter reads its config from the base ref (not fork
   head) when invoked via pull_request_target.

* ci: address PR review feedback on concurrency and labeler workflows

Two blocking fixes
 - pr-labeler.yml: separate concurrency slots for pull_request and
   pull_request_target. Previously both triggers shared a single group
   with cancel-in-progress: true, so the privileged autolabel run could
   cancel the title-validation check mid-run and leave a required status
   in a permanent cancelled state.
 - pr-labeler.yml autolabel job: add contents: read. release-drafter's
   context.config() reads .github/release-drafter.yml from the default
   branch via the repo-contents API and 403s without the scope. Job-level
   permissions nullify all unlisted scopes so an explicit grant is needed.

Two non-blocking improvements
 - Replace the hardcoded reusable-workflow allowlist in ci-quality.yml
   with dynamic on:-block parsing. New workflow_call-only workflows no
   longer produce false-positive convention failures.
 - Implement actual group-key validation. The check now also asserts that
   every concurrency.group expression references either ${{ github.workflow }}
   or the literal CI- prefix (the documented ci.yml exception).
 - Script extracted to .github/scripts/check-workflow-concurrency.py so
   it is runnable locally and independently testable.
2026-04-15 13:24:53 +01:00

53 lines
1.5 KiB
YAML

# release-drafter config — used only for PR autolabeling by
# `.github/workflows/pr-labeler.yml` (the workflow passes `disable-releaser: true`,
# so the draft-release side of release-drafter never runs).
#
# The labels applied here are the same ones `.github/release.yml` maps to
# categorized release-notes sections.
#
# `sync-labels: true` removes managed autolabels that no longer match the PR —
# critical for the breaking-change case: if a PR title drops the `!` or the body
# drops `BREAKING CHANGE:`, the `breaking` label is pulled off automatically.
# Required by release-drafter; not used because releaser is disabled.
name-template: 'unused'
tag-template: 'unused'
template: |
$CHANGES
sync-labels: true
autolabeler:
- label: enhancement
title:
- '/^feat(\([^)]+\))?!?:/i'
- label: bug
title:
- '/^fix(\([^)]+\))?!?:/i'
- label: performance
title:
- '/^perf(\([^)]+\))?!?:/i'
- label: refactor
title:
- '/^refactor(\([^)]+\))?!?:/i'
- label: documentation
title:
- '/^docs(\([^)]+\))?!?:/i'
- label: test
title:
- '/^test(\([^)]+\))?!?:/i'
- label: ci
title:
- '/^ci(\([^)]+\))?!?:/i'
- label: dependencies
title:
- '/^(build|deps)(\([^)]+\))?!?:/i'
- label: chore
title:
- '/^(chore|revert)(\([^)]+\))?!?:/i'
# Breaking-change marker: either `!` in the type prefix or `BREAKING CHANGE:` in body.
- label: breaking
title:
- '/^[a-z]+(\([^)]+\))?!:/i'
body:
- '/BREAKING[ -]CHANGE:/i'