From 9be40503965ccd91137d6fcf3754b34237218c57 Mon Sep 17 00:00:00 2001 From: Michael Hucka Date: Fri, 15 Aug 2025 18:29:16 -0700 Subject: [PATCH] Add checks for titles & descriptions of PRs This adds a simple workflow triggered on pull requests being opened, reopened, or synchronized. It checks that PR descriptions are not empty, and that titles are at least 2 words and 6 characters long. These are very basic checks that hopefully everyone will agree are the minimum for reasonable PRs. --- .github/workflows/pr-text-checker.yaml | 116 +++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 .github/workflows/pr-text-checker.yaml diff --git a/.github/workflows/pr-text-checker.yaml b/.github/workflows/pr-text-checker.yaml new file mode 100644 index 00000000..9b1e8582 --- /dev/null +++ b/.github/workflows/pr-text-checker.yaml @@ -0,0 +1,116 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# Check the subject and description of each PR for basic best practices and +# fail with an error if a PR doesn't meet the conditions. +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +name: 'Pull request text checker' +run-name: >- + Check text of PR + #${{github.event.inputs.pr-number || github.event.pull_request.number}} + by ${{github.actor}} + +on: + pull_request: + types: + - opened + - reopened + - synchronize + branches: + - main + - master + + # Allow manual invocation. + workflow_dispatch: + inputs: + pr-number: + description: 'The PR number of the PR to check:' + type: string + required: true + debug: + description: 'Run with debugging options' + type: boolean + default: true + +# Declare default workflow permissions as read only. +permissions: read-all + +concurrency: + # Cancel any previously-started but still active runs on the same branch. + cancel-in-progress: true + group: ${{github.workflow}}-${{github.event.pull_request.number||github.ref}} + +jobs: + check-pr-text: + if: github.repository_owner == 'quantumlib' + name: Check PR text + runs-on: ubuntu-24.04 + timeout-minutes: 5 + env: + GH_TOKEN: ${{github.token}} + PR_NUMBER: ${{inputs.pr-number || github.event.pull_request.number}} + # The next var is used by Bash. We add 'xtrace' to the options if this run + # is a workflow_dispatch invocation and the user set the 'debug' option. + SHELLOPTS: ${{inputs.debug && 'xtrace' || '' }} + steps: + # Note that this workflow does not need to check out the git repo because + # it does not need to read any files in the repo. + + - name: Check title and description + run: | + declare -i exit_code=0 + declare success=":white_check_mark:" + declare failure=":x:" + + check() { + local condition="$1" + local message="$2" + local result="" + + eval "$condition" && result="$success" || result="$failure" + echo "| $message | $result |" >> "$GITHUB_STEP_SUMMARY" + if [[ "$result" == "$failure" ]]; then + exit_code=1 + fi + } + + data=$(gh pr view -R ${{github.repository}} "$PR_NUMBER" --json title,body) + title=$(jq -r .title <<< "$data") + body=$(jq -r .body <<< "$data") + + { + echo "## Results of checking pull request #$PR_NUMBER" + echo "" + echo "| Check | Result |" + echo "|-------|:------:|" + } >> "$GITHUB_STEP_SUMMARY" + + check "[[ $(echo "$title" | wc -w) -ge 1 ]]" "Title contains at least one word" + check "[[ ${#title} -ge 6 ]]" "Title is at least 6 characters long" + check "[[ -n \"$body\" && \"$body\" != \"null\" ]]" "Description is not empty" + + echo "" >> "$GITHUB_STEP_SUMMARY" + if (( exit_code == 0 )); then + echo "All checks passed." >> "$GITHUB_STEP_SUMMARY" + else + echo '::error::Failed checks. Please check the workflow summary page.' + { + echo "Checks failed." + echo "Please make appropriate corrections to this PR." + } >> "$GITHUB_STEP_SUMMARY" + fi + # shellcheck disable=2086 + exit $exit_code