Adding Danger.js to GitHub Actions
Codify your PR conventions in a Dangerfile and let Danger.js enforce them on every pull request.
Danger.js runs a Dangerfile against each PR and posts warnings or failures as a comment. It is ideal for nudges that are hard to lint: missing changelog entries, empty PR bodies, or touching a lockfile without package.json. It uses the GitHub token to comment.
What you need
- Danger installed (npm i -D danger) and a dangerfile.js or dangerfile.ts.
- The default GITHUB_TOKEN, exposed to Danger as DANGER_GITHUB_API_TOKEN.
- A workflow triggered on pull_request.
The workflow
Run danger ci with the token in the environment.
.github/workflows/ci.yml
danger:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npx danger ci
env:
DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}A sample Dangerfile
Warn when the PR has no description or skips the changelog.
dangerfile.js
import { danger, warn } from "danger";
if (danger.github.pr.body.length < 10) warn("Please add a PR description.");
if (!danger.git.modified_files.includes("CHANGELOG.md")) warn("No changelog entry.");Common gotchas
- Forked PRs cannot post comments with the default token - Danger degrades to log-only.
- danger ci needs the PR context, so it only works on pull_request events.
- A throwing Dangerfile fails the job, not just the Danger rule - wrap risky logic.
Key takeaways
- Danger.js enforces PR conventions from a Dangerfile and comments results.
- Pass GITHUB_TOKEN as DANGER_GITHUB_API_TOKEN.
- Forked PRs limit Danger to log-only, with no comments.
Related guides
Adding ESLint as a CI Gate in GitHub ActionsMake ESLint block merges in GitHub Actions: run lint on every PR, fail on errors, and optionally annotate the…
Adding a Prettier Check to GitHub ActionsEnforce formatting in CI with prettier --check in GitHub Actions so unformatted code fails the build instead…
Adding Super-Linter to GitHub ActionsRun GitHub Super-Linter to lint many languages in one job, scoped to changed files, with the right permission…