allow collaborators on github creation

Signed-off-by: Andrew Johnson <ajohnson@gocardless.com>
This commit is contained in:
Andrew Johnson
2021-04-01 18:56:06 +01:00
parent 4c42dc291c
commit 1d32be309b
3 changed files with 114 additions and 1 deletions
@@ -19,6 +19,7 @@ spec:
- component_id
- use_typescript
- description
- collaborators
properties:
component_id:
title: Name
@@ -39,4 +40,28 @@ spec:
type: boolean
description: Use Github Actions
default: true
collaborators:
title: Collaborators
description: Provide users with permissions
type: array
ui:options:
orderable: false
items:
type: object
required:
- username
- access
properties:
access:
type: string
description: The type of access for the user
default: pull
enum:
- push
- pull
- admin
- maintain
- triage
username:
type: string
description: The username or group
@@ -232,6 +232,62 @@ describe('publish:github', () => {
});
});
it('should add multiple collaborators when provided', async () => {
mockGithubClient.users.getByUsername.mockResolvedValue({
data: { type: 'User' },
});
mockGithubClient.repos.createForAuthenticatedUser.mockResolvedValue({
data: {
clone_url: 'https://github.com/clone/url.git',
html_url: 'https://github.com/html/url',
},
});
await action.handler({
...mockContext,
input: {
...mockContext.input,
collaborators: [
{
access: 'pull',
username: 'robot-1',
},
{
access: 'push',
username: 'robot-2',
},
],
},
});
const commonProperties = {
org: 'owner',
owner: 'owner',
repo: 'repo',
};
expect(
mockGithubClient.teams.addOrUpdateRepoPermissionsInOrg.mock.calls[1],
).toEqual([
{
...commonProperties,
team_slug: 'robot-1',
permission: 'pull',
},
]);
expect(
mockGithubClient.teams.addOrUpdateRepoPermissionsInOrg.mock.calls[2],
).toEqual([
{
...commonProperties,
team_slug: 'robot-2',
permission: 'push',
},
]);
});
it('should call output with the remoteUrl and the repoContentsUrl', async () => {
mockGithubClient.users.getByUsername.mockResolvedValue({
data: { type: 'User' },
@@ -23,6 +23,9 @@ import { initRepoAndPush } from '../../../stages/publish/helpers';
import { getRepoSourceDirectory, parseRepoUrl } from './util';
import { createTemplateAction } from '../../createTemplateAction';
type Permission = 'pull' | 'push' | 'admin' | 'maintain' | 'triage';
type Collaborator = { access: Permission; username: string };
export function createPublishGithubAction(options: {
integrations: ScmIntegrationRegistry;
}) {
@@ -41,6 +44,7 @@ export function createPublishGithubAction(options: {
access?: string;
sourcePath?: string;
repoVisibility: 'private' | 'internal' | 'public';
collaborators: Collaborator[];
}>({
id: 'publish:github',
description:
@@ -72,6 +76,21 @@ export function createPublishGithubAction(options: {
'Path within the workspace that will be used as the repository root. If omitted, the entire workspace will be published as the respository.',
type: 'string',
},
collaborators: {
title: 'Collaborators',
type: 'array',
properties: {
access: {
title: 'The type of access for the user',
type: 'string',
enum: ['push', 'pull', 'admin', 'maintain', 'triage'],
},
username: {
title: 'The username or group',
type: 'string',
},
},
},
},
},
output: {
@@ -94,6 +113,7 @@ export function createPublishGithubAction(options: {
description,
access,
repoVisibility = 'private',
collaborators,
} = ctx.input;
const { owner, repo, host } = parseRepoUrl(repoUrl);
@@ -165,6 +185,18 @@ export function createPublishGithubAction(options: {
});
}
if (collaborators) {
for (const { access, username } of collaborators) {
await client.teams.addOrUpdateRepoPermissionsInOrg({
org: owner,
team_slug: username,
owner,
repo,
permission: access,
});
}
}
const remoteUrl = data.clone_url;
const repoContentsUrl = `${data.html_url}/blob/master`;