From 1d32be309be8807ee790d462e84e817872a1fa7c Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 1 Apr 2021 18:56:06 +0100 Subject: [PATCH] allow collaborators on github creation Signed-off-by: Andrew Johnson --- .../create-react-app/template.yaml | 27 ++++++++- .../actions/builtin/publish/github.test.ts | 56 +++++++++++++++++++ .../actions/builtin/publish/github.ts | 32 +++++++++++ 3 files changed, 114 insertions(+), 1 deletion(-) diff --git a/plugins/scaffolder-backend/sample-templates/create-react-app/template.yaml b/plugins/scaffolder-backend/sample-templates/create-react-app/template.yaml index 91f887ed0a..82fde335c5 100644 --- a/plugins/scaffolder-backend/sample-templates/create-react-app/template.yaml +++ b/plugins/scaffolder-backend/sample-templates/create-react-app/template.yaml @@ -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 diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts index 9880dda621..54282f76cd 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.test.ts @@ -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' }, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts index 70394b0039..8b09c644de 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts @@ -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`;