Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions .github/workflows/autolabeler.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,37 @@ name: 🏷️ Autolabel Pull Requests
# Applies release-drafter labels (feature/fix/chore) to incoming PRs based on
# branch-name patterns from .github/release-drafter.yml. Labels feed into the
# changelog categories that release-drafter.yaml later groups for the draft.
#
# `pull_request_target`, not `pull_request`: a `pull_request` run on a fork gets
# a read-only GITHUB_TOKEN whatever `permissions:` asks for - that block only
# drops privileges - so labelling failed on every outside contribution and left
# a red check nobody could clear. This runs from `main` with a token that can
# write, and reads the config from `main` too.
#
# That token is why: **never check out, install or execute pull request code
# here.** One checkout of the PR ref plus one `npm ci` hands write access to a
# stranger's postinstall script. This job talks to the API and nothing else.
# Anything that runs contributor code belongs in ci.yaml.

on:
pull_request:
pull_request_target:
types:
- opened
- reopened
- synchronize

permissions:
contents: read
pull-requests: write

jobs:
autolabel:
name: 🏷️ Autolabel pull request
runs-on: ubuntu-latest
steps:
# Pinned to the commit behind v7: tags are mutable, and this one now
# resolves inside a job holding a write token.
- name: 🏷️ Run autolabeler
uses: release-drafter/release-drafter/autolabeler@v7
uses: release-drafter/release-drafter/autolabeler@34d80673e067bdc0c24568d3af899c216adcfaa9 # v7
with:
config-name: release-drafter.yml
15 changes: 15 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,21 @@ adding packager `ignore` rules.
- **`pages.yaml`** — publishes `docs/` on pushes to `main` touching `docs/**`.
- **`autolabeler.yaml`** — applies changelog labels from branch-name patterns
(`feat/`, `fix/`, `chore/`). Any other prefix needs labels set by hand.
On **`pull_request_target`**, and it must stay there: a `pull_request` run on
a fork gets a read-only token whatever `permissions:` asks for. The trade is
a write token, so **it must never check out, install or run pull request
code**, and its action is pinned to a commit, not a tag.

**Pull requests from forks** get no secrets and a read-only token, by design.
`ci.yaml` runs contributor code, so it stays on `pull_request`, and `sign:
false` keeps the Developer ID out of a job that runs it. Lint, the end-to-end
tests and an unsigned six-row build are what a fork gets — enough to merge on.
Two repository settings would clear a red fork check by handing fork code the
keys: *send write tokens to* and *send secrets and variables to workflows from
fork pull requests*. Leave both off; a job needing a write token gets its own
checkout-free `pull_request_target` workflow instead. The separate *require
approval* gate, where a fork's run waits for a maintainer to press **Approve
and run** once per push, is expected, not a failure.

**Version numbers come from PR labels, not `package.json`.** The
release-drafter resolver reads `major`/`minor`/`patch` off merged PRs and
Expand Down