Compare commits
9 Commits
signed-com
...
signed-com
Author | SHA1 | Date | |
---|---|---|---|
![]() |
740d9850a7 | ||
![]() |
e7f5ea9fd9 | ||
![]() |
66ddf90dac | ||
![]() |
fd3e742ffd | ||
![]() |
eea4f44785 | ||
![]() |
5a9be5875b | ||
![]() |
3d665e5aea | ||
![]() |
bb1f2b1327 | ||
![]() |
1da4bbe67c |
@@ -75,6 +75,7 @@ All inputs are **optional**. If not set, sensible defaults will be used.
|
|||||||
| `team-reviewers` | A comma or newline-separated list of GitHub teams to request a review from. Note that a `repo` scoped [PAT](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token), or equivalent [GitHub App permissions](docs/concepts-guidelines.md#authenticating-with-github-app-generated-tokens), are required. | |
|
| `team-reviewers` | A comma or newline-separated list of GitHub teams to request a review from. Note that a `repo` scoped [PAT](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token), or equivalent [GitHub App permissions](docs/concepts-guidelines.md#authenticating-with-github-app-generated-tokens), are required. | |
|
||||||
| `milestone` | The number of the milestone to associate this pull request with. | |
|
| `milestone` | The number of the milestone to associate this pull request with. | |
|
||||||
| `draft` | Create a [draft pull request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests#draft-pull-requests). It is not possible to change draft status after creation except through the web interface. | `false` |
|
| `draft` | Create a [draft pull request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests#draft-pull-requests). It is not possible to change draft status after creation except through the web interface. | `false` |
|
||||||
|
| `maintainer-can-modify` | Indicates whether [maintainers can modify](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork) the pull request. | `true` |
|
||||||
|
|
||||||
#### commit-message
|
#### commit-message
|
||||||
|
|
||||||
@@ -116,9 +117,10 @@ The following outputs can be used by subsequent workflow steps.
|
|||||||
|
|
||||||
- `pull-request-number` - The pull request number.
|
- `pull-request-number` - The pull request number.
|
||||||
- `pull-request-url` - The URL of the pull request.
|
- `pull-request-url` - The URL of the pull request.
|
||||||
- `pull-request-operation` - The pull request operation performed by the action, `created`, `updated` or `closed`.
|
- `pull-request-operation` - The pull request operation performed by the action, `created`, `updated`, `closed` or `none`.
|
||||||
- `pull-request-head-sha` - The commit SHA of the pull request branch.
|
- `pull-request-head-sha` - The commit SHA of the pull request branch.
|
||||||
- `pull-request-branch` - The branch name of the pull request.
|
- `pull-request-branch` - The branch name of the pull request.
|
||||||
|
- `pull-request-commits-verified` - Whether GitHub considers the signature of the branch's commits to be verified; `true` or `false`.
|
||||||
|
|
||||||
Step outputs can be accessed as in the following example.
|
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.
|
||||||
|
@@ -53,7 +53,7 @@ inputs:
|
|||||||
The pull request will be created to merge the fork's branch into the parent's base.
|
The pull request will be created to merge the fork's branch into the parent's base.
|
||||||
sign-commits:
|
sign-commits:
|
||||||
description: 'Sign commits as `github-actions[bot]` when using `GITHUB_TOKEN`, or your own bot when using GitHub App tokens.'
|
description: 'Sign commits as `github-actions[bot]` when using `GITHUB_TOKEN`, or your own bot when using GitHub App tokens.'
|
||||||
default: true
|
default: false
|
||||||
title:
|
title:
|
||||||
description: 'The title of the pull request.'
|
description: 'The title of the pull request.'
|
||||||
default: 'Changes by create-pull-request action'
|
default: 'Changes by create-pull-request action'
|
||||||
@@ -77,6 +77,9 @@ inputs:
|
|||||||
draft:
|
draft:
|
||||||
description: 'Create a draft pull request. It is not possible to change draft status after creation except through the web interface'
|
description: 'Create a draft pull request. It is not possible to change draft status after creation except through the web interface'
|
||||||
default: false
|
default: false
|
||||||
|
maintainer-can-modify:
|
||||||
|
description: 'Indicates whether maintainers can modify the pull request.'
|
||||||
|
default: true
|
||||||
outputs:
|
outputs:
|
||||||
pull-request-number:
|
pull-request-number:
|
||||||
description: 'The pull request number'
|
description: 'The pull request number'
|
||||||
|
80
dist/index.js
vendored
80
dist/index.js
vendored
@@ -356,8 +356,9 @@ function createPullRequest(inputs) {
|
|||||||
core.endGroup();
|
core.endGroup();
|
||||||
core.startGroup('Determining the base and head repositories');
|
core.startGroup('Determining the base and head repositories');
|
||||||
const baseRemote = gitConfigHelper.getGitRemote();
|
const baseRemote = gitConfigHelper.getGitRemote();
|
||||||
// Init the GitHub client
|
// Init the GitHub clients
|
||||||
const githubHelper = new github_helper_1.GitHubHelper(baseRemote.hostname, inputs.token);
|
const ghBranch = new github_helper_1.GitHubHelper(baseRemote.hostname, inputs.gitToken);
|
||||||
|
const ghPull = new github_helper_1.GitHubHelper(baseRemote.hostname, inputs.token);
|
||||||
// Determine the head repository; the target for the pull request branch
|
// Determine the head repository; the target for the pull request branch
|
||||||
const branchRemoteName = inputs.pushToFork ? 'fork' : 'origin';
|
const branchRemoteName = inputs.pushToFork ? 'fork' : 'origin';
|
||||||
const branchRepository = inputs.pushToFork
|
const branchRepository = inputs.pushToFork
|
||||||
@@ -366,8 +367,8 @@ function createPullRequest(inputs) {
|
|||||||
if (inputs.pushToFork) {
|
if (inputs.pushToFork) {
|
||||||
// Check if the supplied fork is really a fork of the base
|
// Check if the supplied fork is really a fork of the base
|
||||||
core.info(`Checking if '${branchRepository}' is a fork of '${baseRemote.repository}'`);
|
core.info(`Checking if '${branchRepository}' is a fork of '${baseRemote.repository}'`);
|
||||||
const baseParentRepository = yield githubHelper.getRepositoryParent(baseRemote.repository);
|
const baseParentRepository = yield ghBranch.getRepositoryParent(baseRemote.repository);
|
||||||
const branchParentRepository = yield githubHelper.getRepositoryParent(branchRepository);
|
const branchParentRepository = yield ghBranch.getRepositoryParent(branchRepository);
|
||||||
if (branchParentRepository == null) {
|
if (branchParentRepository == null) {
|
||||||
throw new Error(`Repository '${branchRepository}' is not a fork. Unable to continue.`);
|
throw new Error(`Repository '${branchRepository}' is not a fork. Unable to continue.`);
|
||||||
}
|
}
|
||||||
@@ -450,9 +451,15 @@ function createPullRequest(inputs) {
|
|||||||
core.info(`Configured git committer as '${parsedCommitter.name} <${parsedCommitter.email}>'`);
|
core.info(`Configured git committer as '${parsedCommitter.name} <${parsedCommitter.email}>'`);
|
||||||
core.info(`Configured git author as '${parsedAuthor.name} <${parsedAuthor.email}>'`);
|
core.info(`Configured git author as '${parsedAuthor.name} <${parsedAuthor.email}>'`);
|
||||||
core.endGroup();
|
core.endGroup();
|
||||||
|
// Action outputs
|
||||||
|
const outputs = new Map();
|
||||||
|
outputs.set('pull-request-branch', inputs.branch);
|
||||||
|
outputs.set('pull-request-operation', 'none');
|
||||||
|
outputs.set('pull-request-commits-verified', 'false');
|
||||||
// Create or update the pull request branch
|
// Create or update the pull request branch
|
||||||
core.startGroup('Create or update the pull request branch');
|
core.startGroup('Create or update the pull request branch');
|
||||||
const result = yield (0, create_or_update_branch_1.createOrUpdateBranch)(git, inputs.commitMessage, inputs.base, inputs.branch, branchRemoteName, inputs.signoff, inputs.addPaths, inputs.signCommits);
|
const result = yield (0, create_or_update_branch_1.createOrUpdateBranch)(git, inputs.commitMessage, inputs.base, inputs.branch, branchRemoteName, inputs.signoff, inputs.addPaths, inputs.signCommits);
|
||||||
|
outputs.set('pull-request-head-sha', result.headSha);
|
||||||
// Set the base. It would have been '' if not specified as an input
|
// Set the base. It would have been '' if not specified as an input
|
||||||
inputs.base = result.base;
|
inputs.base = result.base;
|
||||||
core.endGroup();
|
core.endGroup();
|
||||||
@@ -463,7 +470,9 @@ function createPullRequest(inputs) {
|
|||||||
// Create signed commits via the GitHub API
|
// Create signed commits via the GitHub API
|
||||||
const stashed = yield git.stashPush(['--include-untracked']);
|
const stashed = yield git.stashPush(['--include-untracked']);
|
||||||
yield git.checkout(inputs.branch);
|
yield git.checkout(inputs.branch);
|
||||||
yield githubHelper.pushSignedCommits(result.branchCommits, result.baseSha, repoPath, branchRepository, inputs.branch);
|
const pushSignedCommitsResult = yield ghBranch.pushSignedCommits(result.branchCommits, result.baseSha, repoPath, branchRepository, inputs.branch);
|
||||||
|
outputs.set('pull-request-head-sha', pushSignedCommitsResult.sha);
|
||||||
|
outputs.set('pull-request-commits-verified', pushSignedCommitsResult.verified.toString());
|
||||||
yield git.checkout('-');
|
yield git.checkout('-');
|
||||||
if (stashed) {
|
if (stashed) {
|
||||||
yield git.stashPop();
|
yield git.stashPop();
|
||||||
@@ -479,22 +488,16 @@ function createPullRequest(inputs) {
|
|||||||
core.endGroup();
|
core.endGroup();
|
||||||
}
|
}
|
||||||
if (result.hasDiffWithBase) {
|
if (result.hasDiffWithBase) {
|
||||||
// Create or update the pull request
|
|
||||||
core.startGroup('Create or update the pull request');
|
core.startGroup('Create or update the pull request');
|
||||||
const pull = yield githubHelper.createOrUpdatePullRequest(inputs, baseRemote.repository, branchRepository);
|
const pull = yield ghPull.createOrUpdatePullRequest(inputs, baseRemote.repository, branchRepository);
|
||||||
core.endGroup();
|
outputs.set('pull-request-number', pull.number.toString());
|
||||||
// Set outputs
|
outputs.set('pull-request-url', pull.html_url);
|
||||||
core.startGroup('Setting outputs');
|
|
||||||
core.setOutput('pull-request-number', pull.number);
|
|
||||||
core.setOutput('pull-request-url', pull.html_url);
|
|
||||||
if (pull.created) {
|
if (pull.created) {
|
||||||
core.setOutput('pull-request-operation', 'created');
|
outputs.set('pull-request-operation', 'created');
|
||||||
}
|
}
|
||||||
else if (result.action == 'updated') {
|
else if (result.action == 'updated') {
|
||||||
core.setOutput('pull-request-operation', 'updated');
|
outputs.set('pull-request-operation', 'updated');
|
||||||
}
|
}
|
||||||
core.setOutput('pull-request-head-sha', result.headSha);
|
|
||||||
core.setOutput('pull-request-branch', inputs.branch);
|
|
||||||
// Deprecated
|
// Deprecated
|
||||||
core.exportVariable('PULL_REQUEST_NUMBER', pull.number);
|
core.exportVariable('PULL_REQUEST_NUMBER', pull.number);
|
||||||
core.endGroup();
|
core.endGroup();
|
||||||
@@ -512,13 +515,17 @@ function createPullRequest(inputs) {
|
|||||||
branchRemoteName,
|
branchRemoteName,
|
||||||
`refs/heads/${inputs.branch}`
|
`refs/heads/${inputs.branch}`
|
||||||
]);
|
]);
|
||||||
// Set outputs
|
outputs.set('pull-request-operation', 'closed');
|
||||||
core.startGroup('Setting outputs');
|
|
||||||
core.setOutput('pull-request-operation', 'closed');
|
|
||||||
core.endGroup();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Set outputs
|
||||||
|
core.startGroup('Setting outputs');
|
||||||
|
for (const [key, value] of outputs) {
|
||||||
|
core.info(`${key} = ${value}`);
|
||||||
|
core.setOutput(key, value);
|
||||||
|
}
|
||||||
|
core.endGroup();
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
core.setFailed(utils.getErrorMessage(error));
|
core.setFailed(utils.getErrorMessage(error));
|
||||||
@@ -1162,7 +1169,9 @@ const core = __importStar(__nccwpck_require__(2186));
|
|||||||
const octokit_client_1 = __nccwpck_require__(5040);
|
const octokit_client_1 = __nccwpck_require__(5040);
|
||||||
const p_limit_1 = __importDefault(__nccwpck_require__(3783));
|
const p_limit_1 = __importDefault(__nccwpck_require__(3783));
|
||||||
const utils = __importStar(__nccwpck_require__(918));
|
const utils = __importStar(__nccwpck_require__(918));
|
||||||
|
const ERROR_PR_ALREADY_EXISTS = 'A pull request already exists for';
|
||||||
const ERROR_PR_REVIEW_TOKEN_SCOPE = 'Validation Failed: "Could not resolve to a node with the global id of';
|
const ERROR_PR_REVIEW_TOKEN_SCOPE = 'Validation Failed: "Could not resolve to a node with the global id of';
|
||||||
|
const ERROR_PR_FORK_COLLAB = `Fork collab can't be granted by someone without permission`;
|
||||||
const blobCreationLimit = (0, p_limit_1.default)(8);
|
const blobCreationLimit = (0, p_limit_1.default)(8);
|
||||||
class GitHubHelper {
|
class GitHubHelper {
|
||||||
constructor(githubServerHostname, token) {
|
constructor(githubServerHostname, token) {
|
||||||
@@ -1193,7 +1202,7 @@ class GitHubHelper {
|
|||||||
// Try to create the pull request
|
// Try to create the pull request
|
||||||
try {
|
try {
|
||||||
core.info(`Attempting creation of pull request`);
|
core.info(`Attempting creation of pull request`);
|
||||||
const { data: pull } = yield this.octokit.rest.pulls.create(Object.assign(Object.assign({}, this.parseRepository(baseRepository)), { title: inputs.title, head: headBranch, head_repo: headRepository, base: inputs.base, body: inputs.body, draft: inputs.draft }));
|
const { data: pull } = yield this.octokit.rest.pulls.create(Object.assign(Object.assign({}, this.parseRepository(baseRepository)), { title: inputs.title, head: headBranch, head_repo: headRepository, base: inputs.base, body: inputs.body, draft: inputs.draft, maintainer_can_modify: inputs.maintainerCanModify }));
|
||||||
core.info(`Created pull request #${pull.number} (${headBranch} => ${inputs.base})`);
|
core.info(`Created pull request #${pull.number} (${headBranch} => ${inputs.base})`);
|
||||||
return {
|
return {
|
||||||
number: pull.number,
|
number: pull.number,
|
||||||
@@ -1202,9 +1211,15 @@ class GitHubHelper {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
if (utils.getErrorMessage(e).includes(`A pull request already exists for`)) {
|
const errorMessage = utils.getErrorMessage(e);
|
||||||
|
if (errorMessage.includes(ERROR_PR_ALREADY_EXISTS)) {
|
||||||
core.info(`A pull request already exists for ${headBranch}`);
|
core.info(`A pull request already exists for ${headBranch}`);
|
||||||
}
|
}
|
||||||
|
else if (errorMessage.includes(ERROR_PR_FORK_COLLAB)) {
|
||||||
|
core.warning('An attempt was made to create a pull request using a token that does not have write access to the head branch.');
|
||||||
|
core.warning(`For this case, set input 'maintainer-can-modify' to 'false' to allow pull request creation.`);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
@@ -1277,11 +1292,15 @@ class GitHubHelper {
|
|||||||
}
|
}
|
||||||
pushSignedCommits(branchCommits, baseSha, repoPath, branchRepository, branch) {
|
pushSignedCommits(branchCommits, baseSha, repoPath, branchRepository, branch) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
let headSha = baseSha;
|
let headCommit = {
|
||||||
|
sha: baseSha,
|
||||||
|
verified: false
|
||||||
|
};
|
||||||
for (const commit of branchCommits) {
|
for (const commit of branchCommits) {
|
||||||
headSha = yield this.createCommit(commit, [headSha], repoPath, branchRepository);
|
headCommit = yield this.createCommit(commit, [headCommit.sha], repoPath, branchRepository);
|
||||||
}
|
}
|
||||||
yield this.createOrUpdateRef(branchRepository, branch, headSha);
|
yield this.createOrUpdateRef(branchRepository, branch, headCommit.sha);
|
||||||
|
return headCommit;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
createCommit(commit, parents, repoPath, branchRepository) {
|
createCommit(commit, parents, repoPath, branchRepository) {
|
||||||
@@ -1312,7 +1331,10 @@ class GitHubHelper {
|
|||||||
const { data: remoteCommit } = yield this.octokit.rest.git.createCommit(Object.assign(Object.assign({}, repository), { parents: parents, tree: treeSha, message: `${commit.subject}\n\n${commit.body}` }));
|
const { data: remoteCommit } = yield this.octokit.rest.git.createCommit(Object.assign(Object.assign({}, repository), { parents: parents, tree: treeSha, message: `${commit.subject}\n\n${commit.body}` }));
|
||||||
core.info(`Created commit ${remoteCommit.sha} for local commit ${commit.sha}`);
|
core.info(`Created commit ${remoteCommit.sha} for local commit ${commit.sha}`);
|
||||||
core.info(`Commit verified: ${remoteCommit.verification.verified}; reason: ${remoteCommit.verification.reason}`);
|
core.info(`Commit verified: ${remoteCommit.verification.verified}; reason: ${remoteCommit.verification.reason}`);
|
||||||
return remoteCommit.sha;
|
return {
|
||||||
|
sha: remoteCommit.sha,
|
||||||
|
verified: remoteCommit.verification.verified
|
||||||
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
createOrUpdateRef(branchRepository, branch, newHead) {
|
createOrUpdateRef(branchRepository, branch, newHead) {
|
||||||
@@ -1405,7 +1427,8 @@ function run() {
|
|||||||
reviewers: utils.getInputAsArray('reviewers'),
|
reviewers: utils.getInputAsArray('reviewers'),
|
||||||
teamReviewers: utils.getInputAsArray('team-reviewers'),
|
teamReviewers: utils.getInputAsArray('team-reviewers'),
|
||||||
milestone: Number(core.getInput('milestone')),
|
milestone: Number(core.getInput('milestone')),
|
||||||
draft: core.getBooleanInput('draft')
|
draft: core.getBooleanInput('draft'),
|
||||||
|
maintainerCanModify: core.getBooleanInput('maintainer-can-modify')
|
||||||
};
|
};
|
||||||
core.debug(`Inputs: ${(0, util_1.inspect)(inputs)}`);
|
core.debug(`Inputs: ${(0, util_1.inspect)(inputs)}`);
|
||||||
if (!inputs.token) {
|
if (!inputs.token) {
|
||||||
@@ -1485,8 +1508,9 @@ exports.throttleOptions = {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSecondaryRateLimit: (_, options) => {
|
onSecondaryRateLimit: (retryAfter, options) => {
|
||||||
core.warning(`Hit secondary rate limit for request ${options.method} ${options.url}`);
|
core.warning(`Hit secondary rate limit for request ${options.method} ${options.url}`);
|
||||||
|
core.warning(`Requests may be retried after ${retryAfter} seconds.`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const proxyFetch = (proxyUrl) => (url, opts) => {
|
const proxyFetch = (proxyUrl) => (url, opts) => {
|
||||||
|
@@ -33,6 +33,7 @@ export interface Inputs {
|
|||||||
teamReviewers: string[]
|
teamReviewers: string[]
|
||||||
milestone: number
|
milestone: number
|
||||||
draft: boolean
|
draft: boolean
|
||||||
|
maintainerCanModify: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createPullRequest(inputs: Inputs): Promise<void> {
|
export async function createPullRequest(inputs: Inputs): Promise<void> {
|
||||||
@@ -46,8 +47,9 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
|
|||||||
|
|
||||||
core.startGroup('Determining the base and head repositories')
|
core.startGroup('Determining the base and head repositories')
|
||||||
const baseRemote = gitConfigHelper.getGitRemote()
|
const baseRemote = gitConfigHelper.getGitRemote()
|
||||||
// Init the GitHub client
|
// Init the GitHub clients
|
||||||
const githubHelper = new GitHubHelper(baseRemote.hostname, inputs.token)
|
const ghBranch = new GitHubHelper(baseRemote.hostname, inputs.gitToken)
|
||||||
|
const ghPull = new GitHubHelper(baseRemote.hostname, inputs.token)
|
||||||
// Determine the head repository; the target for the pull request branch
|
// Determine the head repository; the target for the pull request branch
|
||||||
const branchRemoteName = inputs.pushToFork ? 'fork' : 'origin'
|
const branchRemoteName = inputs.pushToFork ? 'fork' : 'origin'
|
||||||
const branchRepository = inputs.pushToFork
|
const branchRepository = inputs.pushToFork
|
||||||
@@ -58,11 +60,11 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
|
|||||||
core.info(
|
core.info(
|
||||||
`Checking if '${branchRepository}' is a fork of '${baseRemote.repository}'`
|
`Checking if '${branchRepository}' is a fork of '${baseRemote.repository}'`
|
||||||
)
|
)
|
||||||
const baseParentRepository = await githubHelper.getRepositoryParent(
|
const baseParentRepository = await ghBranch.getRepositoryParent(
|
||||||
baseRemote.repository
|
baseRemote.repository
|
||||||
)
|
)
|
||||||
const branchParentRepository =
|
const branchParentRepository =
|
||||||
await githubHelper.getRepositoryParent(branchRepository)
|
await ghBranch.getRepositoryParent(branchRepository)
|
||||||
if (branchParentRepository == null) {
|
if (branchParentRepository == null) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Repository '${branchRepository}' is not a fork. Unable to continue.`
|
`Repository '${branchRepository}' is not a fork. Unable to continue.`
|
||||||
@@ -175,6 +177,12 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
|
|||||||
)
|
)
|
||||||
core.endGroup()
|
core.endGroup()
|
||||||
|
|
||||||
|
// Action outputs
|
||||||
|
const outputs = new Map<string, string>()
|
||||||
|
outputs.set('pull-request-branch', inputs.branch)
|
||||||
|
outputs.set('pull-request-operation', 'none')
|
||||||
|
outputs.set('pull-request-commits-verified', 'false')
|
||||||
|
|
||||||
// Create or update the pull request branch
|
// Create or update the pull request branch
|
||||||
core.startGroup('Create or update the pull request branch')
|
core.startGroup('Create or update the pull request branch')
|
||||||
const result = await createOrUpdateBranch(
|
const result = await createOrUpdateBranch(
|
||||||
@@ -187,6 +195,7 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
|
|||||||
inputs.addPaths,
|
inputs.addPaths,
|
||||||
inputs.signCommits
|
inputs.signCommits
|
||||||
)
|
)
|
||||||
|
outputs.set('pull-request-head-sha', result.headSha)
|
||||||
// Set the base. It would have been '' if not specified as an input
|
// Set the base. It would have been '' if not specified as an input
|
||||||
inputs.base = result.base
|
inputs.base = result.base
|
||||||
core.endGroup()
|
core.endGroup()
|
||||||
@@ -200,13 +209,18 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
|
|||||||
// Create signed commits via the GitHub API
|
// Create signed commits via the GitHub API
|
||||||
const stashed = await git.stashPush(['--include-untracked'])
|
const stashed = await git.stashPush(['--include-untracked'])
|
||||||
await git.checkout(inputs.branch)
|
await git.checkout(inputs.branch)
|
||||||
await githubHelper.pushSignedCommits(
|
const pushSignedCommitsResult = await ghBranch.pushSignedCommits(
|
||||||
result.branchCommits,
|
result.branchCommits,
|
||||||
result.baseSha,
|
result.baseSha,
|
||||||
repoPath,
|
repoPath,
|
||||||
branchRepository,
|
branchRepository,
|
||||||
inputs.branch
|
inputs.branch
|
||||||
)
|
)
|
||||||
|
outputs.set('pull-request-head-sha', pushSignedCommitsResult.sha)
|
||||||
|
outputs.set(
|
||||||
|
'pull-request-commits-verified',
|
||||||
|
pushSignedCommitsResult.verified.toString()
|
||||||
|
)
|
||||||
await git.checkout('-')
|
await git.checkout('-')
|
||||||
if (stashed) {
|
if (stashed) {
|
||||||
await git.stashPop()
|
await git.stashPop()
|
||||||
@@ -222,26 +236,19 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result.hasDiffWithBase) {
|
if (result.hasDiffWithBase) {
|
||||||
// Create or update the pull request
|
|
||||||
core.startGroup('Create or update the pull request')
|
core.startGroup('Create or update the pull request')
|
||||||
const pull = await githubHelper.createOrUpdatePullRequest(
|
const pull = await ghPull.createOrUpdatePullRequest(
|
||||||
inputs,
|
inputs,
|
||||||
baseRemote.repository,
|
baseRemote.repository,
|
||||||
branchRepository
|
branchRepository
|
||||||
)
|
)
|
||||||
core.endGroup()
|
outputs.set('pull-request-number', pull.number.toString())
|
||||||
|
outputs.set('pull-request-url', pull.html_url)
|
||||||
// Set outputs
|
|
||||||
core.startGroup('Setting outputs')
|
|
||||||
core.setOutput('pull-request-number', pull.number)
|
|
||||||
core.setOutput('pull-request-url', pull.html_url)
|
|
||||||
if (pull.created) {
|
if (pull.created) {
|
||||||
core.setOutput('pull-request-operation', 'created')
|
outputs.set('pull-request-operation', 'created')
|
||||||
} else if (result.action == 'updated') {
|
} else if (result.action == 'updated') {
|
||||||
core.setOutput('pull-request-operation', 'updated')
|
outputs.set('pull-request-operation', 'updated')
|
||||||
}
|
}
|
||||||
core.setOutput('pull-request-head-sha', result.headSha)
|
|
||||||
core.setOutput('pull-request-branch', inputs.branch)
|
|
||||||
// Deprecated
|
// Deprecated
|
||||||
core.exportVariable('PULL_REQUEST_NUMBER', pull.number)
|
core.exportVariable('PULL_REQUEST_NUMBER', pull.number)
|
||||||
core.endGroup()
|
core.endGroup()
|
||||||
@@ -260,13 +267,18 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
|
|||||||
branchRemoteName,
|
branchRemoteName,
|
||||||
`refs/heads/${inputs.branch}`
|
`refs/heads/${inputs.branch}`
|
||||||
])
|
])
|
||||||
// Set outputs
|
outputs.set('pull-request-operation', 'closed')
|
||||||
core.startGroup('Setting outputs')
|
|
||||||
core.setOutput('pull-request-operation', 'closed')
|
|
||||||
core.endGroup()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set outputs
|
||||||
|
core.startGroup('Setting outputs')
|
||||||
|
for (const [key, value] of outputs) {
|
||||||
|
core.info(`${key} = ${value}`)
|
||||||
|
core.setOutput(key, value)
|
||||||
|
}
|
||||||
|
core.endGroup()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(utils.getErrorMessage(error))
|
core.setFailed(utils.getErrorMessage(error))
|
||||||
} finally {
|
} finally {
|
||||||
|
@@ -5,8 +5,10 @@ import {Octokit, OctokitOptions, throttleOptions} from './octokit-client'
|
|||||||
import pLimit from 'p-limit'
|
import pLimit from 'p-limit'
|
||||||
import * as utils from './utils'
|
import * as utils from './utils'
|
||||||
|
|
||||||
|
const ERROR_PR_ALREADY_EXISTS = 'A pull request already exists for'
|
||||||
const ERROR_PR_REVIEW_TOKEN_SCOPE =
|
const ERROR_PR_REVIEW_TOKEN_SCOPE =
|
||||||
'Validation Failed: "Could not resolve to a node with the global id of'
|
'Validation Failed: "Could not resolve to a node with the global id of'
|
||||||
|
const ERROR_PR_FORK_COLLAB = `Fork collab can't be granted by someone without permission`
|
||||||
|
|
||||||
const blobCreationLimit = pLimit(8)
|
const blobCreationLimit = pLimit(8)
|
||||||
|
|
||||||
@@ -21,6 +23,11 @@ interface Pull {
|
|||||||
created: boolean
|
created: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface CommitResponse {
|
||||||
|
sha: string
|
||||||
|
verified: boolean
|
||||||
|
}
|
||||||
|
|
||||||
type TreeObject = {
|
type TreeObject = {
|
||||||
path: string
|
path: string
|
||||||
mode: '100644' | '100755' | '040000' | '160000' | '120000'
|
mode: '100644' | '100755' | '040000' | '160000' | '120000'
|
||||||
@@ -71,7 +78,8 @@ export class GitHubHelper {
|
|||||||
head_repo: headRepository,
|
head_repo: headRepository,
|
||||||
base: inputs.base,
|
base: inputs.base,
|
||||||
body: inputs.body,
|
body: inputs.body,
|
||||||
draft: inputs.draft
|
draft: inputs.draft,
|
||||||
|
maintainer_can_modify: inputs.maintainerCanModify
|
||||||
})
|
})
|
||||||
core.info(
|
core.info(
|
||||||
`Created pull request #${pull.number} (${headBranch} => ${inputs.base})`
|
`Created pull request #${pull.number} (${headBranch} => ${inputs.base})`
|
||||||
@@ -82,10 +90,17 @@ export class GitHubHelper {
|
|||||||
created: true
|
created: true
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (
|
const errorMessage = utils.getErrorMessage(e)
|
||||||
utils.getErrorMessage(e).includes(`A pull request already exists for`)
|
if (errorMessage.includes(ERROR_PR_ALREADY_EXISTS)) {
|
||||||
) {
|
|
||||||
core.info(`A pull request already exists for ${headBranch}`)
|
core.info(`A pull request already exists for ${headBranch}`)
|
||||||
|
} else if (errorMessage.includes(ERROR_PR_FORK_COLLAB)) {
|
||||||
|
core.warning(
|
||||||
|
'An attempt was made to create a pull request using a token that does not have write access to the head branch.'
|
||||||
|
)
|
||||||
|
core.warning(
|
||||||
|
`For this case, set input 'maintainer-can-modify' to 'false' to allow pull request creation.`
|
||||||
|
)
|
||||||
|
throw e
|
||||||
} else {
|
} else {
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
@@ -203,17 +218,21 @@ export class GitHubHelper {
|
|||||||
repoPath: string,
|
repoPath: string,
|
||||||
branchRepository: string,
|
branchRepository: string,
|
||||||
branch: string
|
branch: string
|
||||||
): Promise<void> {
|
): Promise<CommitResponse> {
|
||||||
let headSha = baseSha
|
let headCommit: CommitResponse = {
|
||||||
|
sha: baseSha,
|
||||||
|
verified: false
|
||||||
|
}
|
||||||
for (const commit of branchCommits) {
|
for (const commit of branchCommits) {
|
||||||
headSha = await this.createCommit(
|
headCommit = await this.createCommit(
|
||||||
commit,
|
commit,
|
||||||
[headSha],
|
[headCommit.sha],
|
||||||
repoPath,
|
repoPath,
|
||||||
branchRepository
|
branchRepository
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
await this.createOrUpdateRef(branchRepository, branch, headSha)
|
await this.createOrUpdateRef(branchRepository, branch, headCommit.sha)
|
||||||
|
return headCommit
|
||||||
}
|
}
|
||||||
|
|
||||||
private async createCommit(
|
private async createCommit(
|
||||||
@@ -221,7 +240,7 @@ export class GitHubHelper {
|
|||||||
parents: string[],
|
parents: string[],
|
||||||
repoPath: string,
|
repoPath: string,
|
||||||
branchRepository: string
|
branchRepository: string
|
||||||
): Promise<string> {
|
): Promise<CommitResponse> {
|
||||||
const repository = this.parseRepository(branchRepository)
|
const repository = this.parseRepository(branchRepository)
|
||||||
let treeSha = commit.tree
|
let treeSha = commit.tree
|
||||||
if (commit.changes.length > 0) {
|
if (commit.changes.length > 0) {
|
||||||
@@ -270,7 +289,10 @@ export class GitHubHelper {
|
|||||||
core.info(
|
core.info(
|
||||||
`Commit verified: ${remoteCommit.verification.verified}; reason: ${remoteCommit.verification.reason}`
|
`Commit verified: ${remoteCommit.verification.verified}; reason: ${remoteCommit.verification.reason}`
|
||||||
)
|
)
|
||||||
return remoteCommit.sha
|
return {
|
||||||
|
sha: remoteCommit.sha,
|
||||||
|
verified: remoteCommit.verification.verified
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async createOrUpdateRef(
|
private async createOrUpdateRef(
|
||||||
|
@@ -28,7 +28,8 @@ async function run(): Promise<void> {
|
|||||||
reviewers: utils.getInputAsArray('reviewers'),
|
reviewers: utils.getInputAsArray('reviewers'),
|
||||||
teamReviewers: utils.getInputAsArray('team-reviewers'),
|
teamReviewers: utils.getInputAsArray('team-reviewers'),
|
||||||
milestone: Number(core.getInput('milestone')),
|
milestone: Number(core.getInput('milestone')),
|
||||||
draft: core.getBooleanInput('draft')
|
draft: core.getBooleanInput('draft'),
|
||||||
|
maintainerCanModify: core.getBooleanInput('maintainer-can-modify')
|
||||||
}
|
}
|
||||||
core.debug(`Inputs: ${inspect(inputs)}`)
|
core.debug(`Inputs: ${inspect(inputs)}`)
|
||||||
|
|
||||||
|
@@ -25,10 +25,11 @@ export const throttleOptions = {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSecondaryRateLimit: (_, options) => {
|
onSecondaryRateLimit: (retryAfter, options) => {
|
||||||
core.warning(
|
core.warning(
|
||||||
`Hit secondary rate limit for request ${options.method} ${options.url}`
|
`Hit secondary rate limit for request ${options.method} ${options.url}`
|
||||||
)
|
)
|
||||||
|
core.warning(`Requests may be retried after ${retryAfter} seconds.`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user