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
52 changes: 52 additions & 0 deletions .github/workflows/dco-signoff.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Copyright 2026 Hewlett Packard Enterprise Development LP
---
name: dco-signoff

'on':
pull_request:

permissions:
contents: read

jobs:
dco-signoff-check:
name: DCO / Signed-off-by
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0

- name: Verify Signed-off-by trailers
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
set -euo pipefail

mapfile -t commits < <(git rev-list --reverse "${BASE_SHA}..${HEAD_SHA}")

if [[ ${#commits[@]} -eq 0 ]]; then
echo "[dco] no commits found in PR range"
exit 0
fi

missing=0
for commit in "${commits[@]}"; do
trailers="$(git log -1 --pretty=%B "${commit}" | git interpret-trailers --parse)"
if ! grep -qi '^signed-off-by:' <<< "${trailers}"; then
subject="$(git log -1 --pretty=%s "${commit}")"
echo "::error title=Missing Signed-off-by::${commit}: ${subject}"
missing=1
fi
done

if [[ ${missing} -ne 0 ]]; then
echo "[dco] one or more commits are missing Signed-off-by trailers" >&2
echo "[dco] amend commits with: git commit --amend --signoff" >&2
echo "[dco] for multiple commits: git rebase -i --signoff <base>" >&2
exit 1
fi

echo "[dco] all commits include Signed-off-by trailers"
3 changes: 3 additions & 0 deletions docs/git-commit-message-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ contributors.
Local group policy is stricter: require `Signed-off-by:` for all commits,
including employee-authored commits.

This repository enforces `Signed-off-by:` trailers on pull requests through the
`DCO / Signed-off-by` required status check.

## References

For broader background, see the Git Book section on commit guidelines:
Expand Down
21 changes: 15 additions & 6 deletions docs/maintenance.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,20 @@ merge protections used here.

### Overview

The `basic-source-checks` job from the `checks.yml` workflow is configured as a
required status check. This consolidates all code quality gates:
The following jobs are configured as required status checks:

- `Basic Source checks` from `checks.yml`
- `DCO / Signed-off-by` from `dco-signoff.yml`

`Basic Source checks` consolidates code quality gates:

- `code-checking-ref` guard — blocks accidental commits of local overrides
- Executable mode verification — ensures scripts have correct git index mode
- Dynamic linter selection and execution — runs applicable linters
(shellcheck, etc.)

This consolidation avoids coupling branch protection rules to per-linter checks.
All rules are enforced in a single, stable status check.
The separate DCO check enforces `Signed-off-by:` commit trailer policy.

### Setup (GitHub Web UI)

Expand All @@ -47,7 +51,9 @@ This section describes the underlying structure; exact interface paths may vary.
3. Under Branch targeting criteria, use `Default`.
4. Enable these branch rules:
- **Restrict deletions**
- **Require signed commits**
- **Require signed commits** (optional)
- Enable only when all contributors are set up for verified commit
signing (GPG/SSH/S/MIME).
- **Require a pull request before merging**
- **Required approvals**: 1
- **Dismiss stale pull request approvals when new commits are pushed**
Expand All @@ -56,7 +62,9 @@ This section describes the underlying structure; exact interface paths may vary.
- **Allowed merge methods**: disable merge commits; allow squash and
rebase merges
- **Require status checks to pass**
- **Status checks that are required**: `Basic Source checks`
- **Status checks that are required**:
- `Basic Source checks`
- `DCO / Signed-off-by`
- GitHub does not make this selectable until the workflow exists on the
default `main` branch.
- **Block force pushes**
Expand All @@ -66,8 +74,9 @@ This section describes the underlying structure; exact interface paths may vary.
Once configured, attempts to merge a PR will fail with:

- "`Basic Source checks` – required check"
- "`DCO / Signed-off-by` - required check"

if any of the check steps fail (guard, executable modes, or linters).
if any of the check steps fail.

### Testing the Configuration

Expand Down
2 changes: 2 additions & 0 deletions vscode-project-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ isort
LASTEXITCODE
longpaths
makefiles
mapfile
MSYSTEM
nicolasvuillamy
nonblank
pipefail
Pipenv
pyenv
pylint
Expand Down
Loading