feat: support setting workflow access level during repo creation
Signed-off-by: Phred <fearphage@gmail.com>
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-github': patch
|
||||
---
|
||||
|
||||
Added options to set [workflow access level][access-level] for repositories to `github:repo:create`
|
||||
|
||||
This is useful when creating repositories for GitHub Actions to manage access
|
||||
to the workflows during creation.
|
||||
|
||||
```diff
|
||||
- action: github:repo:create
|
||||
id: create-repo
|
||||
input:
|
||||
repoUrl: github.com?owner=owner&repo=repo
|
||||
visibility: private
|
||||
+ workflowAccess: organization
|
||||
```
|
||||
|
||||
[access-level]: https://docs.github.com/en/rest/actions/permissions?apiVersion=2022-11-28#set-the-level-of-access-for-workflows-outside-of-the-repository
|
||||
+31
-383
File diff suppressed because it is too large
Load Diff
@@ -1021,4 +1021,19 @@ export const examples: TemplateExample[] = [
|
||||
],
|
||||
}),
|
||||
},
|
||||
{
|
||||
description: 'Allow workflow access for organization.',
|
||||
example: yaml.stringify({
|
||||
steps: [
|
||||
{
|
||||
action: 'github:repo:create',
|
||||
name: 'Create a new GitHub repository that allows org-wide access to its workflows',
|
||||
input: {
|
||||
repoUrl: 'github.com?owner=owner&repo=repo',
|
||||
workflowAccess: 'organization',
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -57,6 +57,7 @@ const mockOctokit = {
|
||||
createRepoVariable: jest.fn(),
|
||||
createOrUpdateRepoSecret: jest.fn(),
|
||||
getRepoPublicKey: jest.fn(),
|
||||
setWorkflowAccessToRepository: jest.fn(),
|
||||
},
|
||||
activity: {
|
||||
setRepoSubscription: jest.fn(),
|
||||
@@ -152,12 +153,7 @@ describe('github:repo:create', () => {
|
||||
allow_rebase_merge: true,
|
||||
allow_auto_merge: false,
|
||||
allow_update_branch: false,
|
||||
has_issues: undefined,
|
||||
has_projects: undefined,
|
||||
has_wiki: undefined,
|
||||
homepage: undefined,
|
||||
visibility: 'private',
|
||||
auto_init: undefined,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -180,13 +176,7 @@ describe('github:repo:create', () => {
|
||||
allow_rebase_merge: true,
|
||||
allow_auto_merge: false,
|
||||
allow_update_branch: false,
|
||||
custom_properties: undefined,
|
||||
has_issues: undefined,
|
||||
has_projects: undefined,
|
||||
has_wiki: undefined,
|
||||
homepage: undefined,
|
||||
visibility: 'public',
|
||||
auto_init: undefined,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -210,11 +200,7 @@ describe('github:repo:create', () => {
|
||||
allow_rebase_merge: true,
|
||||
allow_auto_merge: false,
|
||||
allow_update_branch: false,
|
||||
has_issues: undefined,
|
||||
has_projects: undefined,
|
||||
has_wiki: undefined,
|
||||
visibility: 'private',
|
||||
auto_init: undefined,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -239,13 +225,8 @@ describe('github:repo:create', () => {
|
||||
allow_rebase_merge: true,
|
||||
allow_auto_merge: false,
|
||||
allow_update_branch: false,
|
||||
custom_properties: undefined,
|
||||
visibility: 'private',
|
||||
has_wiki: undefined,
|
||||
has_projects: undefined,
|
||||
has_issues: undefined,
|
||||
homepage: 'https://example.com',
|
||||
auto_init: undefined,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -270,12 +251,7 @@ describe('github:repo:create', () => {
|
||||
allow_rebase_merge: true,
|
||||
allow_auto_merge: false,
|
||||
allow_update_branch: false,
|
||||
custom_properties: undefined,
|
||||
visibility: 'private',
|
||||
has_wiki: undefined,
|
||||
has_projects: undefined,
|
||||
has_issues: undefined,
|
||||
auto_init: undefined,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -302,13 +278,8 @@ describe('github:repo:create', () => {
|
||||
allow_rebase_merge: true,
|
||||
allow_auto_merge: false,
|
||||
allow_update_branch: false,
|
||||
custom_properties: undefined,
|
||||
has_issues: undefined,
|
||||
has_projects: undefined,
|
||||
has_wiki: undefined,
|
||||
homepage: 'https://example.com',
|
||||
visibility: 'private',
|
||||
auto_init: undefined,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -332,11 +303,6 @@ describe('github:repo:create', () => {
|
||||
allow_rebase_merge: true,
|
||||
allow_auto_merge: false,
|
||||
allow_update_branch: false,
|
||||
custom_properties: undefined,
|
||||
has_issues: undefined,
|
||||
has_projects: undefined,
|
||||
has_wiki: undefined,
|
||||
homepage: undefined,
|
||||
visibility: 'private',
|
||||
auto_init: true,
|
||||
});
|
||||
@@ -362,11 +328,6 @@ describe('github:repo:create', () => {
|
||||
allow_rebase_merge: true,
|
||||
allow_auto_merge: false,
|
||||
allow_update_branch: false,
|
||||
custom_properties: undefined,
|
||||
has_issues: undefined,
|
||||
has_projects: undefined,
|
||||
has_wiki: undefined,
|
||||
homepage: undefined,
|
||||
visibility: 'private',
|
||||
auto_init: false,
|
||||
});
|
||||
@@ -396,11 +357,6 @@ describe('github:repo:create', () => {
|
||||
allow_rebase_merge: true,
|
||||
allow_auto_merge: false,
|
||||
allow_update_branch: false,
|
||||
has_issues: undefined,
|
||||
has_projects: undefined,
|
||||
has_wiki: undefined,
|
||||
homepage: undefined,
|
||||
auto_init: undefined,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -424,11 +380,6 @@ describe('github:repo:create', () => {
|
||||
allow_rebase_merge: true,
|
||||
allow_auto_merge: false,
|
||||
allow_update_branch: false,
|
||||
has_issues: undefined,
|
||||
has_projects: undefined,
|
||||
has_wiki: undefined,
|
||||
homepage: undefined,
|
||||
auto_init: undefined,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -453,10 +404,6 @@ describe('github:repo:create', () => {
|
||||
allow_rebase_merge: true,
|
||||
allow_auto_merge: false,
|
||||
allow_update_branch: false,
|
||||
has_issues: undefined,
|
||||
has_projects: undefined,
|
||||
has_wiki: undefined,
|
||||
auto_init: undefined,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -482,11 +429,7 @@ describe('github:repo:create', () => {
|
||||
allow_rebase_merge: true,
|
||||
allow_auto_merge: false,
|
||||
allow_update_branch: false,
|
||||
has_wiki: undefined,
|
||||
has_projects: undefined,
|
||||
has_issues: undefined,
|
||||
homepage: 'https://example.com',
|
||||
auto_init: undefined,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -512,11 +455,7 @@ describe('github:repo:create', () => {
|
||||
allow_rebase_merge: true,
|
||||
allow_auto_merge: false,
|
||||
allow_update_branch: false,
|
||||
has_wiki: undefined,
|
||||
has_projects: undefined,
|
||||
has_issues: undefined,
|
||||
homepage: 'https://example.com',
|
||||
auto_init: undefined,
|
||||
});
|
||||
|
||||
// Custom properties on user repos should be ignored
|
||||
@@ -545,11 +484,7 @@ describe('github:repo:create', () => {
|
||||
allow_rebase_merge: true,
|
||||
allow_auto_merge: false,
|
||||
allow_update_branch: false,
|
||||
has_issues: undefined,
|
||||
has_projects: undefined,
|
||||
has_wiki: undefined,
|
||||
homepage: 'https://example.com',
|
||||
auto_init: undefined,
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
@@ -573,10 +508,6 @@ describe('github:repo:create', () => {
|
||||
allow_rebase_merge: true,
|
||||
allow_auto_merge: false,
|
||||
allow_update_branch: false,
|
||||
has_wiki: undefined,
|
||||
has_projects: undefined,
|
||||
has_issues: undefined,
|
||||
homepage: undefined,
|
||||
auto_init: true,
|
||||
});
|
||||
|
||||
@@ -601,10 +532,6 @@ describe('github:repo:create', () => {
|
||||
allow_rebase_merge: true,
|
||||
allow_auto_merge: false,
|
||||
allow_update_branch: false,
|
||||
has_wiki: undefined,
|
||||
has_projects: undefined,
|
||||
has_issues: undefined,
|
||||
homepage: undefined,
|
||||
auto_init: false,
|
||||
});
|
||||
});
|
||||
@@ -966,4 +893,30 @@ describe('github:repo:create', () => {
|
||||
ignored: false,
|
||||
});
|
||||
});
|
||||
|
||||
it.each(['none', 'organization', 'user'])(
|
||||
'should set workflow access level - %s',
|
||||
async expected => {
|
||||
mockOctokit.rest.users.getByUsername.mockResolvedValue({
|
||||
data: { type: 'Organization' },
|
||||
});
|
||||
mockOctokit.rest.repos.createInOrg.mockResolvedValue({ data: {} });
|
||||
|
||||
await action.handler({
|
||||
...mockContext,
|
||||
input: {
|
||||
...mockContext.input,
|
||||
workflowAccess: expected,
|
||||
},
|
||||
});
|
||||
|
||||
expect(
|
||||
mockOctokit.rest.actions.setWorkflowAccessToRepository,
|
||||
).toHaveBeenCalledWith({
|
||||
access_level: expected,
|
||||
owner: 'owner',
|
||||
repo: 'repo',
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
@@ -47,41 +47,7 @@ export function createGithubRepoCreateAction(options: {
|
||||
examples,
|
||||
schema: {
|
||||
input: {
|
||||
repoUrl: inputProps.repoUrl,
|
||||
description: inputProps.description,
|
||||
homepage: inputProps.homepage,
|
||||
access: inputProps.access,
|
||||
requireCodeOwnerReviews: inputProps.requireCodeOwnerReviews,
|
||||
bypassPullRequestAllowances: inputProps.bypassPullRequestAllowances,
|
||||
requiredApprovingReviewCount: inputProps.requiredApprovingReviewCount,
|
||||
restrictions: inputProps.restrictions,
|
||||
requiredStatusCheckContexts: inputProps.requiredStatusCheckContexts,
|
||||
requireBranchesToBeUpToDate: inputProps.requireBranchesToBeUpToDate,
|
||||
requiredConversationResolution:
|
||||
inputProps.requiredConversationResolution,
|
||||
repoVisibility: inputProps.repoVisibility,
|
||||
deleteBranchOnMerge: inputProps.deleteBranchOnMerge,
|
||||
allowMergeCommit: inputProps.allowMergeCommit,
|
||||
allowSquashMerge: inputProps.allowSquashMerge,
|
||||
squashMergeCommitTitle: inputProps.squashMergeCommitTitle,
|
||||
squashMergeCommitMessage: inputProps.squashMergeCommitMessage,
|
||||
allowRebaseMerge: inputProps.allowRebaseMerge,
|
||||
allowAutoMerge: inputProps.allowAutoMerge,
|
||||
allowUpdateBranch: inputProps.allowUpdateBranch,
|
||||
collaborators: inputProps.collaborators,
|
||||
hasProjects: inputProps.hasProjects,
|
||||
hasWiki: inputProps.hasWiki,
|
||||
hasIssues: inputProps.hasIssues,
|
||||
token: inputProps.token,
|
||||
topics: inputProps.topics,
|
||||
repoVariables: inputProps.repoVariables,
|
||||
secrets: inputProps.secrets,
|
||||
oidcCustomization: inputProps.oidcCustomization,
|
||||
requiredCommitSigning: inputProps.requiredCommitSigning,
|
||||
requiredLinearHistory: inputProps.requiredLinearHistory,
|
||||
customProperties: inputProps.customProperties,
|
||||
subscribe: inputProps.subscribe,
|
||||
autoInit: inputProps.autoInit,
|
||||
...inputProps,
|
||||
},
|
||||
output: {
|
||||
remoteUrl: outputProps.remoteUrl,
|
||||
@@ -115,6 +81,7 @@ export function createGithubRepoCreateAction(options: {
|
||||
subscribe,
|
||||
token: providedToken,
|
||||
autoInit = undefined,
|
||||
workflowAccess,
|
||||
} = ctx.input;
|
||||
|
||||
const { host, owner, repo } = parseRepoUrl(repoUrl, integrations);
|
||||
@@ -167,6 +134,7 @@ export function createGithubRepoCreateAction(options: {
|
||||
subscribe,
|
||||
ctx.logger,
|
||||
autoInit,
|
||||
workflowAccess,
|
||||
);
|
||||
return newRepo.clone_url;
|
||||
},
|
||||
|
||||
@@ -79,6 +79,7 @@ export async function createGithubRepoWithCollaboratorsAndTopics(
|
||||
subscribe: boolean | undefined,
|
||||
logger: LoggerService,
|
||||
autoInit?: boolean | undefined,
|
||||
workflowAccess?: 'none' | 'organization' | 'user',
|
||||
) {
|
||||
// eslint-disable-next-line testing-library/no-await-sync-queries
|
||||
const user = await client.rest.users.getByUsername({
|
||||
@@ -272,6 +273,14 @@ export async function createGithubRepoWithCollaboratorsAndTopics(
|
||||
});
|
||||
}
|
||||
|
||||
if (workflowAccess) {
|
||||
await client.rest.actions.setWorkflowAccessToRepository({
|
||||
access_level: workflowAccess,
|
||||
owner,
|
||||
repo,
|
||||
});
|
||||
}
|
||||
|
||||
return newRepo;
|
||||
}
|
||||
|
||||
|
||||
@@ -421,50 +421,59 @@ const autoInit = (z: typeof zod) =>
|
||||
.default(false)
|
||||
.optional();
|
||||
|
||||
const workflowAccess = (z: typeof zod) =>
|
||||
z
|
||||
.enum(['node', 'organization', 'user'], {
|
||||
description:
|
||||
'Level of access for workflows outside of the repository. Default is "none".',
|
||||
})
|
||||
.optional();
|
||||
|
||||
export {
|
||||
repoUrl,
|
||||
description,
|
||||
homepage,
|
||||
access,
|
||||
requireCodeOwnerReviews,
|
||||
dismissStaleReviews,
|
||||
requiredStatusCheckContexts,
|
||||
requireBranchesToBeUpToDate,
|
||||
requiredConversationResolution,
|
||||
requireLastPushApproval,
|
||||
repoVisibility,
|
||||
deleteBranchOnMerge,
|
||||
gitAuthorName,
|
||||
gitAuthorEmail,
|
||||
allowAutoMerge,
|
||||
allowMergeCommit,
|
||||
allowRebaseMerge,
|
||||
allowSquashMerge,
|
||||
allowUpdateBranch,
|
||||
squashMergeCommitTitle,
|
||||
squashMergeCommitMessage,
|
||||
allowRebaseMerge,
|
||||
allowAutoMerge,
|
||||
autoInit,
|
||||
blockCreations,
|
||||
branch,
|
||||
bypassPullRequestAllowances,
|
||||
collaborators,
|
||||
customProperties,
|
||||
defaultBranch,
|
||||
deleteBranchOnMerge,
|
||||
description,
|
||||
dismissStaleReviews,
|
||||
gitAuthorEmail,
|
||||
gitAuthorName,
|
||||
gitCommitMessage,
|
||||
hasIssues,
|
||||
hasProjects,
|
||||
hasWiki,
|
||||
hasIssues,
|
||||
token,
|
||||
topics,
|
||||
defaultBranch,
|
||||
gitCommitMessage,
|
||||
sourcePath,
|
||||
repoVariables,
|
||||
secrets,
|
||||
homepage,
|
||||
oidcCustomization,
|
||||
customProperties,
|
||||
subscribe,
|
||||
requiredApprovingReviewCount,
|
||||
restrictions,
|
||||
requiredCommitSigning,
|
||||
requiredLinearHistory,
|
||||
protectDefaultBranch,
|
||||
protectEnforceAdmins,
|
||||
bypassPullRequestAllowances,
|
||||
branch,
|
||||
blockCreations,
|
||||
autoInit,
|
||||
repoUrl,
|
||||
repoVariables,
|
||||
repoVisibility,
|
||||
requireBranchesToBeUpToDate,
|
||||
requireCodeOwnerReviews,
|
||||
requiredApprovingReviewCount,
|
||||
requiredCommitSigning,
|
||||
requiredConversationResolution,
|
||||
requiredLinearHistory,
|
||||
requiredStatusCheckContexts,
|
||||
requireLastPushApproval,
|
||||
restrictions,
|
||||
secrets,
|
||||
sourcePath,
|
||||
squashMergeCommitMessage,
|
||||
squashMergeCommitTitle,
|
||||
subscribe,
|
||||
token,
|
||||
topics,
|
||||
workflowAccess,
|
||||
};
|
||||
|
||||
@@ -31,6 +31,4 @@ const commitHash = (z: typeof zod) =>
|
||||
description: 'The git commit hash of the initial commit',
|
||||
});
|
||||
|
||||
export { remoteUrl };
|
||||
export { repoContentsUrl };
|
||||
export { commitHash };
|
||||
export { commitHash, remoteUrl, repoContentsUrl };
|
||||
|
||||
Reference in New Issue
Block a user