Merge pull request #11656 from fabuloso/fix_issue_9943

Fix `publish:github` action not adding users as repository collaborators
This commit is contained in:
Ben Lambert
2022-06-01 10:06:16 +02:00
committed by GitHub
4 changed files with 126 additions and 45 deletions
+23
View File
@@ -0,0 +1,23 @@
---
'@backstage/plugin-scaffolder-backend': minor
---
Fixed a bug in `publish:github` action that didn't permit to add users as collaborators.
This fix required changing the way parameters are passed to the action.
In order to add a team as collaborator, now you must use the `team` field instead of `username`.
In order to add a user as collaborator, you must use the `user` field.
It's still possible to use the field `username` but is deprecated in favor of `team`.
```yaml
- id: publish
name: Publish
action: publish:github
input:
repoUrl: ...
collaborators:
- access: ...
team: my_team
- access: ...
user: my_username
```
+14 -4
View File
@@ -284,10 +284,20 @@ export function createPublishGithubAction(options: {
requiredStatusCheckContexts?: string[] | undefined;
repoVisibility?: 'internal' | 'private' | 'public' | undefined;
collaborators?:
| {
username: string;
access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage';
}[]
| (
| {
user: string;
access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage';
}
| {
team: string;
access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage';
}
| {
username: string;
access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage';
}
)[]
| undefined;
token?: string | undefined;
topics?: string[] | undefined;
@@ -399,41 +399,35 @@ describe('publish:github', () => {
collaborators: [
{
access: 'pull',
username: 'robot-1',
user: 'robot-1',
},
{
access: 'push',
username: 'robot-2',
team: 'robot-2',
},
],
},
});
const commonProperties = {
org: 'owner',
owner: 'owner',
repo: 'repo',
};
expect(
mockOctokit.rest.teams.addOrUpdateRepoPermissionsInOrg.mock.calls[1],
).toEqual([
{
...commonProperties,
team_slug: 'robot-1',
permission: 'pull',
},
]);
expect(mockOctokit.rest.repos.addCollaborator).toHaveBeenCalledWith({
...commonProperties,
username: 'robot-1',
permission: 'pull',
});
expect(
mockOctokit.rest.teams.addOrUpdateRepoPermissionsInOrg.mock.calls[2],
).toEqual([
{
...commonProperties,
team_slug: 'robot-2',
permission: 'push',
},
]);
mockOctokit.rest.teams.addOrUpdateRepoPermissionsInOrg,
).toHaveBeenCalledWith({
...commonProperties,
org: 'owner',
team_slug: 'robot-2',
permission: 'push',
});
});
it('should ignore failures when adding multiple collaborators', async () => {
@@ -465,11 +459,11 @@ describe('publish:github', () => {
collaborators: [
{
access: 'pull',
username: 'robot-1',
team: 'robot-1',
},
{
access: 'push',
username: 'robot-2',
team: 'robot-2',
},
],
},
@@ -58,10 +58,21 @@ export function createPublishGithubAction(options: {
requireCodeOwnerReviews?: boolean;
requiredStatusCheckContexts?: string[];
repoVisibility?: 'private' | 'internal' | 'public';
collaborators?: Array<{
username: string;
access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage';
}>;
collaborators?: Array<
| {
user: string;
access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage';
}
| {
team: string;
access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage';
}
| {
/** @deprecated This field is deprecated in favor of team */
username: string;
access: 'pull' | 'push' | 'admin' | 'maintain' | 'triage';
}
>;
token?: string;
topics?: string[];
}>({
@@ -160,22 +171,39 @@ export function createPublishGithubAction(options: {
},
collaborators: {
title: 'Collaborators',
description: 'Provide additional users with permissions',
description: 'Provide additional users or teams with permissions',
type: 'array',
items: {
type: 'object',
required: ['username', 'access'],
additionalProperties: false,
required: ['access'],
properties: {
access: {
type: 'string',
description: 'The type of access for the user',
enum: ['push', 'pull', 'admin', 'maintain', 'triage'],
},
user: {
type: 'string',
description:
'The name of the user that will be added as a collaborator',
},
username: {
type: 'string',
description: 'The username or group',
description:
'Deprecated. Use the `team` or `user` field instead.',
},
team: {
type: 'string',
description:
'The name of the team that will be added as a collaborator',
},
},
oneOf: [
{ required: ['user'] },
{ required: ['username'] },
{ required: ['team'] },
],
},
},
token: {
@@ -306,22 +334,40 @@ export function createPublishGithubAction(options: {
}
if (collaborators) {
for (const {
access: permission,
username: team_slug,
} of collaborators) {
for (const collaborator of collaborators) {
try {
await client.rest.teams.addOrUpdateRepoPermissionsInOrg({
org: owner,
team_slug,
owner,
repo,
permission,
});
if ('user' in collaborator) {
await client.rest.repos.addCollaborator({
owner,
repo,
username: collaborator.user,
permission: collaborator.access,
});
} else if ('username' in collaborator) {
ctx.logger.warn(
'The field `username` is deprecated in favor of `team` and will be removed in the future.',
);
await client.rest.teams.addOrUpdateRepoPermissionsInOrg({
org: owner,
team_slug: collaborator.username,
owner,
repo,
permission: collaborator.access,
});
} else if ('team' in collaborator) {
await client.rest.teams.addOrUpdateRepoPermissionsInOrg({
org: owner,
team_slug: collaborator.team,
owner,
repo,
permission: collaborator.access,
});
}
} catch (e) {
assertError(e);
const name = extractCollaboratorName(collaborator);
ctx.logger.warn(
`Skipping ${permission} access for ${team_slug}, ${e.message}`,
`Skipping ${collaborator.access} access for ${name}, ${e.message}`,
);
}
}
@@ -391,3 +437,11 @@ export function createPublishGithubAction(options: {
},
});
}
function extractCollaboratorName(
collaborator: { user: string } | { team: string } | { username: string },
) {
if ('username' in collaborator) return collaborator.username;
if ('user' in collaborator) return collaborator.user;
return collaborator.team;
}