IKHSAN
ENID Baca dalam Bahasa Indonesia

pixies

Public
Branch
master
Latest commit
9b0697f26 October 2026

pr-template.yml

Open raw
name: PR template guard

on:
  pull_request_target:
    types: [opened, reopened, edited, synchronize]

permissions:
  contents: read
  pull-requests: write
  issues: write

jobs:
  check:
    runs-on: ubuntu-latest
    if: >
      github.repository == 'ikhsanddy/pixies' &&
      !endsWith(github.event.pull_request.user.login, '[bot]')
    steps:
      - name: Check pull request body
        id: check
        env:
          BODY: ${{ github.event.pull_request.body }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          REPO: ${{ github.repository }}
          BASE_SHA: ${{ github.event.pull_request.base.sha }}
        run: |
          strip() { tr -d '\r' | sed -e 's/<!--.*-->//g' -e '/<!--/,/-->/d'; }

          printf '%s' "$BODY" | strip > body.md

          gh api "repos/$REPO/contents/.github/PULL_REQUEST_TEMPLATE.md?ref=$BASE_SHA" \
            --jq '.content' | base64 -d | strip > template.md

          section() {
            awk -v want="$2" '
              /^#{1,6} / { keep = (index(tolower($0), tolower(want)) > 0); next }
              keep { print }
            ' "$1"
          }

          items() {
            section "$1" "$2" \
              | grep -E '^[[:space:]]*- \[[ xX]\]' \
              | sed -E -e 's/^[[:space:]]*- \[[ xX]\][[:space:]]*//' -e 's/[[:space:]]+$//' \
              | tr -s ' ' | tr '[:upper:]' '[:lower:]' \
              | grep -v 'other:' | sort || true
          }

          headings() {
            grep -E '^#{1,6} ' "$1" \
              | sed -E -e 's/^#{1,6}[[:space:]]*//' -e 's/[[:space:]]+$//' \
              | tr -s ' ' | tr '[:upper:]' '[:lower:]' | sort || true
          }

          problems=""
          add() { problems="${problems}- $1"$'\n'; }

          tampered() {
            items template.md "$1" > canonical.txt
            items body.md "$1" > given.txt
            [ -n "$(comm -3 canonical.txt given.txt || true)" ]
          }

          if ! grep -qi '^#\{1,6\} .*Changes made to' body.md || ! grep -qi '^#\{1,6\} .*Checklist' body.md; then
            add "the pull request template was not used"
          else
            headings template.md > canonical_headings.txt
            headings body.md > given_headings.txt
            if [ -n "$(comm -3 canonical_headings.txt given_headings.txt || true)" ]; then
              add "the section headings were edited, please leave them as they are"
            fi

            if grep -qi '^#\{1,6\} .*Description' body.md; then
              description=$(section body.md "Description" | grep -v '^\s*$' || true)
              if [ -z "$description" ]; then
                add "the description is empty"
              fi
            fi

            if tampered "Changes made to"; then
              add "the options under \"Changes made to ...\" were edited, please leave them as they are"
            elif ! section body.md "Changes made to" | grep -qi '^\s*- \[x\]'; then
              add "no option is selected under \"Changes made to ...\""
            fi

            if tampered "Checklist"; then
              add "the checklist was edited, please leave the items as they are"
            elif section body.md "Checklist" | grep -q '^\s*- \[ \]'; then
              add "not every item in the checklist is checked"
            fi
          fi

          {
            echo "problems<<EOF"
            printf '%s' "$problems"
            echo "EOF"
          } >> "$GITHUB_OUTPUT"

      - name: Update comment
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          PR: ${{ github.event.pull_request.number }}
          REPO: ${{ github.repository }}
          AUTHOR: ${{ github.event.pull_request.user.login }}
          PROBLEMS: ${{ steps.check.outputs.problems }}
          MARKER: "<!-- pr-template-guard -->"
        run: |
          comment_id=$(gh api --paginate "repos/$REPO/issues/$PR/comments" \
            --jq ".[] | select(.body | contains(\"$MARKER\")) | .id" | head -n1)

          if [ -z "$PROBLEMS" ]; then
            if [ -n "$comment_id" ]; then
              gh api -X DELETE "repos/$REPO/issues/comments/$comment_id"
            fi
            gh pr edit "$PR" --repo "$REPO" --remove-label "incomplete template" || true
            exit 0
          fi

          {
            echo "$MARKER"
            echo "Hey @$AUTHOR, thanks for the pull request!"
            echo
            echo "Before we can review it, could you complete the pull request template? Right now:"
            echo
            printf '%s' "$PROBLEMS"
            echo
            echo "You can edit the description at any time, this comment disappears once everything is filled in."
          } > comment.md

          if [ -n "$comment_id" ]; then
            gh api -X PATCH "repos/$REPO/issues/comments/$comment_id" -F body=@comment.md >/dev/null
          else
            gh pr comment "$PR" --repo "$REPO" --body-file comment.md
          fi

          gh pr edit "$PR" --repo "$REPO" --add-label "incomplete template" || true
bytes
5,002
lines
137
Type
yml
Latest commit
26 October 2026