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
9 changes: 9 additions & 0 deletions .github/workflows/build_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,15 @@ jobs:
run: |
scripts/opentitan/ot-tidy.sh --ci -p build-clang

lint-commits:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Don't shallow clone, we need to see all commits.
- name: Lint commits
run: ./scripts/opentitan/lint-commits.sh "origin/${{ github.base_ref }}"

test-clang:
runs-on: ubuntu-24.04
needs: build-clang
Expand Down
78 changes: 78 additions & 0 deletions scripts/opentitan/lint-commits.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env sh
# Copyright lowRISC.

# This script checks that commit messages are in the correct format:
#
# 1. The title must be of the form `[ot] path/to/change: description`.
# 2. The message must end with `Signed-off-by: Name <email@address>`.
#
# Usage:
#
# lint-commits.sh <first commit>

set -e

# Check the commit title has the correct prefixes.
lint_title() {
commit="$1"

title="$(git show "$commit" -s --format="format:%s")"
short_hash="$(git show "$commit" -s --format="format:%h")"

example() {
echo "Got:" >&2
echo " ${title}" >&2
echo
echo "Example:" >&2
echo " [ot] hw/opentitan: ot_hmac: fix i2c register address" >&2
}

if ! echo "$title" | grep -P -q '^\[ot\]'; then
echo "::error::${short_hash}: commit titles must have the prefix '[ot]'" >&2
example
exit 1
fi

if ! echo "$title" | grep -P -q '^\[ot\]\s+[^:]+:'; then
echo "::error::${short_hash}: commit titles must contain the path of the change" >&2
example
exit 1
fi

if ! echo "$title" | grep -P -q '^\[ot\]\s+[^:]+:\s+[^:]+:'; then
echo "::error::${short_hash}: commit titles must state the changed component" >&2
example
exit 1
fi
}

# Check the commit is signed off.
lint_signed_off_by() {
commit="$1"

signed_off_by="$(git show "$commit" -s --format="format:%(trailers:key=Signed-off-by)")"
short_hash="$(git show "$commit" -s --format="format:%h")"

if [ -z "$signed_off_by" ]; then
echo "::error::${short_hash}: is missing a 'Signed-off-by' line" >&2
echo "Hint:" >&2
echo "Use \`git commit -s\` to add sign-offs" >&2
exit 1
fi
}

first_commit="$1"
if [ -z "$first_commit" ]; then
echo "Usage: ${0} <first commit>" >&2
exit 1
fi

exit_code=0

# Lint each commit from the merge target to now.
for commit in $(git log "${first_commit}..HEAD" --format="format:%H" --no-merges); do
lint_title "$commit" || exit_code=1
lint_signed_off_by "$commit" || exit_code=1
done

exit $exit_code
Loading