Skip to content

Commit 9e6d7ac

Browse files
authored
Merge pull request #202 from modeseven-lfreleng-actions/refactor/autolabeler-to-generic-workflows
Refactor: Call the migrated autolabeler lane
2 parents 1d28a49 + bb53b69 commit 9e6d7ac

1 file changed

Lines changed: 72 additions & 88 deletions

File tree

.github/workflows/autolabeler.yaml

Lines changed: 72 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -2,58 +2,62 @@
22
# SPDX-FileCopyrightText: 2025 The Linux Foundation
33
# SPDX-License-Identifier: Apache-2.0
44

5+
# Pull request autolabeler (organisation-wide).
6+
#
7+
# Thin caller for the reusable lane in lfreleng-actions/generic-workflows.
8+
# This file is the canonical copy enforced organisation-wide via the
9+
# mandatory-workflows ruleset, so labelling runs on every targeted
10+
# repository without being copied into each one (it also labels pull
11+
# requests raised against this repository).
12+
#
13+
# The labels matter beyond the pull request view: Release Drafter reads
14+
# them to sort entries into release-note categories and to resolve the
15+
# next version, because each category in .github/release-drafter.yml
16+
# carries its own semver-increment.
17+
#
18+
# The routing between the two triggers below lives in the reusable, not
19+
# here. See docs/autolabeler.md in generic-workflows.
520
name: 'Auto Label 🏷️'
621

722
# yamllint disable-line rule:truthy
823
on:
9-
# pull_request is required for autolabeler
10-
pull_request:
11-
types:
12-
- opened
13-
- synchronize
14-
- reopened
15-
# pull_request_target is required for autolabeler on PRs from forks.
24+
# pull_request covers pull requests raised from a branch of the
25+
# target repository.
1626
#
17-
# This use of pull_request_target is safe and does NOT need
18-
# manual-approval gating because:
27+
# 'edited' is load-bearing. Every autolabeler rule in
28+
# .github/release-drafter.yml matches on the pull request TITLE, so a
29+
# title corrected after opening needs a fresh run to earn its label.
30+
# Without it, the common sequence of opening without a Conventional
31+
# Commits prefix, failing the semantic pull request check, then fixing
32+
# the title, leaves the pull request unlabelled for good: it lands in
33+
# no release-note category and contributes no version increment.
34+
# 'synchronize' does not cover this, firing on a push rather than on a
35+
# metadata edit.
36+
pull_request:
37+
types: [opened, synchronize, reopened, edited]
38+
# pull_request_target covers pull requests raised from another
39+
# repository, which pull_request cannot label because GitHub hands it
40+
# a token without write access.
1941
#
20-
# 1. The workflow performs no checkout of PR code
21-
# (no actions/checkout step), so no PR-provided source
22-
# ever runs.
23-
# 2. The workflow body is loaded from the base branch
24-
# (pull_request_target semantics), not from the PR head.
25-
# 3. Every step is pinned to a full commit SHA and runs
26-
# only trusted, pinned action code, never PR-provided
27-
# source. Each is a well-scoped consumer:
28-
# - `lfreleng-actions/harden-runner-block-action`
29-
# fetches one allow-list file over HTTPS, sanitises
30-
# it, and publishes it as $CONNECTION_ALLOW_LIST.
31-
# It reads no PR content.
32-
# - `step-security/harden-runner` installs the egress
33-
# block filter from $CONNECTION_ALLOW_LIST. Pure
34-
# runner-hardening; reads no PR content.
35-
# - `release-drafter/release-drafter/autolabeler`
36-
# makes only GitHub API calls; it reads PR metadata
37-
# (e.g. title and labels) to apply labels but never
38-
# checks out or runs PR head source.
39-
# 4. Permissions are scoped to the minimum needed:
40-
# pull-requests: write and contents: read. No
41-
# repository secrets are passed to the job beyond the
42-
# default GITHUB_TOKEN, which the job receives with the
43-
# permissions scope above and nothing more.
44-
# 5. The runner is hardened with an egress block applied
45-
# before the autolabeler step runs.
42+
# This use of pull_request_target is safe and needs no manual-approval
43+
# gating, because the conditions zizmor's dangerous-triggers audit
44+
# warns about (pull request head code running with elevated
45+
# privileges) cannot arise:
4646
#
47-
# See the SECURITY block on the autolabel job below for the
48-
# full rationale. The zizmor `dangerous-triggers` audit is
49-
# silenced here because the conditions it warns about (PR
50-
# head code running with elevated privileges) cannot occur in
51-
# this workflow.
47+
# 1. The lane has NO checkout step, so head source never reaches the
48+
# runner, let alone runs.
49+
# 2. pull_request_target loads the workflow body from the base
50+
# branch, and the pinned 'uses:' ref below fixes the content of
51+
# the reusable it calls.
52+
# 3. Every step in the lane pins a commit SHA and runs trusted code:
53+
# harden-runner-block-action fetches one allow-list file,
54+
# harden-runner installs the egress filter, and the autolabeler
55+
# makes GitHub API calls against pull request metadata. None of
56+
# the three reads or runs head source.
57+
# 4. Permissions stop at the two grants declared on the job below,
58+
# and the egress block lands before the autolabeler step runs.
5259
pull_request_target: # zizmor: ignore[dangerous-triggers]
53-
types:
54-
- opened
55-
- synchronize
56-
- reopened
60+
types: [opened, synchronize, reopened, edited]
5761

