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
49 changes: 49 additions & 0 deletions .github/workflows/empty-diff.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: empty-diff (reusable)

# Fail a pull request when its diff against the base branch is empty.
# Eight no-op PRs landed on Glyndor/homebrew-tap and Glyndor/scoop-bucket
# before this gate existed: the work was already in main via squash-merge,
# the branch was recreated as `-v2`, and the second merge landed as a commit
# with zero files changed. CI is happy with that — a commit with no diff is
# valid git and a green GitHub Actions run, and only `git show --stat` flags
# it.
#
# Add this as an advisory caller in every repository that opens PRs against
# `main`, then promote it to a required status check once the emitted check
# name has stayed stable across a few weeks of green. Promoting it before
# the name has settled is how a phantom required check is created (see the
# `dco` and `line-limit` reusable docs for the by-name matching detail).

on:
workflow_call:

permissions:
contents: read

concurrency:
group: empty-diff-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
empty-diff:
name: empty diff
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false

- name: Fail when the pull request changes nothing
env:
BASE: ${{ github.event.pull_request.base.ref }}
run: |
set -euo pipefail
if [ -z "${BASE:-}" ]; then
echo "::error::could not determine the pull request base ref — this reusable must be called from a pull_request-triggered workflow"
exit 1
fi
if git diff --quiet "origin/${BASE}...HEAD"; then
echo "::error::this pull request has an empty diff against ${BASE}"
exit 1
fi
1 change: 1 addition & 0 deletions docs/reusables/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ which blocks every pull request until someone works out why.
|---|---|---|---|
| [`bun-ci`](bun-ci.md) | 1 | 0 | 3 |
| [`dco`](dco.md) | 1 | 0 | 0 |
| [`empty-diff`](empty-diff.md) | 1 | 0 | 0 |
| [`go-audit`](go-audit.md) | 2 | 0 | 4 |
| [`go-ci`](go-ci.md) | 1 | 0 | 3 |
| [`go-fuzz`](go-fuzz.md) | 1 | 0 | 3 |
Expand Down
36 changes: 36 additions & 0 deletions docs/reusables/empty-diff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# empty-diff

Fail a pull request when its diff against the base branch is empty. Eight no-op PRs landed on Glyndor/homebrew-tap and Glyndor/scoop-bucket before this gate existed: the work was already in main via squash-merge, the branch was recreated as `-v2`, and the second merge landed as a commit with zero files changed. CI is happy with that — a commit with no diff is valid git and a green GitHub Actions run, and only `git show --stat` flags it. Add this as an advisory caller in every repository that opens PRs against `main`, then promote it to a required status check once the emitted check name has stayed stable across a few weeks of green. Promoting it before the name has settled is how a phantom required check is created (see the `dco` and `line-limit` reusable docs for the by-name matching detail).

## Calling it

```yaml
# .github/workflows/ci.yml in the consuming repository
jobs:
example:
uses: Glyndor/.github/.github/workflows/empty-diff.yml@<sha> # vX.Y.Z
```

Pin to a release commit SHA with the version in a comment. Never track a
branch: the SHA pin is what stops a change here reaching a repository
before that repository's own CI has passed on it.

## Status checks it emits

The name a consumer sees is `<caller job id> / <job name>`, where `example` is
the caller's job id from the snippet above — a repository that names its job
`rust` sees `rust / …` instead. **These are the strings a ruleset matches**, and
a required check whose name nothing emits blocks every pull request.

| Check | Emitted when |
|---|---|
| `example / empty diff` | always |

## Inputs

None.

---

Generated from `.github/workflows/empty-diff.yml` by `scripts/render-reusable-docs.py`.
Edit the workflow, not this page.
Loading