From 37ff975c49ec573bed63fb979d6499924f60b955 Mon Sep 17 00:00:00 2001 From: Andy Fundinger Date: Tue, 19 May 2026 14:31:29 -0400 Subject: [PATCH 1/6] Adding pr-checklist.yml to ensure PR template sign-off compliance. --- .github/workflows/pr-checklist.yml | 42 ++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .github/workflows/pr-checklist.yml diff --git a/.github/workflows/pr-checklist.yml b/.github/workflows/pr-checklist.yml new file mode 100644 index 0000000..6ae658b --- /dev/null +++ b/.github/workflows/pr-checklist.yml @@ -0,0 +1,42 @@ +name: PR Checklist + +on: + pull_request: + types: [opened, edited, reopened, synchronize] + +jobs: + check-pr-template: + runs-on: ubuntu-latest + steps: + - name: Check PR body + env: + PR_BODY: ${{ github.event.pull_request.body }} + run: | + require() { + if ! grep -qE -- "$1" <<< "$PR_BODY"; then + echo "::error::$2" + exit 1 + fi + } + + require "^[[:space:]]*## PR Checklist:" \ + "PR checklist absent. We require PRs to use our template, your PR will be ignored until/unless you change to the standard template. See https://beeware.org/contributing/guide/how/submit-pr/ for details." + + require "^[[:space:]]*- \[\s*[xX]\s*\] I will abide by the BeeWare Code of Conduct" \ + "The 'Code of Conduct' checkbox must be checked." + + require "^[[:space:]]*- \[\s*[xX]\s*\] I have read and have followed the \*\*CONTRIBUTING.md\*\* file" \ + "The 'CONTRIBUTING.md' checkbox must be checked." + + if grep -qE -- "^[[:space:]]*- \[\s*[xX]\s*\] This PR was generated or assisted using an AI tool" <<< "$PR_BODY"; then + require "^[[:space:]]*(-\s+)?Assisted-by:" "'Assisted-by:' line is missing." + + # Extract the value, strip HTML comments and whitespace + ASSISTED_BY_VAL=$(grep -E "^[[:space:]]*(-\s+)?Assisted-by:" <<< "$PR_BODY" | sed -r -e 's/^[[:space:]]*(-\s+)?Assisted-by://' -e 's///' | tr -d '[:space:]') + if [ -z "$ASSISTED_BY_VAL" ]; then + echo "::error::You checked the AI tool checkbox but did not specify the tool in 'Assisted-by:'." + exit 1 + fi + fi + + echo "PR Checklist verification passed." From 35e75419279f21574c876b2a6b25523459821a13 Mon Sep 17 00:00:00 2001 From: Andy Fundinger Date: Tue, 19 May 2026 16:28:52 -0400 Subject: [PATCH 2/6] Add workflow_call as a trigger. --- .github/workflows/pr-checklist.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr-checklist.yml b/.github/workflows/pr-checklist.yml index 6ae658b..5dd6a7d 100644 --- a/.github/workflows/pr-checklist.yml +++ b/.github/workflows/pr-checklist.yml @@ -3,6 +3,7 @@ name: PR Checklist on: pull_request: types: [opened, edited, reopened, synchronize] + workflow_call: jobs: check-pr-template: From e1637e5883846bb6818d486100f40d4fae173051 Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Tue, 19 May 2026 19:53:35 -0700 Subject: [PATCH 3/6] Minor tweaks to error text --- .github/workflows/pr-checklist.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pr-checklist.yml b/.github/workflows/pr-checklist.yml index 5dd6a7d..e5863d3 100644 --- a/.github/workflows/pr-checklist.yml +++ b/.github/workflows/pr-checklist.yml @@ -21,13 +21,13 @@ jobs: } require "^[[:space:]]*## PR Checklist:" \ - "PR checklist absent. We require PRs to use our template, your PR will be ignored until/unless you change to the standard template. See https://beeware.org/contributing/guide/how/submit-pr/ for details." + "Could not find the BeeWare PR checklist in the pull request comment. This probably means you've used a tool to submit your PR, rather than the GitHub UI. The BeeWare project provides, and requires the use of a standard template for all PRs. Your PR will be ignored until/unless you add the required components of the template. See https://beeware.org/contributing/guide/how/submit-pr/ for details." require "^[[:space:]]*- \[\s*[xX]\s*\] I will abide by the BeeWare Code of Conduct" \ - "The 'Code of Conduct' checkbox must be checked." + "The 'Code of Conduct' checkbox in the PR checklist must be checked." require "^[[:space:]]*- \[\s*[xX]\s*\] I have read and have followed the \*\*CONTRIBUTING.md\*\* file" \ - "The 'CONTRIBUTING.md' checkbox must be checked." + "The 'CONTRIBUTING.md' checkbox in the PR checklist must be checked." if grep -qE -- "^[[:space:]]*- \[\s*[xX]\s*\] This PR was generated or assisted using an AI tool" <<< "$PR_BODY"; then require "^[[:space:]]*(-\s+)?Assisted-by:" "'Assisted-by:' line is missing." @@ -35,7 +35,7 @@ jobs: # Extract the value, strip HTML comments and whitespace ASSISTED_BY_VAL=$(grep -E "^[[:space:]]*(-\s+)?Assisted-by:" <<< "$PR_BODY" | sed -r -e 's/^[[:space:]]*(-\s+)?Assisted-by://' -e 's///' | tr -d '[:space:]') if [ -z "$ASSISTED_BY_VAL" ]; then - echo "::error::You checked the AI tool checkbox but did not specify the tool in 'Assisted-by:'." + echo "::error::You checked the AI tool checkbox in the PR template, but did not specify the tool that was used in 'Assisted-by:'." exit 1 fi fi From 5dca85bf224927d55d5d0b1a9def1ad875f11eee Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Tue, 19 May 2026 19:55:16 -0700 Subject: [PATCH 4/6] Add name to task. --- .github/workflows/pr-checklist.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr-checklist.yml b/.github/workflows/pr-checklist.yml index e5863d3..34f5540 100644 --- a/.github/workflows/pr-checklist.yml +++ b/.github/workflows/pr-checklist.yml @@ -7,6 +7,7 @@ on: jobs: check-pr-template: + name: Check PR template runs-on: ubuntu-latest steps: - name: Check PR body From 1a9ef4b8a04ff4627ba15d0de4122bd2a14b8316 Mon Sep 17 00:00:00 2001 From: Andy Fundinger Date: Tue, 19 May 2026 17:22:51 -0400 Subject: [PATCH 5/6] Add explannatory comment for PR check. --- .github/workflows/pr-checklist.yml | 57 ++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pr-checklist.yml b/.github/workflows/pr-checklist.yml index 34f5540..c0e2641 100644 --- a/.github/workflows/pr-checklist.yml +++ b/.github/workflows/pr-checklist.yml @@ -5,19 +5,30 @@ on: types: [opened, edited, reopened, synchronize] workflow_call: +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: check-pr-template: name: Check PR template runs-on: ubuntu-latest + permissions: + pull-requests: write steps: - name: Check PR body env: PR_BODY: ${{ github.event.pull_request.body }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + PR_NUMBER: ${{ github.event.pull_request.number }} run: | + ERRORS=() + require() { if ! grep -qE -- "$1" <<< "$PR_BODY"; then echo "::error::$2" - exit 1 + ERRORS+=("$2") fi } @@ -30,15 +41,55 @@ jobs: require "^[[:space:]]*- \[\s*[xX]\s*\] I have read and have followed the \*\*CONTRIBUTING.md\*\* file" \ "The 'CONTRIBUTING.md' checkbox in the PR checklist must be checked." + require "^[[:space:]]*- \[\s*[xX]?\s*\] This PR was generated or assisted using an AI tool" \ + "The AI tool checkbox is missing. It must be present and either checked or unchecked." + if grep -qE -- "^[[:space:]]*- \[\s*[xX]\s*\] This PR was generated or assisted using an AI tool" <<< "$PR_BODY"; then require "^[[:space:]]*(-\s+)?Assisted-by:" "'Assisted-by:' line is missing." # Extract the value, strip HTML comments and whitespace ASSISTED_BY_VAL=$(grep -E "^[[:space:]]*(-\s+)?Assisted-by:" <<< "$PR_BODY" | sed -r -e 's/^[[:space:]]*(-\s+)?Assisted-by://' -e 's///' | tr -d '[:space:]') if [ -z "$ASSISTED_BY_VAL" ]; then - echo "::error::You checked the AI tool checkbox in the PR template, but did not specify the tool that was used in 'Assisted-by:'." - exit 1 + MSG="You checked the AI tool checkbox in the PR template, but did not specify the tool that was used in 'Assisted-by:'." + echo "::error::$MSG" + ERRORS+=("$MSG") + fi + fi + + if [ ${#ERRORS[@]} -gt 0 ]; then + # Find existing comments + COMMENT_IDS=$(gh api --paginate repos/$REPO/issues/$PR_NUMBER/comments --jq '.[] | select(.body | contains("")) | .id') + + PREFIX="" + if [ -n "$COMMENT_IDS" ]; then + for ID in $COMMENT_IDS; do + # Delete existing comment + gh api -X DELETE repos/$REPO/issues/comments/$ID > /dev/null + done + PREFIX="As previously noted, " fi + + # Build the comment body + COMMENT_BODY=" + Hi there! ${PREFIX}your pull request is missing some required elements. Please review and complete the checklist in our PR template. + + **Missing items:** + " + for ERR in "${ERRORS[@]}"; do + COMMENT_BODY+="- $ERR + " + done + + COMMENT_BODY+=" + For key details on how to contribute, please review and follow the [**CONTRIBUTING.md**](https://github.com/$REPO/blob/main/CONTRIBUTING.md) file. + " + + # Strip leading indentation from COMMENT_BODY + COMMENT_BODY=$(printf '%s\n' "$COMMENT_BODY" | sed -E 's/^[[:space:]]+//') + # Post new comment + gh api repos/$REPO/issues/$PR_NUMBER/comments -f body="$COMMENT_BODY" > /dev/null + + exit 1 fi echo "PR Checklist verification passed." From f782e5f898cceae2925dd02578b010dd91390e48 Mon Sep 17 00:00:00 2001 From: Andy Fundinger Date: Tue, 19 May 2026 20:28:50 -0400 Subject: [PATCH 6/6] Revising message for better tone. --- .github/workflows/pr-checklist.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-checklist.yml b/.github/workflows/pr-checklist.yml index c0e2641..cc797d9 100644 --- a/.github/workflows/pr-checklist.yml +++ b/.github/workflows/pr-checklist.yml @@ -71,7 +71,7 @@ jobs: # Build the comment body COMMENT_BODY=" - Hi there! ${PREFIX}your pull request is missing some required elements. Please review and complete the checklist in our PR template. + Thank you for your pull request! However, ${PREFIX}your pull request is missing some required elements. Please review and complete the checklist in our PR template. **Missing items:** "