feat: add input to enable gpg commit signing

This commit is contained in:
Peter Evans 2021-05-09 10:14:55 +09:00
parent 548adff9dc
commit 0524c01297
9 changed files with 8015 additions and 7 deletions

View file

@ -50,6 +50,7 @@ All inputs are **optional**. If not set, sensible defaults will be used.
| `committer` | The committer name and email address in the format `Display Name <email@address.com>`. Defaults to the GitHub Actions bot user. | `GitHub <noreply@github.com>` |
| `author` | The author name and email address in the format `Display Name <email@address.com>`. Defaults to the user who triggered the workflow run. | `${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>` |
| `signoff` | Add [`Signed-off-by`](https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---signoff) line by the committer at the end of the commit log message. | `false` |
| `gpg-sign` | GPG-sign commits. See [GPG commit signature verification](docs/concepts-guidelines.md#gpg-commit-signature-verification) for details. | `false` |
| `branch` | The pull request branch name. | `create-pull-request/patch` |
| `delete-branch` | Delete the `branch` when closing pull requests, and when undeleted after merging. Recommend `true`. | `false` |
| `branch-suffix` | The branch suffix type when using the alternative branching strategy. Valid values are `random`, `timestamp` and `short-commit-hash`. See [Alternative strategy](#alternative-strategy---always-create-a-new-pull-request-branch) for details. | |

View file

@ -220,6 +220,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('none')
@ -236,6 +237,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -263,6 +265,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -283,6 +286,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -310,6 +314,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -332,6 +337,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -360,6 +366,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('not-updated')
@ -380,6 +387,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -416,6 +424,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -446,6 +455,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -473,6 +483,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -493,6 +504,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -532,6 +544,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -558,6 +571,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -600,6 +614,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -621,6 +636,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -651,6 +667,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -676,6 +693,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -710,6 +728,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -737,6 +756,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -779,6 +799,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -805,6 +826,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
FORK_REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -833,6 +855,7 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
FORK_REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -854,7 +877,8 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
true
true,
false
)
expect(result.action).toEqual('created')
expect(await getFileContent(TRACKED_FILE)).toEqual(changes.tracked)
@ -889,7 +913,8 @@ describe('create-or-update-branch tests', () => {
'',
BRANCH,
REMOTE_NAME,
true
true,
false
)
expect(_result.action).toEqual('updated')
expect(_result.hasDiffWithBase).toBeTruthy()
@ -920,6 +945,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('none')
@ -939,6 +965,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -969,6 +996,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -992,6 +1020,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -1022,6 +1051,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -1047,6 +1077,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -1078,6 +1109,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('not-updated')
@ -1101,6 +1133,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -1140,6 +1173,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -1173,6 +1207,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -1203,6 +1238,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -1228,6 +1264,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -1270,6 +1307,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -1299,6 +1337,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -1344,6 +1383,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -1368,6 +1408,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -1401,6 +1442,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -1429,6 +1471,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -1466,6 +1509,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -1496,6 +1540,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -1541,6 +1586,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -1570,6 +1616,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
FORK_REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -1601,6 +1648,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
FORK_REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -1629,6 +1677,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -1661,6 +1710,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')
@ -1686,6 +1736,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(result.action).toEqual('created')
@ -1726,6 +1777,7 @@ describe('create-or-update-branch tests', () => {
BASE,
BRANCH,
REMOTE_NAME,
false,
false
)
expect(_result.action).toEqual('updated')

View file

@ -24,6 +24,9 @@ inputs:
signoff:
description: 'Add `Signed-off-by` line by the committer at the end of the commit log message.'
default: false
gpg-sign:
description: 'GPG-sign commits.'
default: false
branch:
description: 'The pull request branch name.'
default: 'create-pull-request/patch'

8
dist/index.js vendored
View file

@ -99,7 +99,7 @@ function splitLines(multilineString) {
.map(s => s.trim())
.filter(x => x !== '');
}
function createOrUpdateBranch(git, commitMessage, base, branch, branchRemoteName, signoff) {
function createOrUpdateBranch(git, commitMessage, base, branch, branchRemoteName, signoff, gpgSign) {
return __awaiter(this, void 0, void 0, function* () {
// Get the working base.
// When a ref, it may or may not be the actual base.
@ -129,6 +129,9 @@ function createOrUpdateBranch(git, commitMessage, base, branch, branchRemoteName
if (signoff) {
params.push('--signoff');
}
if (gpgSign) {
params.push('--gpg-sign');
}
yield git.commit(params);
}
// Perform fetch and reset the working base
@ -375,7 +378,7 @@ function createPullRequest(inputs) {
core.endGroup();
// Create or update the pull request branch
core.startGroup('Create or update the pull request branch');
const result = yield create_or_update_branch_1.createOrUpdateBranch(git, inputs.commitMessage, inputs.base, inputs.branch, branchRemoteName, inputs.signoff);
const result = yield create_or_update_branch_1.createOrUpdateBranch(git, inputs.commitMessage, inputs.base, inputs.branch, branchRemoteName, inputs.signoff, inputs.gpgSign);
core.endGroup();
if (['created', 'updated'].includes(result.action)) {
// The branch was created or updated
@ -1070,6 +1073,7 @@ function run() {
committer: core.getInput('committer'),
author: core.getInput('author'),
signoff: core.getInput('signoff') === 'true',
gpgSign: core.getInput('gpg-sign') === 'true',
branch: core.getInput('branch'),
deleteBranch: core.getInput('delete-branch') === 'true',
branchSuffix: core.getInput('branch-suffix'),

View file

@ -16,6 +16,7 @@ This document covers terminology, how the action works, general usage guidelines
- [Push using SSH (deploy keys)](#push-using-ssh-deploy-keys)
- [Push pull request branches to a fork](#push-pull-request-branches-to-a-fork)
- [Authenticating with GitHub App generated tokens](#authenticating-with-github-app-generated-tokens)
- [GPG commit signature verification](#gpg-commit-signature-verification)
- [Running in a container or on self-hosted runners](#running-in-a-container-or-on-self-hosted-runners)
## Terminology
@ -274,6 +275,49 @@ GitHub App generated tokens are more secure than using a PAT because GitHub App
token: ${{ steps.generate-token.outputs.token }}
```
### GPG commit signature verification
The action can use GPG to sign commits with a GPG key that you generate yourself.
1. Follow GitHub's guide to [generate a new GPG key](https://docs.github.com/en/github/authenticating-to-github/generating-a-new-gpg-key).
2. [Add the public key](https://docs.github.com/en/github/authenticating-to-github/adding-a-new-gpg-key-to-your-github-account) to the user account associated with the [Personal Access Token (PAT)](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) that you will use with the action.
3. Copy the private key to your clipboard, replacing `email@example.com` with the email address of your GPG key.
```
# macOS
gpg --armor --export-secret-key email@example.com | pbcopy
```
4. Paste the private key into a repository secret where the workflow will run. e.g. `GPG_PRIVATE_KEY`
5. Create another repository secret for the key's passphrase, if applicable. e.g. `GPG_PASSPHRASE`
6. The following example workflow shows how to use [crazy-max/ghaction-import-gpg](https://github.com/crazy-max/ghaction-import-gpg) to import your GPG key and instruct the action to sign commits by setting the `gpg-sign` input to `true`.
Note that the `committer` email address *MUST* match the email address used to create your GPG key.
```yaml
steps:
- uses: actions/checkout@v2
- uses: crazy-max/ghaction-import-gpg@v3
with:
gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
git-user-signingkey: true
git-commit-gpgsign: true
# Make changes to pull request here
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
token: ${{ secrets.PAT }}
committer: example <email@example.com>
gpg-sign: true
```
### Running in a container or on self-hosted runners
This action can be run inside a container, or on [self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners), by installing the necessary dependencies.

7899
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -91,7 +91,8 @@ export async function createOrUpdateBranch(
base: string,
branch: string,
branchRemoteName: string,
signoff: boolean
signoff: boolean,
gpgSign: boolean
): Promise<CreateOrUpdateBranchResult> {
// Get the working base.
// When a ref, it may or may not be the actual base.
@ -124,6 +125,9 @@ export async function createOrUpdateBranch(
if (signoff) {
params.push('--signoff')
}
if (gpgSign) {
params.push('--gpg-sign')
}
await git.commit(params)
}

View file

@ -16,6 +16,7 @@ export interface Inputs {
committer: string
author: string
signoff: boolean
gpgSign: boolean
branch: string
deleteBranch: boolean
branchSuffix: string
@ -173,7 +174,8 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
inputs.base,
inputs.branch,
branchRemoteName,
inputs.signoff
inputs.signoff,
inputs.gpgSign
)
core.endGroup()

View file

@ -12,6 +12,7 @@ async function run(): Promise<void> {
committer: core.getInput('committer'),
author: core.getInput('author'),
signoff: core.getInput('signoff') === 'true',
gpgSign: core.getInput('gpg-sign') === 'true',
branch: core.getInput('branch'),
deleteBranch: core.getInput('delete-branch') === 'true',
branchSuffix: core.getInput('branch-suffix'),