From 31bb01d1e9985ba29563c284179f890f24f3075d Mon Sep 17 00:00:00 2001 From: Adam Moussa <166072409+amoussa1229@users.noreply.github.com> Date: Thu, 11 Jun 2026 13:34:39 -0400 Subject: [PATCH] Add org-wide reusable PR labeler (INFRA-56) (#50) Add callable-labeler.yaml, a reusable workflow that carries the label rules inline as the single source of truth and writes them to the runner at execution time, so caller repos need only a short caller workflow and no per-repo labeler.yml. Triggered by callers on pull_request (private org takes no fork PRs); requires contents:read + pull-requests:write + issues:write on every caller so labeler@v5 can create missing labels. Remove the workflow-templates/labeler.yml starter it supersedes (no ruleset workflows-rule or compliance-audit reference depends on it). Add the repo's own dependabot.yml (github-actions, weekly, grouped minor+patch) to keep the action pins current per the Pinning Principle. --- .github/dependabot.yml | 11 +++ .github/workflows/callable-labeler.yaml | 88 ++++++++++++++++++++++ workflow-templates/labeler.properties.json | 7 -- workflow-templates/labeler.yml | 20 ----- 4 files changed, 99 insertions(+), 27 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/callable-labeler.yaml delete mode 100644 workflow-templates/labeler.properties.json delete mode 100644 workflow-templates/labeler.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..1210f19 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + groups: + minor-and-patch: + update-types: + - "minor" + - "patch" diff --git a/.github/workflows/callable-labeler.yaml b/.github/workflows/callable-labeler.yaml new file mode 100644 index 0000000..cc48824 --- /dev/null +++ b/.github/workflows/callable-labeler.yaml @@ -0,0 +1,88 @@ +name: Labeler + +# Reusable PR auto-labeler for all Sea-Haven-Industries repos. +# +# The label rules live HERE as the single source of truth and are written to the +# runner at execution time, so caller repos need only a short caller workflow and +# no per-repo labeler.yml. +# +# Callers trigger this on `pull_request` (NOT pull_request_target): every org repo +# is private and takes no fork PRs, so the lower-privilege event is sufficient and +# avoids the pull_request_target pwn-request surface. Because `pull_request` runs +# the workflow from the PR merge commit, the Labeler check appears on the PR that +# first adds the caller — an absent or failed Labeler check means a missing +# permission grant on the caller, not "expected" behaviour. +# +# Callers MUST grant all three permissions below. Reusable-workflow permissions can +# only be downgraded from the caller, so a caller that omits one (e.g. issues:write) +# either fails to create labels or triggers a silent startup_failure: +# permissions: +# contents: read +# pull-requests: write +# issues: write + +on: + workflow_call: + +permissions: + contents: read + pull-requests: write + issues: write + +jobs: + label: + runs-on: ubuntu-latest + steps: + - name: Write central label rules + run: | + mkdir -p "${{ runner.temp }}" + cat > "${{ runner.temp }}/labeler.yml" <<'EOF' + infra: + - changed-files: + - any-glob-to-any-file: + - 'lib/**' + - 'bin/**' + - 'cdk/**' + - 'cdk.json' + - 'template.yaml' + - 'template.yml' + - '**/template.yaml' + - 'samconfig.toml' + app: + - changed-files: + - any-glob-to-any-file: + - 'src/**' + - 'functions/**' + - 'lambdas/**' + - 'api/**' + - 'services/**' + ci: + - changed-files: + - any-glob-to-any-file: + - '.github/workflows/**' + docs: + - changed-files: + - any-glob-to-any-file: + - '**/*.md' + dependencies: + - changed-files: + - any-glob-to-any-file: + - '**/requirements.txt' + - '**/package.json' + - '**/package-lock.json' + - '**/*.csproj' + - '**/packages.lock.json' + - '.github/dependabot.yml' + tests: + - changed-files: + - any-glob-to-any-file: + - '**/tests/**' + - '**/test/**' + - '**/*.test.ts' + - '**/*_test.py' + EOF + - uses: actions/labeler@v5 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + configuration-path: ${{ runner.temp }}/labeler.yml + sync-labels: false diff --git a/workflow-templates/labeler.properties.json b/workflow-templates/labeler.properties.json deleted file mode 100644 index 06e8b23..0000000 --- a/workflow-templates/labeler.properties.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "Sea Haven — PR Labeler", - "description": "Auto-labels PRs by changed paths (infra / lambda / ci / docs). Requires a .github/labeler.yml config.", - "iconName": "octicon-tag", - "categories": ["Automation", "Pull requests"], - "filePatterns": [".github/labeler\\.ya?ml$"] -} diff --git a/workflow-templates/labeler.yml b/workflow-templates/labeler.yml deleted file mode 100644 index dbe6db3..0000000 --- a/workflow-templates/labeler.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Labeler -on: [pull_request_target] - -permissions: - contents: read - pull-requests: write - -jobs: - label: - runs-on: ubuntu-latest - steps: - # Requires .github/labeler.yml in this repo, e.g.: - # infra: [ 'cdk/**', 'template.yaml', 'oidc-deploy-roles.yaml' ] - # lambda: [ 'lambdas/**', 'src/**', 'functions/**' ] - # ci: [ '.github/workflows/**' ] - # docs: [ '**/*.md' ] - - uses: actions/labeler@v5 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - sync-labels: true