Compare commits
39 Commits
Author | SHA1 | Date | |
---|---|---|---|
1ff93da091 | |||
0524c01297 | |||
548adff9dc | |||
28674474a4 | |||
4fb90330a4 | |||
e4c811acf5 | |||
99ccb3479b | |||
13616a4432 | |||
b5b91bc2b0 | |||
5666cd8fe9 | |||
ad897490d5 | |||
0735106af9 | |||
9aeedaa8c2 | |||
52d31873b6 | |||
09b9ac155b | |||
6ec5e3e26b | |||
8b46437b6d | |||
e361fd1788 | |||
052fc72b41 | |||
ed00d4629c | |||
34371f09e5 | |||
c27ea51ae0 | |||
5e9d0ee9ea | |||
b5f41d9b08 | |||
2455e15969 | |||
05bc46786e | |||
adc6552966 | |||
171fc6cce4 | |||
3fb765f674 | |||
d95c81ee98 | |||
8d5ed6557f | |||
7b1819c092 | |||
be0a8c9666 | |||
a0a6157bf1 | |||
9c5ec2e07d | |||
45c510e1f6 | |||
249b80db6b | |||
6c2b44c6ac | |||
76c58cf6a9 |
@ -9,8 +9,7 @@
|
||||
"plugin:import/errors",
|
||||
"plugin:import/warnings",
|
||||
"plugin:import/typescript",
|
||||
"plugin:prettier/recommended",
|
||||
"prettier/@typescript-eslint"
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"rules": {
|
||||
|
@ -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. | |
|
||||
@ -66,7 +67,13 @@ All inputs are **optional**. If not set, sensible defaults will be used.
|
||||
|
||||
### Action outputs
|
||||
|
||||
The pull request number and URL are available as step outputs.
|
||||
The following outputs can be used by subsequent workflow steps.
|
||||
|
||||
- `pull-request-number` - The pull request number.
|
||||
- `pull-request-url` - The URL of the pull request.
|
||||
- `pull-request-operation` - The pull request operation performed by the action, `created`, `updated` or `closed`.
|
||||
|
||||
Step outputs can be accessed as in the following example.
|
||||
Note that in order to read the step outputs the action step must have an id.
|
||||
|
||||
```yml
|
||||
|
@ -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')
|
||||
|
@ -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'
|
||||
|
980
dist/index.js
vendored
980
dist/index.js
vendored
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
@ -129,6 +130,8 @@ jobs:
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
```
|
||||
|
||||
For further reading regarding the security of pull requests, see this GitHub blog post titled [Keeping your GitHub Actions and workflows secure: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/)
|
||||
|
||||
### Triggering further workflow runs
|
||||
|
||||
Pull requests created by the action using the default `GITHUB_TOKEN` cannot trigger other workflows. If you have `on: pull_request` or `on: push` workflows acting as checks on pull requests, they will not run.
|
||||
@ -272,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.
|
||||
|
@ -21,6 +21,7 @@
|
||||
- [Filtering push events](#filtering-push-events)
|
||||
- [Dynamic configuration using variables](#dynamic-configuration-using-variables)
|
||||
- [Setting the pull request body from a file](#setting-the-pull-request-body-from-a-file)
|
||||
- [Using a markdown template](#using-a-markdown-template)
|
||||
- [Debugging GitHub Actions](#debugging-github-actions)
|
||||
|
||||
|
||||
@ -560,6 +561,31 @@ The content must be [escaped to preserve newlines](https://github.community/t/se
|
||||
body: ${{ steps.get-pr-body.outputs.body }}
|
||||
```
|
||||
|
||||
### Using a markdown template
|
||||
|
||||
In this example, a markdown template file is added to the repository at `.github/pull-request-template.md` with the following content.
|
||||
```
|
||||
This is a test pull request template
|
||||
Render template variables such as {{ .foo }} and {{ .bar }}.
|
||||
```
|
||||
|
||||
The template is rendered using the [render-template](https://github.com/chuhlomin/render-template) action and the result is used to create the pull request.
|
||||
```yml
|
||||
- name: Render template
|
||||
id: template
|
||||
uses: chuhlomin/render-template@v1.2
|
||||
with:
|
||||
template: .github/pull-request-template.md
|
||||
vars: |
|
||||
foo: this
|
||||
bar: that
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v3
|
||||
with:
|
||||
body: ${{ steps.template.outputs.result }}
|
||||
```
|
||||
|
||||
### Debugging GitHub Actions
|
||||
|
||||
#### Runner Diagnostic Logging
|
||||
|
11407
package-lock.json
generated
11407
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
34
package.json
34
package.json
@ -31,24 +31,24 @@
|
||||
"dependencies": {
|
||||
"@actions/core": "1.2.6",
|
||||
"@actions/exec": "1.0.4",
|
||||
"@octokit/core": "3.1.2",
|
||||
"@octokit/plugin-paginate-rest": "2.4.0",
|
||||
"@octokit/plugin-rest-endpoint-methods": "4.2.0",
|
||||
"uuid": "8.3.0"
|
||||
"@octokit/core": "3.3.2",
|
||||
"@octokit/plugin-paginate-rest": "2.13.3",
|
||||
"@octokit/plugin-rest-endpoint-methods": "5.0.0",
|
||||
"uuid": "8.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "26.0.14",
|
||||
"@types/node": "14.10.3",
|
||||
"@typescript-eslint/parser": "4.1.1",
|
||||
"@vercel/ncc": "0.24.1",
|
||||
"eslint": "7.9.0",
|
||||
"eslint-plugin-github": "4.1.1",
|
||||
"eslint-plugin-jest": "24.0.1",
|
||||
"jest": "26.4.2",
|
||||
"jest-circus": "26.4.2",
|
||||
"js-yaml": "3.14.0",
|
||||
"prettier": "2.1.2",
|
||||
"ts-jest": "26.3.0",
|
||||
"typescript": "4.0.2"
|
||||
"@types/jest": "26.0.22",
|
||||
"@types/node": "14.14.37",
|
||||
"@typescript-eslint/parser": "4.20.0",
|
||||
"@vercel/ncc": "0.27.0",
|
||||
"eslint": "7.23.0",
|
||||
"eslint-plugin-github": "4.1.2",
|
||||
"eslint-plugin-jest": "24.3.2",
|
||||
"jest": "26.6.3",
|
||||
"jest-circus": "26.6.3",
|
||||
"js-yaml": "4.0.0",
|
||||
"prettier": "2.2.1",
|
||||
"ts-jest": "26.5.4",
|
||||
"typescript": "4.2.3"
|
||||
}
|
||||
}
|
||||
|
@ -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,14 +125,27 @@ export async function createOrUpdateBranch(
|
||||
if (signoff) {
|
||||
params.push('--signoff')
|
||||
}
|
||||
if (gpgSign) {
|
||||
params.push('--gpg-sign')
|
||||
}
|
||||
await git.commit(params)
|
||||
}
|
||||
|
||||
// Perform fetch and reset the working base
|
||||
// Commits made during the workflow will be removed
|
||||
if (workingBaseType == WorkingBaseType.Branch) {
|
||||
core.info(`Resetting working base branch '${workingBase}' to its remote`)
|
||||
await git.fetch([`${workingBase}:${workingBase}`], baseRemote, ['--force'])
|
||||
core.info(`Resetting working base branch '${workingBase}'`)
|
||||
if (branchRemoteName == 'fork') {
|
||||
// If pushing to a fork we must fetch with 'unshallow' to avoid the following error on git push
|
||||
// ! [remote rejected] HEAD -> tests/push-branch-to-fork (shallow update not allowed)
|
||||
await git.fetch([`${workingBase}:${workingBase}`], baseRemote, [
|
||||
'--force'
|
||||
])
|
||||
} else {
|
||||
// If the remote is 'origin' we can git reset
|
||||
await git.checkout(workingBase)
|
||||
await git.exec(['reset', '--hard', `${baseRemote}/${workingBase}`])
|
||||
}
|
||||
}
|
||||
|
||||
// If the working base is not the base, rebase the temp branch commits
|
||||
@ -168,7 +182,7 @@ export async function createOrUpdateBranch(
|
||||
// The pull request branch does not exist
|
||||
core.info(`Pull request branch '${branch}' does not exist yet.`)
|
||||
// Create the pull request branch
|
||||
await git.checkout(branch, 'HEAD')
|
||||
await git.checkout(branch, tempBranch)
|
||||
// Check if the pull request branch is ahead of the base
|
||||
result.hasDiffWithBase = await isAhead(git, base, branch)
|
||||
if (result.hasDiffWithBase) {
|
||||
|
@ -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()
|
||||
|
||||
@ -195,11 +197,24 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
|
||||
|
||||
if (result.hasDiffWithBase) {
|
||||
// Create or update the pull request
|
||||
await githubHelper.createOrUpdatePullRequest(
|
||||
const pull = await githubHelper.createOrUpdatePullRequest(
|
||||
inputs,
|
||||
baseRemote.repository,
|
||||
branchRepository
|
||||
)
|
||||
|
||||
// Set outputs
|
||||
core.startGroup('Setting outputs')
|
||||
core.setOutput('pull-request-number', pull.number)
|
||||
core.setOutput('pull-request-url', pull.html_url)
|
||||
if (pull.created) {
|
||||
core.setOutput('pull-request-operation', 'created')
|
||||
} else if (result.action == 'updated') {
|
||||
core.setOutput('pull-request-operation', 'updated')
|
||||
}
|
||||
// Deprecated
|
||||
core.exportVariable('PULL_REQUEST_NUMBER', pull.number)
|
||||
core.endGroup()
|
||||
} else {
|
||||
// There is no longer a diff with the base
|
||||
// Check we are in a state where a branch exists
|
||||
@ -215,6 +230,10 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
|
||||
branchRemoteName,
|
||||
`refs/heads/${inputs.branch}`
|
||||
])
|
||||
// Set outputs
|
||||
core.startGroup('Setting outputs')
|
||||
core.setOutput('pull-request-operation', 'closed')
|
||||
core.endGroup()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ interface Repository {
|
||||
interface Pull {
|
||||
number: number
|
||||
html_url: string
|
||||
created: boolean
|
||||
}
|
||||
|
||||
export class GitHubHelper {
|
||||
@ -23,6 +24,7 @@ export class GitHubHelper {
|
||||
if (token) {
|
||||
options.auth = `${token}`
|
||||
}
|
||||
options.baseUrl = process.env['GITHUB_API_URL'] || 'https://api.github.com'
|
||||
this.octokit = new Octokit(options)
|
||||
}
|
||||
|
||||
@ -41,7 +43,7 @@ export class GitHubHelper {
|
||||
): Promise<Pull> {
|
||||
// Try to create the pull request
|
||||
try {
|
||||
const {data: pull} = await this.octokit.pulls.create({
|
||||
const {data: pull} = await this.octokit.rest.pulls.create({
|
||||
...this.parseRepository(baseRepository),
|
||||
title: inputs.title,
|
||||
head: headBranch,
|
||||
@ -54,7 +56,8 @@ export class GitHubHelper {
|
||||
)
|
||||
return {
|
||||
number: pull.number,
|
||||
html_url: pull.html_url
|
||||
html_url: pull.html_url,
|
||||
created: true
|
||||
}
|
||||
} catch (e) {
|
||||
if (
|
||||
@ -68,13 +71,13 @@ export class GitHubHelper {
|
||||
}
|
||||
|
||||
// Update the pull request that exists for this branch and base
|
||||
const {data: pulls} = await this.octokit.pulls.list({
|
||||
const {data: pulls} = await this.octokit.rest.pulls.list({
|
||||
...this.parseRepository(baseRepository),
|
||||
state: 'open',
|
||||
head: headBranch,
|
||||
base: inputs.base
|
||||
})
|
||||
const {data: pull} = await this.octokit.pulls.update({
|
||||
const {data: pull} = await this.octokit.rest.pulls.update({
|
||||
...this.parseRepository(baseRepository),
|
||||
pull_number: pulls[0].number,
|
||||
title: inputs.title,
|
||||
@ -86,12 +89,13 @@ export class GitHubHelper {
|
||||
)
|
||||
return {
|
||||
number: pull.number,
|
||||
html_url: pull.html_url
|
||||
html_url: pull.html_url,
|
||||
created: false
|
||||
}
|
||||
}
|
||||
|
||||
async getRepositoryParent(headRepository: string): Promise<string> {
|
||||
const {data: headRepo} = await this.octokit.repos.get({
|
||||
const {data: headRepo} = await this.octokit.rest.repos.get({
|
||||
...this.parseRepository(headRepository)
|
||||
})
|
||||
if (!headRepo.parent) {
|
||||
@ -106,40 +110,38 @@ export class GitHubHelper {
|
||||
inputs: Inputs,
|
||||
baseRepository: string,
|
||||
headRepository: string
|
||||
): Promise<void> {
|
||||
): Promise<Pull> {
|
||||
const [headOwner] = headRepository.split('/')
|
||||
const headBranch = `${headOwner}:${inputs.branch}`
|
||||
|
||||
// Create or update the pull request
|
||||
const pull = await this.createOrUpdate(inputs, baseRepository, headBranch)
|
||||
|
||||
// Set outputs
|
||||
core.startGroup('Setting outputs')
|
||||
core.setOutput('pull-request-number', pull.number)
|
||||
core.setOutput('pull-request-url', pull.html_url)
|
||||
// Deprecated
|
||||
core.exportVariable('PULL_REQUEST_NUMBER', pull.number)
|
||||
core.endGroup()
|
||||
|
||||
// Set milestone, labels and assignees
|
||||
const updateIssueParams = {}
|
||||
// Apply milestone
|
||||
if (inputs.milestone) {
|
||||
updateIssueParams['milestone'] = inputs.milestone
|
||||
core.info(`Applying milestone '${inputs.milestone}'`)
|
||||
}
|
||||
if (inputs.labels.length > 0) {
|
||||
updateIssueParams['labels'] = inputs.labels
|
||||
core.info(`Applying labels '${inputs.labels}'`)
|
||||
}
|
||||
if (inputs.assignees.length > 0) {
|
||||
updateIssueParams['assignees'] = inputs.assignees
|
||||
core.info(`Applying assignees '${inputs.assignees}'`)
|
||||
}
|
||||
if (Object.keys(updateIssueParams).length > 0) {
|
||||
await this.octokit.issues.update({
|
||||
await this.octokit.rest.issues.update({
|
||||
...this.parseRepository(baseRepository),
|
||||
issue_number: pull.number,
|
||||
...updateIssueParams
|
||||
milestone: inputs.milestone
|
||||
})
|
||||
}
|
||||
// Apply labels
|
||||
if (inputs.labels.length > 0) {
|
||||
core.info(`Applying labels '${inputs.labels}'`)
|
||||
await this.octokit.rest.issues.addLabels({
|
||||
...this.parseRepository(baseRepository),
|
||||
issue_number: pull.number,
|
||||
labels: inputs.labels
|
||||
})
|
||||
}
|
||||
// Apply assignees
|
||||
if (inputs.assignees.length > 0) {
|
||||
core.info(`Applying assignees '${inputs.assignees}'`)
|
||||
await this.octokit.rest.issues.addAssignees({
|
||||
...this.parseRepository(baseRepository),
|
||||
issue_number: pull.number,
|
||||
assignees: inputs.assignees
|
||||
})
|
||||
}
|
||||
|
||||
@ -155,7 +157,7 @@ export class GitHubHelper {
|
||||
}
|
||||
if (Object.keys(requestReviewersParams).length > 0) {
|
||||
try {
|
||||
await this.octokit.pulls.requestReviewers({
|
||||
await this.octokit.rest.pulls.requestReviewers({
|
||||
...this.parseRepository(baseRepository),
|
||||
pull_number: pull.number,
|
||||
...requestReviewersParams
|
||||
@ -168,5 +170,7 @@ export class GitHubHelper {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pull
|
||||
}
|
||||
}
|
||||
|
@ -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'),
|
||||
|
17
src/utils.ts
17
src/utils.ts
@ -39,8 +39,21 @@ interface RemoteDetail {
|
||||
export function getRemoteDetail(remoteUrl: string): RemoteDetail {
|
||||
// Parse the protocol and github repository from a URL
|
||||
// e.g. HTTPS, peter-evans/create-pull-request
|
||||
const httpsUrlPattern = /^https:\/\/.*@?github.com\/(.+\/.+)$/i
|
||||
const sshUrlPattern = /^git@github.com:(.+\/.+).git$/i
|
||||
const githubUrl = process.env['GITHUB_SERVER_URL'] || 'https://github.com'
|
||||
|
||||
const githubServerMatch = githubUrl.match(/^https?:\/\/(.+)$/i)
|
||||
if (!githubServerMatch) {
|
||||
throw new Error('Could not parse GitHub Server name')
|
||||
}
|
||||
|
||||
const httpsUrlPattern = new RegExp(
|
||||
'^https?://.*@?' + githubServerMatch[1] + '/(.+/.+)$',
|
||||
'i'
|
||||
)
|
||||
const sshUrlPattern = new RegExp(
|
||||
'^git@' + githubServerMatch[1] + ':(.+/.+).git$',
|
||||
'i'
|
||||
)
|
||||
|
||||
const httpsMatch = remoteUrl.match(httpsUrlPattern)
|
||||
if (httpsMatch) {
|
||||
|
Reference in New Issue
Block a user