actions/slash-commands/action.yml
Den Delimarsky 225d66d1f2
slash-commands: gate project status update on a required PR label
Add project-gate-label input. When set, the project status update on
/lgtm accept only runs if the PR carries that label — lets callers
restrict project-board tracking to a subset of PRs (e.g. only SEPs go
to the SEP Review Pipeline, not every accepted PR).

onAccept now takes the full PR object instead of (number, nodeId) so it
can inspect labels without a second fetch.

Label removal via remove-labels-on-accept is unchanged — it runs on
every accept regardless of the gate.

🏠 Remote-Dev: homespace
2026-03-28 01:46:32 +00:00

149 lines
5.9 KiB
YAML

name: PR Slash Commands
description: >-
Handles /lgtm, /hold, and /stageblog slash commands on PRs. Core maintainers
can approve via /lgtm (adds an accepted label, submits a bot APPROVE review,
and enables auto-merge). Core maintainers or CODEOWNERS can block via /hold
or trigger a blog preview staging workflow via /stageblog. Approval is
invalidated when new commits are pushed.
inputs:
github-token:
description: >-
GitHub App installation token used for all API calls: team-membership
checks, labels, comments, reactions, reviews, auto-merge, CODEOWNERS
fetch, and workflow dispatch. Must have Organization Members:read plus
Repository Pull requests:write and Contents:read (and Actions:write if
/stageblog is enabled). The default GITHUB_TOKEN will NOT work — it
lacks read:org and its approvals may not count toward required reviews.
required: true
approved-label:
description: Label added by /lgtm to mark the PR as accepted
required: false
default: accepted
hold-label:
description: Label added by /hold to block merging
required: false
default: do-not-merge/hold
always-allow-teams:
description: >-
Comma-separated team slugs (within the repo's org) whose members may
/lgtm any PR. Only these teams can /lgtm — CODEOWNERS does not grant
/lgtm authorization. Members may also /hold and /stageblog any PR.
required: false
default: core-maintainers
force-allow-teams:
description: >-
Comma-separated team slugs (within the repo's org) whose members may
use /lgtm force. This bypasses the self-approval guard and CODEOWNERS —
only membership in one of these teams grants it.
required: false
default: core-maintainers,lead-maintainers
codeowners-path:
description: Path to the CODEOWNERS file (fetched from the PR base branch)
required: false
default: .github/CODEOWNERS
invalidate-on-push:
description: >-
Remove the approved label and dismiss the bot review when new commits
are pushed to the PR. Set to 'false' to keep approval across pushes.
required: false
default: 'true'
submit-review:
description: >-
Whether to submit a bot APPROVE review alongside the label on /lgtm.
Set to 'false' to rely on the label alone.
required: false
default: 'true'
enable-auto-merge:
description: >-
Enable auto-merge on the PR after a successful /lgtm. The PR will merge
automatically once all required checks pass. Requires the repo to have
"Allow auto-merge" enabled in Settings. Disabled on /lgtm cancel and on
push invalidation.
required: false
default: 'true'
auto-merge-method:
description: Merge method for auto-merge — one of squash, merge, rebase
required: false
default: squash
remove-labels-on-accept:
description: >-
Comma-separated label names to remove from the PR when /lgtm accepts it
(e.g. in-review,draft,proposal). Missing labels are ignored.
required: false
default: ''
project-number:
description: >-
Org-level Project (V2) number to update when /lgtm accepts the PR. Leave
empty to disable project updates. The PR is added to the project if not
already present.
required: false
default: ''
project-status-field:
description: Name of the single-select field to set on accept
required: false
default: Status
project-accepted-option:
description: Name of the option to set in the status field on accept
required: false
default: Accepted
project-gate-label:
description: >-
If set, only update the project status when the PR has this label.
Leave empty to update the project for every accepted PR.
required: false
default: ''
stageblog-workflow:
description: >-
Workflow file name (e.g. stage-blog.yml) to dispatch when /stageblog is
invoked. Leave empty to disable the command. The workflow must accept
inputs 'pr_number' and 'head_sha'.
required: false
default: ''
stageblog-paths:
description: >-
Comma-separated glob patterns (CODEOWNERS-style: **, *, ?, leading /,
trailing /) matched against the PR's changed files. /stageblog is refused
if no file matches.
required: false
default: 'blog/**'
outputs:
result:
description: >-
One of: lgtm-added, lgtm-forced, lgtm-removed, hold-added, hold-removed,
invalidated, unauthorized, force-unauthorized, self-lgtm-blocked,
stageblog-dispatched, stageblog-not-blog, stageblog-disabled, noop
value: ${{ steps.handle.outputs.result }}
actor:
description: Login of the user who triggered the action (commenter)
value: ${{ steps.handle.outputs.actor }}
runs:
using: composite
steps:
- name: Handle slash command
id: handle
uses: actions/github-script@v8
env:
APPROVED_LABEL: ${{ inputs.approved-label }}
HOLD_LABEL: ${{ inputs.hold-label }}
ALWAYS_ALLOW_TEAMS: ${{ inputs.always-allow-teams }}
FORCE_ALLOW_TEAMS: ${{ inputs.force-allow-teams }}
CODEOWNERS_PATH: ${{ inputs.codeowners-path }}
INVALIDATE_ON_PUSH: ${{ inputs.invalidate-on-push }}
SUBMIT_REVIEW: ${{ inputs.submit-review }}
ENABLE_AUTO_MERGE: ${{ inputs.enable-auto-merge }}
AUTO_MERGE_METHOD: ${{ inputs.auto-merge-method }}
REMOVE_LABELS_ON_ACCEPT: ${{ inputs.remove-labels-on-accept }}
PROJECT_NUMBER: ${{ inputs.project-number }}
PROJECT_STATUS_FIELD: ${{ inputs.project-status-field }}
PROJECT_ACCEPTED_OPTION: ${{ inputs.project-accepted-option }}
PROJECT_GATE_LABEL: ${{ inputs.project-gate-label }}
STAGEBLOG_WORKFLOW: ${{ inputs.stageblog-workflow }}
STAGEBLOG_PATHS: ${{ inputs.stageblog-paths }}
with:
github-token: ${{ inputs.github-token }}
script: |
const main = require(process.env.GITHUB_ACTION_PATH + '/main.js');
await main({ github, context, core });