Compare commits

...

28 Commits

Author SHA1 Message Date
052fc72b41 Merge pull request #724 from peter-evans/fix-assignees
fix: use the correct assignees property
2021-02-10 09:28:28 +09:00
ed00d4629c fix: use the correct assignees property 2021-02-10 09:00:23 +09:00
34371f09e5 Merge pull request #719 from peter-evans/add-to-lists
fix: add to labels and assignees instead of resetting
2021-02-08 10:19:41 +09:00
c27ea51ae0 fix: add to labels and assignees instead of resetting 2021-02-08 09:32:46 +09:00
5e9d0ee9ea Merge pull request #712 from peter-evans/operation-output
feat: add pull-request-operation output
2021-02-01 10:28:29 +09:00
b5f41d9b08 feat: add pull-request-operation output 2021-02-01 09:57:11 +09:00
2455e15969 Merge pull request #704 from jonico/support-ghes
Support GitHub Enterprise Server
2021-01-26 11:17:38 +09:00
05bc46786e Support GitHub Server API URL
* pass GitHub Server API in Octokkit constructor
2021-01-25 19:16:19 +01:00
adc6552966 Support GitHub Enterprise Server
* parse GITHUB_SERVER_URL if present
* accept proper server remotes as well
2021-01-25 18:25:20 +01:00
171fc6cce4 Merge pull request #701 from peter-evans/update-distribution
Update distribution
2021-01-25 14:22:27 +09:00
3fb765f674 build: update distribution 2021-01-25 05:19:37 +00:00
d95c81ee98 Merge pull request #686 from peter-evans/update-dependencies
Update dependencies
2021-01-25 14:16:59 +09:00
8d5ed6557f chore: update dependencies 2021-01-21 02:46:33 +00:00
7b1819c092 Merge pull request #683 from peter-evans/update-distribution
Update distribution
2020-12-28 10:22:06 +09:00
be0a8c9666 build: update distribution 2020-12-28 01:20:44 +00:00
a0a6157bf1 Merge pull request #594 from peter-evans/update-dependencies
Update dependencies
2020-12-28 10:18:18 +09:00
9c5ec2e07d chore: update dependencies 2020-12-24 02:04:52 +00:00
45c510e1f6 Merge pull request #672 from peter-evans/reset-perf
perf: git reset instead of fetch
2020-12-23 14:28:23 +09:00
249b80db6b perf: git reset instead of fetch 2020-12-23 14:10:40 +09:00
6c2b44c6ac Merge pull request #666 from peter-evans/dependabot/npm_and_yarn/node-notifier-8.0.1
build(deps): bump node-notifier from 8.0.0 to 8.0.1
2020-12-23 09:48:12 +09:00
76c58cf6a9 build(deps): bump node-notifier from 8.0.0 to 8.0.1
Bumps [node-notifier](https://github.com/mikaelbr/node-notifier) from 8.0.0 to 8.0.1.
- [Release notes](https://github.com/mikaelbr/node-notifier/releases)
- [Changelog](https://github.com/mikaelbr/node-notifier/blob/v8.0.1/CHANGELOG.md)
- [Commits](https://github.com/mikaelbr/node-notifier/compare/v8.0.0...v8.0.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-22 13:17:50 +00:00
8c603dbb04 Merge pull request #653 from peter-evans/fix-error-handling
fix: change or->and to catch all errors
2020-12-09 09:56:23 +09:00
d01e0807ef fix: change or->and to catch all errors 2020-12-09 09:38:10 +09:00
ce699aa2d1 Merge pull request #637 from peter-evans/prune-remote
fix: prune stale remote ref for self-hosted runners
2020-11-25 12:40:23 +09:00
9984f611a7 fix: prune stale remote ref for self-hosted runners 2020-11-24 12:34:57 +09:00
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
10 changed files with 9384 additions and 2538 deletions

View File

@ -66,7 +66,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

783
dist/index.js vendored

File diff suppressed because it is too large Load Diff

View File

@ -20,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)

10940
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -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.2.4",
"@octokit/plugin-paginate-rest": "2.8.0",
"@octokit/plugin-rest-endpoint-methods": "4.5.2",
"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",
"@types/jest": "26.0.20",
"@types/node": "14.14.22",
"@typescript-eslint/parser": "4.14.0",
"@vercel/ncc": "0.27.0",
"eslint": "7.18.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"
"eslint-plugin-jest": "24.1.3",
"jest": "26.6.3",
"jest-circus": "26.6.3",
"js-yaml": "4.0.0",
"prettier": "2.2.1",
"ts-jest": "26.4.4",
"typescript": "4.1.3"
}
}

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')
@ -139,8 +130,18 @@ export async function createOrUpdateBranch(
// 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
@ -177,7 +178,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) {
@ -205,7 +206,7 @@ export async function createOrUpdateBranch(
// 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 hasDiff(git, branch, tempBranch)) ||
(await git.hasDiff([`${branch}..${tempBranch}`])) ||
!(await isAhead(git, base, tempBranch))
) {
core.info(`Resetting '${branch}'`)

View File

@ -106,6 +106,12 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
`The 'base' and 'branch' for a pull request must be different branches. Unable to continue.`
)
}
// For self-hosted runners the repository state persists between runs.
// This command prunes the stale remote ref when the pull request branch was
// deleted after being merged or closed. Without this the push using
// '--force-with-lease' fails due to "stale info."
// https://github.com/peter-evans/create-pull-request/issues/633
await git.exec(['remote', 'prune', branchRemoteName])
core.endGroup()
// Apply the branch suffix if set
@ -189,11 +195,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
@ -209,6 +228,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()
}
}
}

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

@ -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)
}
@ -54,13 +56,16 @@ export class GitHubHelper {
)
return {
number: pull.number,
html_url: pull.html_url
html_url: pull.html_url,
created: true
}
} catch (e) {
if (
!e.message ||
!e.message.includes(`A pull request already exists for ${headBranch}`)
e.message &&
e.message.includes(`A pull request already exists for ${headBranch}`)
) {
core.info(`A pull request already exists for ${headBranch}`)
} else {
throw e
}
}
@ -84,7 +89,8 @@ export class GitHubHelper {
)
return {
number: pull.number,
html_url: pull.html_url
html_url: pull.html_url,
created: false
}
}
@ -104,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({
...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.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.issues.addAssignees({
...this.parseRepository(baseRepository),
issue_number: pull.number,
assignees: inputs.assignees
})
}
@ -166,5 +170,7 @@ export class GitHubHelper {
}
}
}
return pull
}
}

View File

@ -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) {