Adds createWhenEmpty option to publish:github:pull-request action
Signed-off-by: Tanner Juedeman <tbjuedeman@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-github': patch
|
||||
---
|
||||
|
||||
Adds `createWhenEmpty` option to `publish:github:pull-request` action.
|
||||
+50
-8
@@ -617,13 +617,7 @@ describe('publish:github:pull-request examples', () => {
|
||||
expect(mockContext.output).toHaveBeenCalledWith('pullRequestNumber', 123);
|
||||
});
|
||||
|
||||
it('Create a pull request with all parameters', async () => {
|
||||
mockDir.setContent({
|
||||
[workspacePath]: {
|
||||
source: { 'foo.txt': 'Hello there!' },
|
||||
irrelevant: { 'bar.txt': 'Nothing to see here' },
|
||||
},
|
||||
});
|
||||
it('Does not create an empty pull request', async () => {
|
||||
const input = yaml.parse(examples[12].example).steps[0].input;
|
||||
|
||||
await action.handler({
|
||||
@@ -638,8 +632,56 @@ describe('publish:github:pull-request examples', () => {
|
||||
title: 'Create my new app',
|
||||
body: 'This PR is really good',
|
||||
head: 'new-app',
|
||||
draft: true,
|
||||
draft: undefined,
|
||||
createWhenEmpty: false,
|
||||
changes: [
|
||||
{
|
||||
commit: 'Create my new app',
|
||||
files: {
|
||||
'file.txt': {
|
||||
content: Buffer.from('Hello there!').toString('base64'),
|
||||
encoding: 'base64',
|
||||
mode: '100644',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expect(fakeClient.rest.pulls.requestReviewers).not.toHaveBeenCalled();
|
||||
expect(mockContext.output).toHaveBeenCalledTimes(3);
|
||||
expect(mockContext.output).toHaveBeenCalledWith('targetBranchName', 'main');
|
||||
expect(mockContext.output).toHaveBeenCalledWith(
|
||||
'remoteUrl',
|
||||
'https://github.com/myorg/myrepo/pull/123',
|
||||
);
|
||||
expect(mockContext.output).toHaveBeenCalledWith('pullRequestNumber', 123);
|
||||
});
|
||||
|
||||
it('Create a pull request with all parameters', async () => {
|
||||
mockDir.setContent({
|
||||
[workspacePath]: {
|
||||
source: { 'foo.txt': 'Hello there!' },
|
||||
irrelevant: { 'bar.txt': 'Nothing to see here' },
|
||||
},
|
||||
});
|
||||
const input = yaml.parse(examples[13].example).steps[0].input;
|
||||
|
||||
await action.handler({
|
||||
...mockContext,
|
||||
workspacePath,
|
||||
input,
|
||||
});
|
||||
|
||||
expect(fakeClient.createPullRequest).toHaveBeenCalledWith({
|
||||
owner: 'owner',
|
||||
repo: 'repo',
|
||||
title: 'Create my new app',
|
||||
body: 'This PR is really good',
|
||||
head: 'new-app',
|
||||
base: 'test',
|
||||
draft: true,
|
||||
createWhenEmpty: true,
|
||||
changes: [
|
||||
{
|
||||
commit: 'Commit for foo changes',
|
||||
|
||||
+32
-13
@@ -23,7 +23,7 @@ export const examples: TemplateExample[] = [
|
||||
steps: [
|
||||
{
|
||||
action: 'publish:github:pull-request',
|
||||
name: 'Create a pull reuqest',
|
||||
name: 'Create a pull request',
|
||||
input: {
|
||||
repoUrl: 'github.com?repo=repo&owner=owner',
|
||||
branchName: 'new-app',
|
||||
@@ -40,7 +40,7 @@ export const examples: TemplateExample[] = [
|
||||
steps: [
|
||||
{
|
||||
action: 'publish:github:pull-request',
|
||||
name: 'Create a pull reuqest with target branch name',
|
||||
name: 'Create a pull request with target branch name',
|
||||
input: {
|
||||
repoUrl: 'github.com?repo=repo&owner=owner',
|
||||
branchName: 'new-app',
|
||||
@@ -58,7 +58,7 @@ export const examples: TemplateExample[] = [
|
||||
steps: [
|
||||
{
|
||||
action: 'publish:github:pull-request',
|
||||
name: 'Create a pull reuqest as draft',
|
||||
name: 'Create a pull request as draft',
|
||||
input: {
|
||||
repoUrl: 'github.com?repo=repo&owner=owner',
|
||||
branchName: 'new-app',
|
||||
@@ -76,7 +76,7 @@ export const examples: TemplateExample[] = [
|
||||
steps: [
|
||||
{
|
||||
action: 'publish:github:pull-request',
|
||||
name: 'Create a pull reuqest with target path',
|
||||
name: 'Create a pull request with target path',
|
||||
input: {
|
||||
repoUrl: 'github.com?repo=repo&owner=owner',
|
||||
branchName: 'new-app',
|
||||
@@ -94,7 +94,7 @@ export const examples: TemplateExample[] = [
|
||||
steps: [
|
||||
{
|
||||
action: 'publish:github:pull-request',
|
||||
name: 'Create a pull reuqest with source path',
|
||||
name: 'Create a pull request with source path',
|
||||
input: {
|
||||
repoUrl: 'github.com?repo=repo&owner=owner',
|
||||
branchName: 'new-app',
|
||||
@@ -112,7 +112,7 @@ export const examples: TemplateExample[] = [
|
||||
steps: [
|
||||
{
|
||||
action: 'publish:github:pull-request',
|
||||
name: 'Create a pull reuqest',
|
||||
name: 'Create a pull request',
|
||||
input: {
|
||||
repoUrl: 'github.com?repo=repo&owner=owner',
|
||||
branchName: 'new-app',
|
||||
@@ -130,7 +130,7 @@ export const examples: TemplateExample[] = [
|
||||
steps: [
|
||||
{
|
||||
action: 'publish:github:pull-request',
|
||||
name: 'Create a pull reuqest with reviewers',
|
||||
name: 'Create a pull request with reviewers',
|
||||
input: {
|
||||
repoUrl: 'github.com?repo=repo&owner=owner',
|
||||
branchName: 'new-app',
|
||||
@@ -148,7 +148,7 @@ export const examples: TemplateExample[] = [
|
||||
steps: [
|
||||
{
|
||||
action: 'publish:github:pull-request',
|
||||
name: 'Create a pull reuqest with team reviewers',
|
||||
name: 'Create a pull request with team reviewers',
|
||||
input: {
|
||||
repoUrl: 'github.com?repo=repo&owner=owner',
|
||||
branchName: 'new-app',
|
||||
@@ -166,7 +166,7 @@ export const examples: TemplateExample[] = [
|
||||
steps: [
|
||||
{
|
||||
action: 'publish:github:pull-request',
|
||||
name: 'Create a pull reuqest',
|
||||
name: 'Create a pull request',
|
||||
input: {
|
||||
repoUrl: 'github.com?repo=repo&owner=owner',
|
||||
branchName: 'new-app',
|
||||
@@ -184,7 +184,7 @@ export const examples: TemplateExample[] = [
|
||||
steps: [
|
||||
{
|
||||
action: 'publish:github:pull-request',
|
||||
name: 'Create a pull reuqest',
|
||||
name: 'Create a pull request',
|
||||
input: {
|
||||
repoUrl: 'github.com?repo=repo&owner=owner',
|
||||
branchName: 'new-app',
|
||||
@@ -203,7 +203,7 @@ export const examples: TemplateExample[] = [
|
||||
steps: [
|
||||
{
|
||||
action: 'publish:github:pull-request',
|
||||
name: 'Create a pull reuqest',
|
||||
name: 'Create a pull request',
|
||||
input: {
|
||||
repoUrl: 'github.com?repo=repo&owner=owner',
|
||||
branchName: 'new-app',
|
||||
@@ -223,7 +223,7 @@ export const examples: TemplateExample[] = [
|
||||
steps: [
|
||||
{
|
||||
action: 'publish:github:pull-request',
|
||||
name: 'Create a pull reuqest',
|
||||
name: 'Create a pull request',
|
||||
input: {
|
||||
repoUrl: 'github.com?repo=repo&owner=owner',
|
||||
branchName: 'new-app',
|
||||
@@ -237,13 +237,31 @@ export const examples: TemplateExample[] = [
|
||||
],
|
||||
}),
|
||||
},
|
||||
{
|
||||
description: 'Do not create empty pull request',
|
||||
example: yaml.stringify({
|
||||
steps: [
|
||||
{
|
||||
action: 'publish:github:pull-request',
|
||||
name: 'Create a pull request',
|
||||
input: {
|
||||
repoUrl: 'github.com?repo=repo&owner=owner',
|
||||
branchName: 'new-app',
|
||||
title: 'Create my new app',
|
||||
description: 'This PR is really good',
|
||||
createWhenEmpty: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
{
|
||||
description: 'Create a pull request with all parameters',
|
||||
example: yaml.stringify({
|
||||
steps: [
|
||||
{
|
||||
action: 'publish:github:pull-request',
|
||||
name: 'Create a pull reuqest',
|
||||
name: 'Create a pull request',
|
||||
input: {
|
||||
repoUrl: 'github.com?repo=repo&owner=owner',
|
||||
branchName: 'new-app',
|
||||
@@ -259,6 +277,7 @@ export const examples: TemplateExample[] = [
|
||||
commitMessage: 'Commit for foo changes',
|
||||
gitAuthorName: 'Foo Bar',
|
||||
gitAuthorEmail: 'foo@bar.example',
|
||||
createWhenEmpty: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1062,4 +1062,119 @@ describe('createPublishGithubPullRequestAction', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with createWhenEmpty equals true', () => {
|
||||
let input: GithubPullRequestActionInput;
|
||||
let ctx: ActionContext<GithubPullRequestActionInput>;
|
||||
|
||||
beforeEach(() => {
|
||||
input = {
|
||||
repoUrl: 'github.com?owner=myorg&repo=myrepo',
|
||||
title: 'Create my new app',
|
||||
branchName: 'new-app',
|
||||
description: 'This PR is really good',
|
||||
createWhenEmpty: true,
|
||||
};
|
||||
|
||||
mockDir.setContent({
|
||||
[workspacePath]: { 'file.txt': 'Hello there!' },
|
||||
});
|
||||
|
||||
ctx = createMockActionContext({ input, workspacePath });
|
||||
});
|
||||
it('creates a pull request', async () => {
|
||||
await instance.handler(ctx);
|
||||
|
||||
expect(fakeClient.createPullRequest).toHaveBeenCalledWith({
|
||||
owner: 'myorg',
|
||||
repo: 'myrepo',
|
||||
title: 'Create my new app',
|
||||
head: 'new-app',
|
||||
body: 'This PR is really good',
|
||||
createWhenEmpty: true,
|
||||
changes: [
|
||||
{
|
||||
commit: 'Create my new app',
|
||||
files: {
|
||||
'file.txt': {
|
||||
content: Buffer.from('Hello there!').toString('base64'),
|
||||
encoding: 'base64',
|
||||
mode: '100644',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('creates outputs for the pull request url and number', async () => {
|
||||
await instance.handler(ctx);
|
||||
|
||||
expect(ctx.output).toHaveBeenCalledWith(
|
||||
'remoteUrl',
|
||||
'https://github.com/myorg/myrepo/pull/123',
|
||||
);
|
||||
expect(ctx.output).toHaveBeenCalledWith('pullRequestNumber', 123);
|
||||
});
|
||||
|
||||
it('throws when creating a pull request fails', async () => {
|
||||
fakeClient.createPullRequest.mockResolvedValueOnce(null);
|
||||
|
||||
await expect(instance.handler(ctx)).rejects.toThrow(
|
||||
'null response from Github',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with createWhenEmpty equals false', () => {
|
||||
let input: GithubPullRequestActionInput;
|
||||
let ctx: ActionContext<GithubPullRequestActionInput>;
|
||||
|
||||
beforeEach(() => {
|
||||
fakeClient.createPullRequest.mockResolvedValueOnce(null);
|
||||
input = {
|
||||
repoUrl: 'github.com?owner=myorg&repo=myrepo',
|
||||
title: 'Create my new app',
|
||||
branchName: 'new-app',
|
||||
description: 'This PR is really good',
|
||||
createWhenEmpty: false,
|
||||
};
|
||||
|
||||
mockDir.setContent({
|
||||
[workspacePath]: { 'file.txt': 'Hello there!' },
|
||||
});
|
||||
|
||||
ctx = createMockActionContext({ input, workspacePath });
|
||||
});
|
||||
it('creates a pull request', async () => {
|
||||
await instance.handler(ctx);
|
||||
|
||||
expect(fakeClient.createPullRequest).toHaveBeenCalledWith({
|
||||
owner: 'myorg',
|
||||
repo: 'myrepo',
|
||||
title: 'Create my new app',
|
||||
head: 'new-app',
|
||||
body: 'This PR is really good',
|
||||
createWhenEmpty: false,
|
||||
changes: [
|
||||
{
|
||||
commit: 'Create my new app',
|
||||
files: {
|
||||
'file.txt': {
|
||||
content: Buffer.from('Hello there!').toString('base64'),
|
||||
encoding: 'base64',
|
||||
mode: '100644',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('does not create outputs for the pull request url and number', async () => {
|
||||
await instance.handler(ctx);
|
||||
|
||||
expect(ctx.output).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -145,6 +145,7 @@ export const createPublishGithubPullRequestAction = (
|
||||
gitAuthorName?: string;
|
||||
gitAuthorEmail?: string;
|
||||
forceEmptyGitAuthor?: boolean;
|
||||
createWhenEmpty?: boolean;
|
||||
}>({
|
||||
id: 'publish:github:pull-request',
|
||||
examples,
|
||||
@@ -251,10 +252,16 @@ export const createPublishGithubPullRequestAction = (
|
||||
description:
|
||||
'Forces the author to be empty. This is useful when using a Github App, it permit the commit to be verified on Github',
|
||||
},
|
||||
createWhenEmpty: {
|
||||
type: 'boolean',
|
||||
title: 'Create When Empty',
|
||||
description:
|
||||
'Set whether to create pull request when there are no changes to commit. The default value is true',
|
||||
},
|
||||
},
|
||||
},
|
||||
output: {
|
||||
required: ['remoteUrl'],
|
||||
required: [],
|
||||
type: 'object',
|
||||
properties: {
|
||||
targetBranchName: {
|
||||
@@ -293,6 +300,7 @@ export const createPublishGithubPullRequestAction = (
|
||||
gitAuthorEmail,
|
||||
gitAuthorName,
|
||||
forceEmptyGitAuthor,
|
||||
createWhenEmpty,
|
||||
} = ctx.input;
|
||||
|
||||
const { owner, repo, host } = parseRepoUrl(repoUrl, integrations);
|
||||
@@ -379,6 +387,7 @@ export const createPublishGithubPullRequestAction = (
|
||||
draft,
|
||||
update,
|
||||
forceFork,
|
||||
createWhenEmpty,
|
||||
};
|
||||
|
||||
const gitAuthorInfo = {
|
||||
@@ -417,6 +426,11 @@ export const createPublishGithubPullRequestAction = (
|
||||
}
|
||||
const response = await client.createPullRequest(createOptions);
|
||||
|
||||
if (createWhenEmpty === false && !response) {
|
||||
ctx.logger.info('No changes to commit, pull request was not created');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!response) {
|
||||
throw new GithubResponseError('null response from Github');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user