5862
permissions: {}
5963

@@ -71,53 +75,33 @@ concurrency:
7175
# serialise every open pull request into one group.
7276
# yamllint disable-line rule:line-length
7377
group: 'org-autolabeler-${{ github.event_name }}-pr-${{ github.event.pull_request.number }}'
78+
# Cancelling is safe here, unlike the semantic pull request check.
79+
# Labelling is idempotent, and this workflow publishes no check run
80+
# that a required status check names, so a superseded run leaves
81+
# nothing behind for the merge box to report.
7482
cancel-in-progress: true
7583

7684
jobs:
7785
autolabel:
7886
name: 'Label PR'
79-
# Run on pull_request_target for forks, or pull_request for same-repo PRs
80-
# This prevents duplicate runs for same-repo PRs
81-
# yamllint disable rule:line-length
82-
if: >
83-
(github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.fork) ||
84-
(github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork)
85-
# yamllint enable rule:line-length
86-
# SECURITY: pull_request_target with write permissions is safe here because:
87-
# 1. This workflow does NOT checkout any code from the PR
88-
# 2. The workflow code itself runs from the base branch (not the fork)
89-
# 3. release-drafter runs only trusted, SHA-pinned action code and
90-
# makes GitHub API calls; it reads PR metadata but never runs
91-
# PR head source
92-
# 4. pull_request_target is needed ONLY for autolabeling fork PRs
87+
# No 'if:' here by design. The reusable carries the routing
88+
# condition, which compares the head repository against the base
89+
# repository so that each pull request takes exactly one of the two
90+
# triggers. Repeating it here would duplicate logic that is easy to
91+
# get wrong, and the version this file used to carry keyed on
92+
# head.repo.fork, which reports whether the head repository is
93+
# itself a fork rather than whether the pull request crosses
94+
# repositories.
95+
# yamllint disable-line rule:line-length
96+
uses: lfreleng-actions/generic-workflows/.github/workflows/autolabeler.yaml@41059e423606179bc80dedcdd1a50331d059788e # v0.2.1
9397
permissions:
94-
pull-requests: write # Autolabeler applies labels to pull requests
95-
# read is sufficient; autolabeler does not create releases
96-
contents: read
97-
runs-on: 'ubuntu-latest'
98-
timeout-minutes: 3
99-
steps:
100-
# Load the egress allow-list out-of-band from
101-
# lfreleng-actions/.github and publish it as
102-
# $CONNECTION_ALLOW_LIST for the harden-runner step below
103-
# to consume in 'block' mode. Loading out-of-band means
104-
# the workflow no longer depends on any org-level GitHub
105-
# variable being exposed at runtime (org variables are
106-
# unreachable from workflows triggered by PRs raised from
107-
# forks, which previously forced a fallback to audit mode).
108-
# yamllint disable-line rule:line-length
109-
- uses: lfreleng-actions/harden-runner-block-action@6db537b3e6d060c3287c5a3ce2c28b55b0af330d # v0.2.1
110-
with:
111-
config: '@18d9c4446bea555d0783e850f6d295f844fe8f67' # v0.1.1
112-
113-
# Harden the runner with the just-loaded allow-list.
114-
- name: 'Harden runner (block)'
115-
# yamllint disable-line rule:line-length
116-
uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
117-
with:
118-
egress-policy: 'block'
119-
allowed-endpoints: >
120-
${{ env.CONNECTION_ALLOW_LIST }}
121-
122-
# yamllint disable-line rule:line-length
123-
- uses: release-drafter/release-drafter/autolabeler@34d80673e067bdc0c24568d3af899c216adcfaa9 # v7.7.0
98+
contents: read # Lane reads the release-drafter config from the repo
99+
pull-requests: write # Lane applies labels to the pull request
100+
# No 'with:' block: the lane's defaults are this organisation's
101+
# policy. config_name defaults to 'release-drafter.yml', which
102+
# release-drafter resolves from the target repository and falls back
103+
# to this one when the target has no copy.
104+
#
105+
# No 'secrets:' block either. The lane's optional 'token' secret
106+
# exists for callers needing labels under a different identity;
107+
# unset, it uses the job's GITHUB_TOKEN, which is what ran before.

0 commit comments

Comments
 (0)