|
| 1 | +name: PR Signature Comment |
| 2 | + |
| 3 | +on: |
| 4 | + pull_request_target: |
| 5 | + types: [opened, reopened, synchronize] |
| 6 | + |
| 7 | +jobs: |
| 8 | + check-and-comment: |
| 9 | + runs-on: ubuntu-latest |
| 10 | + permissions: |
| 11 | + pull-requests: write |
| 12 | + |
| 13 | + steps: |
| 14 | + - name: Check for unsigned commits and comment |
| 15 | + uses: actions/github-script@v7 |
| 16 | + with: |
| 17 | + script: | |
| 18 | + // Get all commits in this PR |
| 19 | + const commits = await github.rest.pulls.listCommits({ |
| 20 | + owner: context.repo.owner, |
| 21 | + repo: context.repo.repo, |
| 22 | + pull_number: context.issue.number |
| 23 | + }); |
| 24 | +
|
| 25 | + // Check for unsigned commits |
| 26 | + const unsignedCommits = commits.data.filter(commit => |
| 27 | + !commit.commit.verification || !commit.commit.verification.verified |
| 28 | + ); |
| 29 | +
|
| 30 | + if (unsignedCommits.length === 0) { |
| 31 | + console.log('All commits are signed. No comment needed.'); |
| 32 | + return; |
| 33 | + } |
| 34 | +
|
| 35 | + console.log(`Found ${unsignedCommits.length} unsigned commit(s).`); |
| 36 | +
|
| 37 | + // Check if we already left a comment about signatures |
| 38 | + const comments = await github.rest.issues.listComments({ |
| 39 | + owner: context.repo.owner, |
| 40 | + repo: context.repo.repo, |
| 41 | + issue_number: context.issue.number |
| 42 | + }); |
| 43 | +
|
| 44 | + const signatureCommentMarker = '<!-- signature-reminder-comment -->'; |
| 45 | + const existingComment = comments.data.find(comment => |
| 46 | + comment.body.includes(signatureCommentMarker) |
| 47 | + ); |
| 48 | +
|
| 49 | + const unsignedList = unsignedCommits.map(c => |
| 50 | + `- \`${c.sha.substring(0, 7)}\` ${c.commit.message.split('\n')[0]}` |
| 51 | + ).join('\n'); |
| 52 | +
|
| 53 | + const commentBody = `${signatureCommentMarker} |
| 54 | + ⚠️ **Unsigned Commits Detected** |
| 55 | +
|
| 56 | + This pull request contains ${unsignedCommits.length} unsigned commit(s): |
| 57 | +
|
| 58 | + ${unsignedList} |
| 59 | +
|
| 60 | + All commits must be signed before this PR can be merged. Please sign your commits by following these steps: |
| 61 | +
|
| 62 | + ### Option 1: SSH Key Signing (Recommended) |
| 63 | +
|
| 64 | + 1. **Add your SSH key to GitHub** (if not already done): |
| 65 | + - Go to [GitHub SSH Keys Settings](https://github.com/settings/keys) |
| 66 | + - Click "New SSH Key" and select "Signing Key" as the key type |
| 67 | +
|
| 68 | + 2. **Configure Git to use SSH signing**: |
| 69 | + \`\`\`bash |
| 70 | + git config --global gpg.format ssh |
| 71 | + git config --global user.signingkey ~/.ssh/id_ed25519.pub # or your key path |
| 72 | + git config --global commit.gpgsign true |
| 73 | + \`\`\` |
| 74 | +
|
| 75 | + 3. **Re-sign your commits**: |
| 76 | + \`\`\`bash |
| 77 | + git rebase -i HEAD~${unsignedCommits.length} --exec "git commit --amend --no-edit -S" |
| 78 | + git push --force |
| 79 | + \`\`\` |
| 80 | +
|
| 81 | + ### Option 2: GPG Key Signing |
| 82 | +
|
| 83 | + 1. **Generate a GPG key**: [GitHub Docs](https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key) |
| 84 | +
|
| 85 | + 2. **Add the GPG key to GitHub**: [GitHub Docs](https://docs.github.com/en/authentication/managing-commit-signature-verification/adding-a-gpg-key-to-your-github-account) |
| 86 | +
|
| 87 | + 3. **Configure Git to sign commits**: |
| 88 | + \`\`\`bash |
| 89 | + git config --global user.signingkey YOUR_GPG_KEY_ID |
| 90 | + git config --global commit.gpgsign true |
| 91 | + \`\`\` |
| 92 | +
|
| 93 | + 4. **Re-sign your commits** (same as above): |
| 94 | + \`\`\`bash |
| 95 | + git rebase -i HEAD~${unsignedCommits.length} --exec "git commit --amend --no-edit -S" |
| 96 | + git push --force |
| 97 | + \`\`\` |
| 98 | +
|
| 99 | + For more details, see [GitHub's commit signature verification docs](https://docs.github.com/en/authentication/managing-commit-signature-verification). |
| 100 | +
|
| 101 | + --- |
| 102 | + *This comment will be updated when you push new commits.*`; |
| 103 | +
|
| 104 | + if (existingComment) { |
| 105 | + // Update existing comment |
| 106 | + await github.rest.issues.updateComment({ |
| 107 | + owner: context.repo.owner, |
| 108 | + repo: context.repo.repo, |
| 109 | + comment_id: existingComment.id, |
| 110 | + body: commentBody |
| 111 | + }); |
| 112 | + console.log('Updated existing signature reminder comment.'); |
| 113 | + } else { |
| 114 | + // Create new comment |
| 115 | + await github.rest.issues.createComment({ |
| 116 | + owner: context.repo.owner, |
| 117 | + repo: context.repo.repo, |
| 118 | + issue_number: context.issue.number, |
| 119 | + body: commentBody |
| 120 | + }); |
| 121 | + console.log('Created new signature reminder comment.'); |
| 122 | + } |
| 123 | +
|
0 commit comments