Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
052fc72b41 | |||
ed00d4629c | |||
34371f09e5 | |||
c27ea51ae0 | |||
5e9d0ee9ea | |||
b5f41d9b08 | |||
2455e15969 | |||
05bc46786e | |||
adc6552966 | |||
171fc6cce4 | |||
3fb765f674 | |||
d95c81ee98 | |||
8d5ed6557f | |||
7b1819c092 | |||
be0a8c9666 | |||
a0a6157bf1 | |||
9c5ec2e07d | |||
45c510e1f6 | |||
249b80db6b | |||
6c2b44c6ac | |||
76c58cf6a9 | |||
8c603dbb04 | |||
d01e0807ef |
@ -66,7 +66,13 @@ All inputs are **optional**. If not set, sensible defaults will be used.
|
|||||||
|
|
||||||
### Action outputs
|
### 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.
|
Note that in order to read the step outputs the action step must have an id.
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
|
738
dist/index.js
vendored
738
dist/index.js
vendored
File diff suppressed because it is too large
Load Diff
10940
package-lock.json
generated
10940
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
32
package.json
32
package.json
@ -31,24 +31,24 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "1.2.6",
|
"@actions/core": "1.2.6",
|
||||||
"@actions/exec": "1.0.4",
|
"@actions/exec": "1.0.4",
|
||||||
"@octokit/core": "3.1.2",
|
"@octokit/core": "3.2.4",
|
||||||
"@octokit/plugin-paginate-rest": "2.4.0",
|
"@octokit/plugin-paginate-rest": "2.8.0",
|
||||||
"@octokit/plugin-rest-endpoint-methods": "4.2.0",
|
"@octokit/plugin-rest-endpoint-methods": "4.5.2",
|
||||||
"uuid": "8.3.0"
|
"uuid": "8.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "26.0.14",
|
"@types/jest": "26.0.20",
|
||||||
"@types/node": "14.10.3",
|
"@types/node": "14.14.22",
|
||||||
"@typescript-eslint/parser": "4.1.1",
|
"@typescript-eslint/parser": "4.14.0",
|
||||||
"@vercel/ncc": "0.24.1",
|
"@vercel/ncc": "0.27.0",
|
||||||
"eslint": "7.9.0",
|
"eslint": "7.18.0",
|
||||||
"eslint-plugin-github": "4.1.1",
|
"eslint-plugin-github": "4.1.1",
|
||||||
"eslint-plugin-jest": "24.0.1",
|
"eslint-plugin-jest": "24.1.3",
|
||||||
"jest": "26.4.2",
|
"jest": "26.6.3",
|
||||||
"jest-circus": "26.4.2",
|
"jest-circus": "26.6.3",
|
||||||
"js-yaml": "3.14.0",
|
"js-yaml": "4.0.0",
|
||||||
"prettier": "2.1.2",
|
"prettier": "2.2.1",
|
||||||
"ts-jest": "26.3.0",
|
"ts-jest": "26.4.4",
|
||||||
"typescript": "4.0.2"
|
"typescript": "4.1.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,8 +130,18 @@ export async function createOrUpdateBranch(
|
|||||||
// Perform fetch and reset the working base
|
// Perform fetch and reset the working base
|
||||||
// Commits made during the workflow will be removed
|
// Commits made during the workflow will be removed
|
||||||
if (workingBaseType == WorkingBaseType.Branch) {
|
if (workingBaseType == WorkingBaseType.Branch) {
|
||||||
core.info(`Resetting working base branch '${workingBase}' to its remote`)
|
core.info(`Resetting working base branch '${workingBase}'`)
|
||||||
await git.fetch([`${workingBase}:${workingBase}`], baseRemote, ['--force'])
|
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
|
// If the working base is not the base, rebase the temp branch commits
|
||||||
@ -168,7 +178,7 @@ export async function createOrUpdateBranch(
|
|||||||
// The pull request branch does not exist
|
// The pull request branch does not exist
|
||||||
core.info(`Pull request branch '${branch}' does not exist yet.`)
|
core.info(`Pull request branch '${branch}' does not exist yet.`)
|
||||||
// Create the pull request branch
|
// 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
|
// Check if the pull request branch is ahead of the base
|
||||||
result.hasDiffWithBase = await isAhead(git, base, branch)
|
result.hasDiffWithBase = await isAhead(git, base, branch)
|
||||||
if (result.hasDiffWithBase) {
|
if (result.hasDiffWithBase) {
|
||||||
|
@ -195,11 +195,24 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
|
|||||||
|
|
||||||
if (result.hasDiffWithBase) {
|
if (result.hasDiffWithBase) {
|
||||||
// Create or update the pull request
|
// Create or update the pull request
|
||||||
await githubHelper.createOrUpdatePullRequest(
|
const pull = await githubHelper.createOrUpdatePullRequest(
|
||||||
inputs,
|
inputs,
|
||||||
baseRemote.repository,
|
baseRemote.repository,
|
||||||
branchRepository
|
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 {
|
} else {
|
||||||
// There is no longer a diff with the base
|
// There is no longer a diff with the base
|
||||||
// Check we are in a state where a branch exists
|
// Check we are in a state where a branch exists
|
||||||
@ -215,6 +228,10 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
|
|||||||
branchRemoteName,
|
branchRemoteName,
|
||||||
`refs/heads/${inputs.branch}`
|
`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 {
|
interface Pull {
|
||||||
number: number
|
number: number
|
||||||
html_url: string
|
html_url: string
|
||||||
|
created: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GitHubHelper {
|
export class GitHubHelper {
|
||||||
@ -23,6 +24,7 @@ export class GitHubHelper {
|
|||||||
if (token) {
|
if (token) {
|
||||||
options.auth = `${token}`
|
options.auth = `${token}`
|
||||||
}
|
}
|
||||||
|
options.baseUrl = process.env['GITHUB_API_URL'] || 'https://api.github.com'
|
||||||
this.octokit = new Octokit(options)
|
this.octokit = new Octokit(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,13 +56,16 @@ export class GitHubHelper {
|
|||||||
)
|
)
|
||||||
return {
|
return {
|
||||||
number: pull.number,
|
number: pull.number,
|
||||||
html_url: pull.html_url
|
html_url: pull.html_url,
|
||||||
|
created: true
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (
|
if (
|
||||||
!e.message ||
|
e.message &&
|
||||||
!e.message.includes(`A pull request already exists for ${headBranch}`)
|
e.message.includes(`A pull request already exists for ${headBranch}`)
|
||||||
) {
|
) {
|
||||||
|
core.info(`A pull request already exists for ${headBranch}`)
|
||||||
|
} else {
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,7 +89,8 @@ export class GitHubHelper {
|
|||||||
)
|
)
|
||||||
return {
|
return {
|
||||||
number: pull.number,
|
number: pull.number,
|
||||||
html_url: pull.html_url
|
html_url: pull.html_url,
|
||||||
|
created: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,40 +110,38 @@ export class GitHubHelper {
|
|||||||
inputs: Inputs,
|
inputs: Inputs,
|
||||||
baseRepository: string,
|
baseRepository: string,
|
||||||
headRepository: string
|
headRepository: string
|
||||||
): Promise<void> {
|
): Promise<Pull> {
|
||||||
const [headOwner] = headRepository.split('/')
|
const [headOwner] = headRepository.split('/')
|
||||||
const headBranch = `${headOwner}:${inputs.branch}`
|
const headBranch = `${headOwner}:${inputs.branch}`
|
||||||
|
|
||||||
// Create or update the pull request
|
// Create or update the pull request
|
||||||
const pull = await this.createOrUpdate(inputs, baseRepository, headBranch)
|
const pull = await this.createOrUpdate(inputs, baseRepository, headBranch)
|
||||||
|
|
||||||
// Set outputs
|
// Apply milestone
|
||||||
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 = {}
|
|
||||||
if (inputs.milestone) {
|
if (inputs.milestone) {
|
||||||
updateIssueParams['milestone'] = inputs.milestone
|
|
||||||
core.info(`Applying 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.issues.update({
|
||||||
...this.parseRepository(baseRepository),
|
...this.parseRepository(baseRepository),
|
||||||
issue_number: pull.number,
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
17
src/utils.ts
17
src/utils.ts
@ -39,8 +39,21 @@ interface RemoteDetail {
|
|||||||
export function getRemoteDetail(remoteUrl: string): RemoteDetail {
|
export function getRemoteDetail(remoteUrl: string): RemoteDetail {
|
||||||
// Parse the protocol and github repository from a URL
|
// Parse the protocol and github repository from a URL
|
||||||
// e.g. HTTPS, peter-evans/create-pull-request
|
// e.g. HTTPS, peter-evans/create-pull-request
|
||||||
const httpsUrlPattern = /^https:\/\/.*@?github.com\/(.+\/.+)$/i
|
const githubUrl = process.env['GITHUB_SERVER_URL'] || 'https://github.com'
|
||||||
const sshUrlPattern = /^git@github.com:(.+\/.+).git$/i
|
|
||||||
|
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)
|
const httpsMatch = remoteUrl.match(httpsUrlPattern)
|
||||||
if (httpsMatch) {
|
if (httpsMatch) {
|
||||||
|
Reference in New Issue
Block a user