|
1 | | -name: "Check Signed Commits" |
| 1 | +name: Check signed commits in PR |
| 2 | +on: pull_request_target |
2 | 3 |
|
3 | | -on: |
4 | | - pull_request: |
5 | | - types: |
6 | | - - opened |
7 | | - - synchronize |
8 | | - - reopened |
9 | | - branches: |
10 | | - - main |
| 4 | +concurrency: |
| 5 | + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} |
| 6 | + cancel-in-progress: true |
11 | 7 |
|
12 | 8 | jobs: |
13 | 9 | check-signed-commits: |
| 10 | + name: Check signed commits in PR |
14 | 11 | runs-on: ubuntu-latest |
| 12 | + timeout-minutes: 10 |
15 | 13 | permissions: |
16 | 14 | contents: read |
17 | 15 | pull-requests: write |
18 | | - issues: write |
19 | 16 | steps: |
20 | | - - name: Checkout repository |
21 | | - uses: actions/checkout@v5.0.0 |
| 17 | + - name: Checkout code |
| 18 | + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 |
22 | 19 | with: |
23 | | - fetch-depth: 0 |
24 | 20 | ref: ${{ github.event.pull_request.head.sha }} |
| 21 | + fetch-depth: 0 |
25 | 22 |
|
26 | | - - name: Configure Git for SSH signature verification |
27 | | - run: | |
28 | | - # Create a temporary allowed signers file (not used for actual verification) |
29 | | - # This allows git to recognize SSH signatures exist without requiring key validation |
30 | | - touch /tmp/allowed_signers |
31 | | - git config --global gpg.ssh.allowedSignersFile /tmp/allowed_signers |
32 | | - # Configure git to recognize SSH signing format |
33 | | - git config --global gpg.format ssh |
34 | | -
|
35 | | - - name: Check for verified commits |
36 | | - id: check-commits |
| 23 | + - name: Check for bot commits |
| 24 | + id: check-bots |
37 | 25 | run: | |
38 | 26 | # Get all commits in the PR |
39 | 27 | git fetch origin ${{ github.event.pull_request.base.ref }} |
40 | | - COMMITS=$(git rev-list origin/${{ github.event.pull_request.base.ref }}..${{ github.event.pull_request.head.sha }}) |
41 | | -
|
42 | | - UNSIGNED_COMMITS="" |
43 | | - UNSIGNED_COUNT=0 |
44 | | - TOTAL_COUNT=0 |
45 | | -
|
46 | | - for commit in $COMMITS; do |
47 | | - TOTAL_COUNT=$((TOTAL_COUNT + 1)) |
48 | | - # Check if commit is signed (GPG or SSH signature) |
49 | | - # %G? returns signature status |
50 | | - # %GF returns the signing key fingerprint (empty if not signed) |
51 | | - SIGNATURE=$(git log -1 --format='%G?' $commit) |
52 | | - FINGERPRINT=$(git log -1 --format='%GF' $commit) |
53 | | -
|
54 | | - # %G? returns: |
55 | | - # G = good GPG signature |
56 | | - # U = unverified signature (has signature but can't verify - common for SSH) |
57 | | - # B = bad signature |
58 | | - # N = no signature |
59 | | - # E = signature expired |
60 | | - # Y = good signature (expired key) |
61 | | -
|
62 | | - # A commit is considered SIGNED if it has any signature present |
63 | | - # We check for a fingerprint to confirm a signature exists |
64 | | - # For SSH signatures, %G? will be "U" but %GF will have the fingerprint |
65 | | -
|
66 | | - if [[ -z "$FINGERPRINT" ]]; then |
67 | | - # No fingerprint means no signature at all |
68 | | - UNSIGNED_COMMITS="${UNSIGNED_COMMITS}${commit}\n" |
69 | | - UNSIGNED_COUNT=$((UNSIGNED_COUNT + 1)) |
70 | | - fi |
71 | | - done |
72 | | -
|
73 | | - echo "total_commits=${TOTAL_COUNT}" >> $GITHUB_OUTPUT |
74 | | - echo "unsigned_commits=${UNSIGNED_COUNT}" >> $GITHUB_OUTPUT |
75 | | -
|
76 | | - if [ $UNSIGNED_COUNT -gt 0 ]; then |
77 | | - echo "has_unsigned=true" >> $GITHUB_OUTPUT |
78 | | - else |
79 | | - echo "has_unsigned=false" >> $GITHUB_OUTPUT |
80 | | - fi |
| 28 | + COMMITS=$(git log origin/${{ github.event.pull_request.base.ref }}..HEAD --format="%an") |
81 | 29 |
|
82 | | - - name: Check if comment already exists |
83 | | - if: steps.check-commits.outputs.has_unsigned == 'true' |
84 | | - id: check-comment |
85 | | - env: |
86 | | - GH_TOKEN: ${{ github.token }} |
87 | | - run: | |
88 | | - # Check if our bot has already commented on this PR |
89 | | - COMMENT_EXISTS=$(gh api \ |
90 | | - -H "Accept: application/vnd.github+json" \ |
91 | | - -H "X-GitHub-Api-Version: 2022-11-28" \ |
92 | | - "/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" \ |
93 | | - | jq -r '.[] | select(.user.login == "github-actions[bot]" and (.body | contains("⚠️ Unsigned Commits Detected"))) | .id' | head -1) |
94 | | -
|
95 | | - if [ -n "$COMMENT_EXISTS" ]; then |
96 | | - echo "comment_exists=true" >> $GITHUB_OUTPUT |
97 | | - echo "comment_id=${COMMENT_EXISTS}" >> $GITHUB_OUTPUT |
| 30 | + echo "Commits in PR:" |
| 31 | + echo "$COMMITS" |
| 32 | +
|
| 33 | + # Check if any commits are NOT from bots |
| 34 | + # grep -v returns 0 (true) if it finds lines NOT matching the pattern |
| 35 | + # grep -v returns 1 (false) if all lines match the pattern (all are bots) |
| 36 | + if echo "$COMMITS" | grep -qv '\[bot\]'; then |
| 37 | + echo "Found human commits" |
| 38 | + echo "has_human_commits=true" >> $GITHUB_OUTPUT |
98 | 39 | else |
99 | | - echo "comment_exists=false" >> $GITHUB_OUTPUT |
| 40 | + echo "All commits are from bots" |
| 41 | + echo "has_human_commits=false" >> $GITHUB_OUTPUT |
100 | 42 | fi |
101 | 43 |
|
102 | | - - name: Post warning comment |
103 | | - if: steps.check-commits.outputs.has_unsigned == 'true' && steps.check-comment.outputs.comment_exists == 'false' |
104 | | - env: |
105 | | - GH_TOKEN: ${{ github.token }} |
106 | | - run: | |
107 | | - cat << 'EOF' | gh pr comment ${{ github.event.pull_request.number }} --repo ${{ github.repository }} -F - |
108 | | - ## ⚠️ Unsigned Commits Detected |
109 | | -
|
110 | | - This pull request contains unsigned commits. |
| 44 | + - name: Check signed commits in PR |
| 45 | + if: steps.check-bots.outputs.has_human_commits == 'true' |
| 46 | + continue-on-error: true |
| 47 | + uses: 1Password/check-signed-commits-action@ed2885f3ed2577a4f5d3c3fe895432a557d23d52 # v1.2.0 |
| 48 | + with: |
| 49 | + comment: | |
| 50 | + ## ⚠️ Unsigned Commits Detected |
111 | 51 |
|
112 | | - ### What does this mean? |
| 52 | + This pull request contains unsigned commits. |
113 | 53 |
|
114 | | - Signed commits help ensure the authenticity and traceability of contributions. They allow us to verify that commits actually came from the stated author, even if GitHub accounts are deleted or modified in the future. |
| 54 | + ### What does this mean? |
115 | 55 |
|
116 | | - ### Current Policy (Grace Period) |
| 56 | + Signed commits help ensure the authenticity and traceability of contributions. They allow us to verify that commits actually came from the stated author, even if GitHub accounts are deleted or modified in the future. |
117 | 57 |
|
118 | | - **This is currently a warning only.** We are in a transition period to give all contributors time to set up commit signing. |
| 58 | + ### Current Policy (Grace Period) |
119 | 59 |
|
120 | | - After this grace period, **all commits will be required to be signed** before PRs can be merged. |
| 60 | + **This is currently a warning only.** We are in a transition period to give all contributors time to set up commit signing. |
121 | 61 |
|
122 | | - ### How to sign your commits |
| 62 | + After this grace period, **all commits will be required to be signed** before PRs can be merged. |
123 | 63 |
|
124 | | - Please see our [Contributing Guide](../blob/main/CONTRIBUTING.md#setting-up-your-development-environment) for detailed instructions on setting up commit signing. |
| 64 | + ### How to sign your commits |
125 | 65 |
|
126 | | - ### Resources |
| 66 | + Please see our [Contributing Guide](../blob/main/CONTRIBUTING.md#setting-up-your-development-environment) for detailed instructions on setting up commit signing. |
127 | 67 |
|
128 | | - - [Contributing Guide: Development Setup](../blob/main/CONTRIBUTING.md#setting-up-your-development-environment) |
129 | | - - [GitHub Docs: About Commit Signature Verification](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification) |
| 68 | + ### Resources |
130 | 69 |
|
131 | | - --- |
| 70 | + - [Contributing Guide: Development Setup](../blob/main/CONTRIBUTING.md#setting-up-your-development-environment) |
| 71 | + - [GitHub Docs: About Commit Signature Verification](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification) |
132 | 72 |
|
133 | | - _This check will become mandatory in the future. Please start signing your commits now to avoid issues later._ |
134 | | - EOF |
| 73 | + --- |
135 | 74 |
|
136 | | - - name: Success message |
137 | | - if: steps.check-commits.outputs.has_unsigned == 'false' |
138 | | - run: | |
139 | | - echo "✅ All ${{ steps.check-commits.outputs.total_commits }} commits in this PR are signed!" |
| 75 | + _This check will become mandatory in the future. Please start signing your commits now to avoid issues later._ |
0 commit comments