Compare commits

...

32 Commits

Author SHA1 Message Date
ff0beed1b2 Merge pull request #627 from peter-evans/git-diff-perf
perf: set diff quiet and switch isdirty command order
2020-11-17 13:22:44 +09:00
ddeca94037 perf: set diff quiet and switch isdirty command order 2020-11-17 11:42:31 +09:00
0fd77ba8cc docs: add missing contents link 2020-10-26 09:23:01 +09:00
c7f493a800 docs: remove deprecated set-env example 2020-10-02 15:53:49 +09:00
91664dfb28 Merge pull request #604 from peter-evans/update-distribution
Update distribution
2020-10-02 15:18:04 +09:00
13ec5274b1 build: update distribution 2020-10-02 06:17:23 +00:00
bcf9790963 Merge pull request #599 from peter-evans/dependabot/npm_and_yarn/actions/core-1.2.6
Bump @actions/core from 1.2.5 to 1.2.6
2020-10-02 15:14:43 +09:00
88ea447de7 Bump @actions/core from 1.2.5 to 1.2.6
Bumps [@actions/core](https://github.com/actions/toolkit/tree/HEAD/packages/core) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/actions/toolkit/releases)
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/core/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/core)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-01 17:24:16 +00:00
da928d5fcc Merge pull request #587 from peter-evans/url-output
feat: output the pull request url
2020-09-17 11:18:34 +09:00
2465e435b9 feat: output the pull request url 2020-09-17 10:41:26 +09:00
37b2bd1eca Merge pull request #584 from peter-evans/update-distribution
Update distribution
2020-09-17 10:39:30 +09:00
eb13e17e17 build: update distribution 2020-09-17 01:38:44 +00:00
a1ecc20658 Merge pull request #565 from peter-evans/update-dependencies
Update dependencies
2020-09-17 10:36:25 +09:00
ffcad23634 chore: update dependencies 2020-09-17 01:15:53 +00:00
f4b52b768a Merge pull request #574 from peter-evans/update-distribution
Update distribution
2020-09-13 15:13:25 +09:00
af682c8fcb build: update distribution 2020-09-13 06:11:21 +00:00
7378b23cb0 Merge pull request #569 from peter-evans/dependabot/npm_and_yarn/node-fetch-2.6.1
Bump node-fetch from 2.6.0 to 2.6.1
2020-09-13 15:08:27 +09:00
370ae6d537 Bump node-fetch from 2.6.0 to 2.6.1
Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1.
- [Release notes](https://github.com/bitinn/node-fetch/releases)
- [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md)
- [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-12 21:49:56 +00:00
ae0797ee12 ci: update commit message type 2020-09-07 17:25:24 +09:00
e05457394a ci: update commit messages 2020-09-07 15:26:59 +09:00
44f76dd5b3 Merge pull request #558 from peter-evans/update-distribution
Update distribution
2020-09-07 09:30:37 +09:00
279e66ed27 Update distribution 2020-09-07 00:29:59 +00:00
ce9dd3641e Merge pull request #511 from peter-evans/update-dependencies
Update dependencies
2020-09-07 09:27:33 +09:00
1a00b34382 Update dependencies 2020-09-07 09:18:17 +09:00
e17bb55cb7 Merge pull request #547 from peter-evans/delete-branch
feat: add input for branch delete
2020-09-07 09:14:08 +09:00
1890e1ec35 Merge pull request #537 from peter-evans/squash-merge-fix
fix: reset branches to handle squash merge
2020-09-07 09:10:33 +09:00
a49ee3308e feat: add input for branch delete 2020-09-06 10:21:35 +09:00
16fa12ee5f fix: reset branches to handle squash merge 2020-09-06 08:55:33 +09:00
5ea31358e9 docs: updates related to checkout 2020-09-01 09:15:45 +09:00
105f0d3816 docs: update examples 2020-08-30 15:17:23 +09:00
8fb2374109 docs: update readme 2020-08-30 11:20:42 +09:00
a68328a1ee docs: update concepts-guidelines 2020-08-30 11:06:03 +09:00
16 changed files with 5091 additions and 4867 deletions

View File

@ -120,7 +120,7 @@ jobs:
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
commit-message: Update distribution
commit-message: 'build: update distribution'
title: Update distribution
body: |
- Updates the distribution for changes on `master`

View File

@ -34,10 +34,12 @@ jobs:
milestone: 1
draft: false
branch: example-patches
delete-branch: true
- name: Check output
run: |
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
- name: Add reaction
uses: peter-evans/create-or-update-comment@v1

View File

@ -18,7 +18,7 @@ jobs:
uses: peter-evans/create-pull-request@v3
with:
token: ${{ secrets.ACTIONS_BOT_TOKEN }}
commit-message: Update dependencies
commit-message: 'chore: update dependencies'
committer: GitHub <noreply@github.com>
author: actions-bot <actions-bot@users.noreply.github.com>
title: Update dependencies

View File

@ -26,6 +26,10 @@ Create Pull Request action will:
## Usage
```yml
- uses: actions/checkout@v2
# Make changes to pull request here
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
```
@ -47,6 +51,7 @@ All inputs are **optional**. If not set, sensible defaults will be used.
| `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` |
| `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. | |
| `base` | Sets the pull request base branch. | Defaults to the branch checked out in the workflow. |
| `push-to-fork` | A fork of the checked-out parent repository to which the pull request branch will be pushed. e.g. `owner/repo-fork`. The pull request will be created to merge the fork's branch into the parent's base. See [push pull request branches to a fork](docs/concepts-guidelines.md#push-pull-request-branches-to-a-fork) for details. | |
@ -61,8 +66,8 @@ All inputs are **optional**. If not set, sensible defaults will be used.
### Action outputs
The pull request number is output as a step output.
Note that in order to read the step output the action step must have an id.
The pull request number and URL are available as step outputs.
Note that in order to read the step outputs the action step must have an id.
```yml
- name: Create Pull Request
@ -71,6 +76,7 @@ Note that in order to read the step output the action step must have an id.
- name: Check outputs
run: |
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
```
### Action behaviour
@ -84,7 +90,7 @@ How the action behaves:
- If there are changes (i.e. a diff exists with the checked-out base branch), the changes will be pushed to a new `branch` and a pull request created.
- If there are no changes (i.e. no diff exists with the checked-out base branch), no pull request will be created and the action exits silently.
- If a pull request already exists and there are no further changes (i.e. no diff with the current pull request branch) then the action exits silently.
- If a pull request exists and new changes on the base branch make the pull request unnecessary (i.e. there is no longer a diff between the base and pull request branch), the pull request is automatically closed and the branch deleted.
- If a pull request exists and new changes on the base branch make the pull request unnecessary (i.e. there is no longer a diff between the pull request branch and the base), the pull request is automatically closed. Additionally, if `delete-branch` is set to `true` the `branch` will be deleted.
For further details about how the action works and usage guidelines, see [Concepts, guidelines and advanced usage](docs/concepts-guidelines.md).
@ -147,13 +153,12 @@ To create a project card for the pull request, pass the `pull-request-number` st
## Reference Example
The following workflow is a reference example that sets many of the main inputs.
The following workflow sets many of the action's inputs for reference purposes.
Check the [defaults](#action-inputs) to avoid setting inputs unnecessarily.
See [examples](docs/examples.md) for more realistic use cases.
```yml
name: Create Pull Request
on: push
jobs:
createPullRequest:
runs-on: ubuntu-latest
@ -173,6 +178,7 @@ jobs:
author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
signoff: false
branch: example-patches
delete-branch: true
title: '[Example] Update report'
body: |
Update report
@ -191,9 +197,10 @@ jobs:
milestone: 1
draft: false
- name: Check output
- name: Check outputs
run: |
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
```
An example based on the above reference configuration creates pull requests that look like this:

View File

@ -543,6 +543,74 @@ describe('create-or-update-branch tests', () => {
).toBeTruthy()
})
it('tests create, squash merge, and update with identical changes', async () => {
// Branches that have been squash merged appear to have a diff with the base due to
// different commits for the same changes. To prevent creating pull requests
// unnecessarily we reset (rebase) the pull request branch when a reset would result
// in no diff with the base. This will reset any undeleted branches after merging.
// Create tracked and untracked file changes
const changes = await createChanges()
const commitMessage = uuidv4()
const result = await createOrUpdateBranch(
git,
commitMessage,
'',
BRANCH,
REMOTE_NAME,
false
)
expect(result.action).toEqual('created')
expect(await getFileContent(TRACKED_FILE)).toEqual(changes.tracked)
expect(await getFileContent(UNTRACKED_FILE)).toEqual(changes.untracked)
expect(
await gitLogMatches([commitMessage, INIT_COMMIT_MESSAGE])
).toBeTruthy()
// Push pull request branch to remote
await git.push([
'--force-with-lease',
REMOTE_NAME,
`HEAD:refs/heads/${BRANCH}`
])
await afterTest(false)
await beforeTest()
// Create a commit on the base with the same changes as the branch
// This simulates squash merge of the pull request
const commits = await createCommits(
git,
1,
changes.tracked,
changes.untracked
)
await git.push([
'--force',
REMOTE_NAME,
`HEAD:refs/heads/${DEFAULT_BRANCH}`
])
// Create the same tracked and untracked file changes (no change on update)
const _changes = await createChanges(changes.tracked, changes.untracked)
const _commitMessage = uuidv4()
const _result = await createOrUpdateBranch(
git,
_commitMessage,
'',
BRANCH,
REMOTE_NAME,
false
)
expect(_result.action).toEqual('updated')
expect(_result.hasDiffWithBase).toBeFalsy()
expect(await getFileContent(TRACKED_FILE)).toEqual(_changes.tracked)
expect(await getFileContent(UNTRACKED_FILE)).toEqual(_changes.untracked)
expect(
await gitLogMatches([...commits.commitMsgs, INIT_COMMIT_MESSAGE])
).toBeTruthy()
})
it('tests create and update with commits on the working base (during the workflow)', async () => {
// Create commits on the working base
const commits = await createCommits(git)
@ -1213,6 +1281,80 @@ describe('create-or-update-branch tests', () => {
).toBeTruthy()
})
it('tests create, squash merge, and update with identical changes (WBNB)', async () => {
// Branches that have been squash merged appear to have a diff with the base due to
// different commits for the same changes. To prevent creating pull requests
// unnecessarily we reset (rebase) the pull request branch when a reset would result
// in no diff with the base. This will reset any undeleted branches after merging.
// Set the working base to a branch that is not the pull request base
await git.checkout(NOT_BASE_BRANCH)
// Create tracked and untracked file changes
const changes = await createChanges()
const commitMessage = uuidv4()
const result = await createOrUpdateBranch(
git,
commitMessage,
BASE,
BRANCH,
REMOTE_NAME,
false
)
expect(result.action).toEqual('created')
expect(await getFileContent(TRACKED_FILE)).toEqual(changes.tracked)
expect(await getFileContent(UNTRACKED_FILE)).toEqual(changes.untracked)
expect(
await gitLogMatches([commitMessage, INIT_COMMIT_MESSAGE])
).toBeTruthy()
// Push pull request branch to remote
await git.push([
'--force-with-lease',
REMOTE_NAME,
`HEAD:refs/heads/${BRANCH}`
])
await afterTest(false)
await beforeTest()
// Create a commit on the base with the same changes as the branch
// This simulates squash merge of the pull request
const commits = await createCommits(
git,
1,
changes.tracked,
changes.untracked
)
await git.push([
'--force',
REMOTE_NAME,
`HEAD:refs/heads/${DEFAULT_BRANCH}`
])
// Set the working base to a branch that is not the pull request base
await git.checkout(NOT_BASE_BRANCH)
// Create the same tracked and untracked file changes (no change on update)
const _changes = await createChanges(changes.tracked, changes.untracked)
const _commitMessage = uuidv4()
const _result = await createOrUpdateBranch(
git,
_commitMessage,
BASE,
BRANCH,
REMOTE_NAME,
false
)
expect(_result.action).toEqual('updated')
expect(_result.hasDiffWithBase).toBeFalsy()
expect(await getFileContent(TRACKED_FILE)).toEqual(_changes.tracked)
expect(await getFileContent(UNTRACKED_FILE)).toEqual(_changes.untracked)
expect(
await gitLogMatches([...commits.commitMsgs, INIT_COMMIT_MESSAGE])
).toBeTruthy()
})
it('tests create and update with commits on the working base (during the workflow) (WBNB)', async () => {
// Set the working base to a branch that is not the pull request base
await git.checkout(NOT_BASE_BRANCH)

View File

@ -27,6 +27,11 @@ inputs:
branch:
description: 'The pull request branch name.'
default: 'create-pull-request/patch'
delete-branch:
description: >
Delete the `branch` when closing pull requests, and when undeleted after merging.
Recommend `true`.
default: false
branch-suffix:
description: 'The branch suffix type when using the alternative branching strategy.'
base:

8788
dist/index.js vendored

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,8 @@ A pull request references two branches:
## Events and checkout
For each [event type](https://docs.github.com/en/actions/reference/events-that-trigger-workflows) there is a default `GITHUB_SHA` that will be checked out by the GitHub Actions [checkout](https://github.com/actions/checkout) action.
This action expects repositories to be checked out with the official GitHub Actions [checkout](https://github.com/actions/checkout) action.
For each [event type](https://docs.github.com/en/actions/reference/events-that-trigger-workflows) there is a default `GITHUB_SHA` that will be checked out.
The default can be overridden by specifying a `ref` on checkout.
@ -141,9 +142,13 @@ Pull requests created by the action using the default `GITHUB_TOKEN` cannot trig
There are a number of workarounds with different pros and cons.
- Use the default `GITHUB_TOKEN` and allow the action to create pull requests that have no checks enabled. Manually close pull requests and immediately reopen them. This will enable `on: pull_request` workflows to run and be added as checks.
- Use a `repo` scoped [Personal Access Token (PAT)](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) created on an account that has write access to the repository that pull requests are being created in. This is the standard workaround and [recommended by GitHub](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#triggering-new-workflows-using-a-personal-access-token). However, the PAT cannot be scoped to a specific repository so the token becomes a very sensitive secret. If this is a concern, the PAT can instead be created for a dedicated [machine account](https://docs.github.com/en/github/site-policy/github-terms-of-service#3-account-requirements) that has collaborator access to the repository. Also note that because the account that owns the PAT will be the creator of pull requests, that user account will be unable to perform actions such as request changes or approve the pull request.
- Use [SSH (deploy keys)](#push-using-ssh-deploy-keys) to push the pull request branch. This is arguably more secure than using a PAT because deploy keys can be set per repository. However, this method will only trigger `on: push` workflows.
- Use a [machine account that creates pull requests from its own fork](#push-pull-request-branches-to-a-fork). This is the most secure because the PAT created only grants access to the machine account's fork, not the main repository. This method will trigger `on: pull_request` workflows to run. Workflows triggered `on: push` will not run because the push event is in the fork.
- Use a [GitHub App to generate a token](#authenticating-with-github-app-generated-tokens) that can be used with this action. GitHub App generated tokens are more secure than using a PAT because GitHub App access permissions can be set with finer granularity and are scoped to only repositories where the App is installed. This method will trigger both `on: push` and `on: pull_request` workflows.
### Security

View File

@ -3,6 +3,8 @@
- [Use case: Create a pull request to update X on push](#use-case-create-a-pull-request-to-update-x-on-push)
- [Update project authors](#update-project-authors)
- [Keep a branch up-to-date with another](#keep-a-branch-up-to-date-with-another)
- [Use case: Create a pull request to update X on release](#use-case-create-a-pull-request-to-update-x-on-release)
- [Update changelog](#update-changelog)
- [Use case: Create a pull request to update X periodically](#use-case-create-a-pull-request-to-update-x-periodically)
- [Update NPM dependencies](#update-npm-dependencies)
- [Update Gradle dependencies](#update-gradle-dependencies)
@ -18,6 +20,7 @@
- [Misc workflow tips](#misc-workflow-tips)
- [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)
- [Debugging GitHub Actions](#debugging-github-actions)
@ -83,6 +86,45 @@ jobs:
branch: production-promotion
```
## Use case: Create a pull request to update X on release
This pattern will work well for updating any kind of static content based on the tagged commit of a release. Note that because `release` is one of the [events which checkout a commit](concepts-guidelines.md#events-which-checkout-a-commit) it is necessary to supply the `base` input to the action.
### Update changelog
Raises a pull request to update the `CHANGELOG.md` file based on the tagged commit of the release.
Note that [git-chglog](https://github.com/git-chglog/git-chglog/) requires some configuration files to exist in the repository before this workflow will work.
This workflow assumes the tagged release was made on a default branch called `master`.
```yml
name: Update Changelog
on:
release:
types: [published]
jobs:
updateChangelog:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Update Changelog
run: |
curl -o git-chglog -L https://github.com/git-chglog/git-chglog/releases/download/0.9.1/git-chglog_linux_amd64
chmod u+x git-chglog
./git-chglog -o CHANGELOG.md
rm git-chglog
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
commit-message: update changelog
title: Update Changelog
body: Update changelog to reflect release changes
branch: update-changelog
base: master
```
## Use case: Create a pull request to update X periodically
This pattern will work well for updating any kind of static content from an external source. The workflow executes on a schedule and raises a pull request when there are changes.
@ -498,21 +540,6 @@ The recommended method is to use [`set-output`](https://docs.github.com/en/actio
body: ${{ steps.vars.outputs.pr_body }}
```
Alternatively, [`set-env`](https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable) can be used to create environment variables.
```yml
- name: Set environment variables
run: |
echo ::set-env name=PULL_REQUEST_TITLE::"[Test] Add report file $(date +%d-%m-%Y)"
echo ::set-env name=PULL_REQUEST_BODY::"This PR was auto-generated on $(date +%d-%m-%Y) \
by [create-pull-request](https://github.com/peter-evans/create-pull-request)."
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
title: ${{ env.PULL_REQUEST_TITLE }}
body: ${{ env.PULL_REQUEST_BODY }}
```
### Setting the pull request body from a file
This example shows how file content can be read into a variable and passed to the action.

797
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -29,26 +29,26 @@
},
"homepage": "https://github.com/peter-evans/create-pull-request",
"dependencies": {
"@actions/core": "1.2.4",
"@actions/core": "1.2.6",
"@actions/exec": "1.0.4",
"@octokit/core": "3.1.2",
"@octokit/plugin-paginate-rest": "2.3.0",
"@octokit/plugin-rest-endpoint-methods": "4.1.2",
"@octokit/plugin-paginate-rest": "2.4.0",
"@octokit/plugin-rest-endpoint-methods": "4.2.0",
"uuid": "8.3.0"
},
"devDependencies": {
"@types/jest": "26.0.9",
"@types/node": "14.0.27",
"@typescript-eslint/parser": "3.9.0",
"@vercel/ncc": "0.23.0",
"eslint": "7.6.0",
"@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": "23.20.0",
"jest": "26.4.0",
"jest-circus": "26.4.0",
"eslint-plugin-jest": "24.0.1",
"jest": "26.4.2",
"jest-circus": "26.4.2",
"js-yaml": "3.14.0",
"prettier": "2.0.5",
"ts-jest": "26.2.0",
"typescript": "3.9.7"
"prettier": "2.1.2",
"ts-jest": "26.3.0",
"typescript": "4.0.2"
}
}

View File

@ -78,15 +78,6 @@ async function isEven(
)
}
async function hasDiff(
git: GitCommandManager,
branch1: string,
branch2: string
): Promise<boolean> {
const result = await git.diff([`${branch1}..${branch2}`])
return result.length > 0
}
function splitLines(multilineString: string): string[] {
return multilineString
.split('\n')
@ -196,9 +187,18 @@ export async function createOrUpdateBranch(
// Checkout the pull request branch
await git.checkout(branch)
if (await hasDiff(git, branch, tempBranch)) {
// If the branch differs from the recreated temp version then the branch is reset
// For changes on base this action is similar to a rebase of the pull request branch
// Reset the branch if one of the following conditions is true.
// - If the branch differs from the recreated temp branch.
// - If the recreated temp branch is not ahead of the base. This means there will be
// no pull request diff after the branch is reset. This will reset any undeleted
// branches after merging. In particular, it catches a case where the branch was
// squash merged but not deleted. We need to reset to make sure it doesn't appear
// to have a diff with the base due to different commits for the same changes.
// For changes on base this reset is equivalent to a rebase of the pull request branch.
if (
(await git.hasDiff([`${branch}..${tempBranch}`])) ||
!(await isAhead(git, base, tempBranch))
) {
core.info(`Resetting '${branch}'`)
// Alternatively, git switch -C branch tempBranch
await git.checkout(branch, tempBranch)

View File

@ -17,6 +17,7 @@ export interface Inputs {
author: string
signoff: boolean
branch: string
deleteBranch: boolean
branchSuffix: string
base: string
pushToFork: string
@ -194,18 +195,21 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
branchRepository
)
} else {
// If there is no longer a diff with the base delete the branch
// There is no longer a diff with the base
// Check we are in a state where a branch exists
if (['updated', 'not-updated'].includes(result.action)) {
core.info(
`Branch '${inputs.branch}' no longer differs from base branch '${inputs.base}'`
)
core.info(`Closing pull request and deleting branch '${inputs.branch}'`)
await git.push([
'--delete',
'--force',
branchRemoteName,
`refs/heads/${inputs.branch}`
])
if (inputs.deleteBranch) {
core.info(`Deleting branch '${inputs.branch}'`)
await git.push([
'--delete',
'--force',
branchRemoteName,
`refs/heads/${inputs.branch}`
])
}
}
}
} catch (error) {

View File

@ -96,15 +96,6 @@ export class GitCommandManager {
return output.exitCode === 0
}
async diff(options?: string[]): Promise<string> {
const args = ['-c', 'core.pager=cat', 'diff']
if (options) {
args.push(...options)
}
const output = await this.exec(args)
return output.stdout.trim()
}
async fetch(
refSpec: string[],
remoteName?: string,
@ -153,18 +144,26 @@ export class GitCommandManager {
return this.workingDirectory
}
async hasDiff(options?: string[]): Promise<boolean> {
const args = ['diff', '--quiet']
if (options) {
args.push(...options)
}
const output = await this.exec(args, true)
return output.exitCode === 1
}
async isDirty(untracked: boolean): Promise<boolean> {
const diffArgs = ['--abbrev=40', '--full-index', '--raw']
// Check staged changes
if (await this.diff([...diffArgs, '--staged'])) {
// Check untracked changes
if (untracked && (await this.status(['--porcelain', '-unormal']))) {
return true
}
// Check working index changes
if (await this.diff(diffArgs)) {
if (await this.hasDiff()) {
return true
}
// Check untracked changes
if (untracked && (await this.status(['--porcelain', '-unormal']))) {
// Check staged changes
if (await this.hasDiff(['--staged'])) {
return true
}
return false

View File

@ -10,6 +10,11 @@ interface Repository {
repo: string
}
interface Pull {
number: number
html_url: string
}
export class GitHubHelper {
private octokit: InstanceType<typeof Octokit>
@ -33,7 +38,7 @@ export class GitHubHelper {
inputs: Inputs,
baseRepository: string,
headBranch: string
): Promise<number> {
): Promise<Pull> {
// Try to create the pull request
try {
const {data: pull} = await this.octokit.pulls.create({
@ -47,7 +52,10 @@ export class GitHubHelper {
core.info(
`Created pull request #${pull.number} (${headBranch} => ${inputs.base})`
)
return pull.number
return {
number: pull.number,
html_url: pull.html_url
}
} catch (e) {
if (
!e.message ||
@ -74,7 +82,10 @@ export class GitHubHelper {
core.info(
`Updated pull request #${pull.number} (${headBranch} => ${inputs.base})`
)
return pull.number
return {
number: pull.number,
html_url: pull.html_url
}
}
async getRepositoryParent(headRepository: string): Promise<string> {
@ -98,16 +109,14 @@ export class GitHubHelper {
const headBranch = `${headOwner}:${inputs.branch}`
// Create or update the pull request
const pullNumber = await this.createOrUpdate(
inputs,
baseRepository,
headBranch
)
const pull = await this.createOrUpdate(inputs, baseRepository, headBranch)
// Set outputs
core.startGroup('Setting outputs')
core.setOutput('pull-request-number', pullNumber)
core.exportVariable('PULL_REQUEST_NUMBER', pullNumber)
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
@ -127,7 +136,7 @@ export class GitHubHelper {
if (Object.keys(updateIssueParams).length > 0) {
await this.octokit.issues.update({
...this.parseRepository(baseRepository),
issue_number: pullNumber,
issue_number: pull.number,
...updateIssueParams
})
}
@ -146,7 +155,7 @@ export class GitHubHelper {
try {
await this.octokit.pulls.requestReviewers({
...this.parseRepository(baseRepository),
pull_number: pullNumber,
pull_number: pull.number,
...requestReviewersParams
})
} catch (e) {

View File

@ -13,6 +13,7 @@ async function run(): Promise<void> {
author: core.getInput('author'),
signoff: core.getInput('signoff') === 'true',
branch: core.getInput('branch'),
deleteBranch: core.getInput('delete-branch') === 'true',
branchSuffix: core.getInput('branch-suffix'),
base: core.getInput('base'),
pushToFork: core.getInput('push-to-fork'),