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
30 changes: 25 additions & 5 deletions .github/scripts/validate-pr-description.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,29 @@
* Validate that a PR description has a filled Overview section.
* Intended for use with actions/github-script.
*
* Revert PRs and bot authors whose login matches EXEMPT_BOT_LOGIN_PATTERN are
* exempt; detection lives here rather than in a caller/workflow `if` condition
* so the job still completes successfully instead of showing as skipped, which
* can block merges when this check is required.
*
* @param {{ core: import('@actions/core'), context: import('@actions/github').Context }} params
* @param {{ minOverviewLength?: number }} options
*/
/**
* Revert PRs are exempt from description validation. Detection lives here rather than
* in a workflow `if` condition so the job still completes successfully instead of
* showing as skipped, which can block merges when this check is required.
*/

/** Case-insensitive: "alloy" anywhere, or "ai" as a hyphen/underscore-delimited token. */
const EXEMPT_BOT_LOGIN_PATTERN = /alloy|(?:^|[-_])ai(?:[-_]|$)/i;

function normalizeBotLogin(login) {
return (login ?? '').toLowerCase().replace(/\[bot\]$/, '');
}

function isExemptBotPr(pr) {
if (pr?.user?.type !== 'Bot') {
return false;
}
return EXEMPT_BOT_LOGIN_PATTERN.test(normalizeBotLogin(pr?.user?.login));
}

function isRevertPr(pr) {
const title = pr?.title ?? '';
const headRef = pr?.head?.ref ?? '';
Expand All @@ -20,6 +35,11 @@ module.exports = async function validatePrDescription({ core, context }, options
const minOverviewLength = Number(options.minOverviewLength) || 40;
const pr = context.payload.pull_request;

if (isExemptBotPr(pr)) {
core.info('Skipping PR description check for exempt bot-authored PR.');
return;
}

if (isRevertPr(pr)) {
core.info('Skipping PR description check for revert PR.');
return;
Expand Down
12 changes: 11 additions & 1 deletion .github/workflows/callable.pr-description-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ on:
GH_TOKEN:
required: true

# The actual use of the workflow should have the following:
#on:
# pull_request:
# types: [opened, edited, reopened]
#
# Exempt bot and revert PRs are handled in validate-pr-description.js so this job
# still passes. Other bot PRs must fill Overview. Callers must always invoke this
# workflow — do not add a job-level if on the caller, or the required check stays
# pending for bot-authored PRs.

jobs:
pr-description-check:
name: PR description check
Expand All @@ -37,7 +47,7 @@ jobs:
const script = require('${{ github.workspace }}/.github/scripts/validate-pr-description.js');
// github, context, and core are injected by github-script from this
// job's runtime context (the caller's workflow run / PR payload).
// Revert PRs (title "Revert ..." or revert-* branch) are exempt — see validate-pr-description.js.
// Exempt bot and revert PRs are handled in validate-pr-description.js.
await script(
{ github, context, core },
{ minOverviewLength: Number(process.env.MIN_OVERVIEW_LENGTH) }
Expand Down