Enforce single commit PRs #26
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # .github/workflows/pr-single-commit-up-to-date.yml | |
| name: Enforce single commit & up-to-date | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened, ready_for_review, converted_to_draft] | |
| pull_request_target: | |
| types: [opened, synchronize, reopened, ready_for_review, converted_to_draft] | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| jobs: | |
| check-ahead-behind: | |
| if: ${{ !github.event.pull_request.draft }} | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - name: Checkout PR HEAD (full history) | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| fetch-depth: 0 | |
| - name: Fetch base branch | |
| run: | | |
| git fetch origin ${{ github.event.pull_request.base.ref }} | |
| - name: Compute ahead/behind | |
| id: ab | |
| shell: bash | |
| run: | | |
| BASE_SHA=${{ github.event.pull_request.base.sha }} | |
| read BEHIND AHEAD < <(git rev-list --left-right --count ${BASE_SHA}...HEAD) | |
| echo "head=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT | |
| echo "base=${BASE_SHA}" >> $GITHUB_OUTPUT | |
| echo "behind=$BEHIND" >> $GITHUB_OUTPUT | |
| echo "ahead=$AHEAD" >> $GITHUB_OUTPUT | |
| echo "Behind: $BEHIND, Ahead: $AHEAD" | |
| - name: Enforce rule | |
| shell: bash | |
| run: | | |
| BASE=${{ steps.ab.outputs.base }} | |
| HEAD=${{ steps.ab.outputs.head}} | |
| BEHIND=${{ steps.ab.outputs.behind }} | |
| AHEAD=${{ steps.ab.outputs.ahead }} | |
| if [[ "$BEHIND" -ne 0 || "$AHEAD" -ne 1 ]]; then | |
| echo "PR must be exactly 1 commit ahead and 0 behind the base branch." | |
| echo "base=$BASE, HEAD=$HEAD" | |
| echo "Ahead=$AHEAD, Behind=$BEHIND" | |
| echo "Rebase and squash to fix." | |
| exit 1 | |
| fi | |
| echo "OK: PR is exactly 1 ahead and 0 behind." | |
| - name: Convert PR to draft on failure (base repo context) | |
| if: failure() | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const pr = context.payload.pull_request; | |
| if (!pr) { | |
| core.setFailed('No pull_request context available.'); | |
| } else if (pr.draft) { | |
| core.info('PR is already in draft.'); | |
| } else { | |
| await github.request('POST /repos/{owner}/{repo}/pulls/{pull_number}/convert-to-draft', { | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: pr.number, | |
| headers: { 'X-GitHub-Api-Version': '2022-11-28' } | |
| }); | |
| core.info(`Converted PR #${pr.number} to draft.`); | |
| } |