A GitHub Actions composite action that verifies the Developer Certificate of Origin (DCO) on all commits in a pull request and posts a structured remediation comment when sign-off is missing.
Built from production use in MisakaNet, where it gates every incoming PR from autonomous AI agents.
The DCO requires every commit to include a Signed-off-by: Name <email> line. Many open-source projects enforce it, but:
- GitHub's built-in DCO check only flags failures — it doesn't help contributors fix them
- Existing bots are either too noisy or require third-party services
- AI agents and automated PRs frequently miss sign-off, creating triage overhead
This action checks + guides in one step.
jobs:
dco-check:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: Ikalus1988/dco-audit@v1
with:
base-sha: ${{ github.event.pull_request.base.sha }}
head-sha: ${{ github.event.pull_request.head.sha }}
token: ${{ secrets.GITHUB_TOKEN }}
pr-number: ${{ github.event.pull_request.number }}| Name | Required | Default | Description |
|---|---|---|---|
base-sha |
✅ | — | Base branch SHA (github.event.pull_request.base.sha) |
head-sha |
✅ | — | Head branch SHA (github.event.pull_request.head.sha) |
token |
✅ | — | Token with pull-requests: write scope. Use secrets.GITHUB_TOKEN for same-repo PRs, or a PAT with public_repo for fork PRs |
repo |
❌ | ${{ github.repository }} |
Repository in owner/repo format |
pr-number |
❌ | "" |
PR number. When set, posts a remediation comment on DCO failure |
| Name | Description |
|---|---|
dco-passed |
"true" if all commits are signed off, "false" otherwise |
failed-commits-log |
Newline-separated list of `sha |
failed-count |
Number of commits without sign-off |
- uses: Ikalus1988/dco-audit@v1
with:
base-sha: ${{ github.event.pull_request.base.sha }}
head-sha: ${{ github.event.pull_request.head.sha }}
token: ${{ secrets.GITHUB_TOKEN }}- uses: Ikalus1988/dco-audit@v1
id: dco
with:
base-sha: ${{ github.event.pull_request.base.sha }}
head-sha: ${{ github.event.pull_request.head.sha }}
token: ${{ secrets.GITHUB_TOKEN }}
repo: ${{ github.repository }}
pr-number: ${{ github.event.pull_request.number }}
- name: Block on DCO violation
if: steps.dco.outputs.dco-passed == 'false'
run: |
echo "DCO check failed: ${{ steps.dco.outputs.failed-count }} commit(s) missing sign-off."
exit 1See examples/full-pipeline.yml for a production-grade workflow that combines DCO audit, quality scoring, PR size check, and auto-merge.
- Scan phase: iterates all non-merge commits in
base-sha..head-shaand checks each forSigned-off-by: Name <email>in the commit message - Comment phase (optional): if
pr-numberis provided and DCO fails, posts a comment with:- A table of offending commits
- The exact
git rebasecommand to fix all of them - No emotional language — pure state-machine output
This is a composite action. No build step needed.
# Validate action.yml
action-validator action.yml
# Test locally (requires gh CLI and a test repo)
./test/run-local.shMIT — see LICENSE.