diff --git a/plugins/scaffolder-backend-module-github/src/actions/gitHubEnvironment.examples.ts b/plugins/scaffolder-backend-module-github/src/actions/gitHubEnvironment.examples.ts index 7c5f7efa3d..44ddcc2175 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/gitHubEnvironment.examples.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/gitHubEnvironment.examples.ts @@ -302,4 +302,61 @@ export const examples: TemplateExample[] = [ ], }), }, + { + description: 'Create a GitHub Environment with Wait Timer', + example: yaml.stringify({ + steps: [ + { + action: 'github:environment:create', + name: 'Create Environment', + input: { + repoUrl: 'github.com?repo=repository&owner=owner', + name: 'envname', + wait_timer: 1000, + }, + }, + ], + }), + }, + { + description: 'Create a GitHub Environment with Prevent Self Review', + example: yaml.stringify({ + steps: [ + { + action: 'github:environment:create', + name: 'Create Environment', + input: { + repoUrl: 'github.com?repo=repository&owner=owner', + name: 'envname', + prevent_self_review: true, + }, + }, + ], + }), + }, + { + description: 'Create a GitHub Environment with Reviewers', + example: yaml.stringify({ + steps: [ + { + action: 'github:environment:create', + name: 'Create Environment', + input: { + repoUrl: 'github.com?repo=repository&owner=owner', + name: 'envname', + reviewers: [ + { + Type: 'User', + ID: 1, + }, + { + Type: 'Team', + ID: 2, + }, + ], + }, + }, + ], + }), + }, ]; diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.examples.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.examples.test.ts index c8b133859b..7d0b72c8ba 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.examples.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.examples.test.ts @@ -95,6 +95,9 @@ describe('github:environment:create examples', () => { repo: 'repository', environment_name: 'envname', deployment_branch_policy: null, + wait_timer: 0, + reviewers: null, + prevent_self_review: false, }); expect( mockOctokit.rest.repos.createDeploymentBranchPolicy, @@ -128,6 +131,9 @@ describe('github:environment:create examples', () => { protected_branches: true, custom_branch_policies: false, }, + wait_timer: 0, + reviewers: null, + prevent_self_review: false, }); expect( @@ -162,6 +168,9 @@ describe('github:environment:create examples', () => { protected_branches: false, custom_branch_policies: true, }, + wait_timer: 0, + reviewers: null, + prevent_self_review: false, }); expect( @@ -208,6 +217,9 @@ describe('github:environment:create examples', () => { repo: 'repository', environment_name: 'envname', deployment_branch_policy: null, + wait_timer: 0, + reviewers: null, + prevent_self_review: false, }); expect( @@ -280,6 +292,9 @@ describe('github:environment:create examples', () => { repo: 'repository', environment_name: 'envname', deployment_branch_policy: null, + wait_timer: 0, + reviewers: null, + prevent_self_review: false, }); expect( @@ -331,6 +346,9 @@ describe('github:environment:create examples', () => { custom_branch_policies: true, protected_branches: false, }, + wait_timer: 0, + reviewers: null, + prevent_self_review: false, }); expect( @@ -382,6 +400,9 @@ describe('github:environment:create examples', () => { custom_branch_policies: true, protected_branches: false, }, + wait_timer: 0, + reviewers: null, + prevent_self_review: false, }); expect( @@ -473,6 +494,9 @@ describe('github:environment:create examples', () => { repo: 'repository', environment_name: 'envname', deployment_branch_policy: null, + wait_timer: 0, + reviewers: null, + prevent_self_review: false, }); expect( @@ -503,6 +527,9 @@ describe('github:environment:create examples', () => { repo: 'repository', environment_name: 'envname', deployment_branch_policy: null, + wait_timer: 0, + reviewers: null, + prevent_self_review: false, }); expect( @@ -536,6 +563,9 @@ describe('github:environment:create examples', () => { custom_branch_policies: true, protected_branches: false, }, + wait_timer: 0, + reviewers: null, + prevent_self_review: false, }); expect( @@ -593,6 +623,9 @@ describe('github:environment:create examples', () => { repo: 'repository', environment_name: 'envname', deployment_branch_policy: null, + wait_timer: 0, + reviewers: null, + prevent_self_review: false, }); expect( @@ -643,6 +676,9 @@ describe('github:environment:create examples', () => { repo: 'repository', environment_name: 'envname', deployment_branch_policy: null, + wait_timer: 0, + reviewers: null, + prevent_self_review: false, }); expect( @@ -697,6 +733,9 @@ describe('github:environment:create examples', () => { custom_branch_policies: false, protected_branches: true, }, + wait_timer: 0, + reviewers: null, + prevent_self_review: false, }); expect( @@ -726,6 +765,9 @@ describe('github:environment:create examples', () => { repo: 'repository', environment_name: 'envname', deployment_branch_policy: null, + wait_timer: 0, + reviewers: null, + prevent_self_review: false, }); expect( @@ -782,4 +824,112 @@ describe('github:environment:create examples', () => { secret_name: 'SECRET2', }); }); + + it(`should ${examples[14].description}`, async () => { + const input = yaml.parse(examples[14].example).steps[0].input; + + await action.handler({ + ...mockContext, + input, + }); + + expect( + mockOctokit.rest.repos.createOrUpdateEnvironment, + ).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repository', + environment_name: 'envname', + deployment_branch_policy: null, + wait_timer: 1000, + reviewers: null, + prevent_self_review: false, + }); + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).not.toHaveBeenCalled(); + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).not.toHaveBeenCalled(); + expect( + mockOctokit.rest.actions.getEnvironmentPublicKey, + ).not.toHaveBeenCalled(); + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).not.toHaveBeenCalled(); + }); + + it(`should ${examples[15].description}`, async () => { + const input = yaml.parse(examples[15].example).steps[0].input; + + await action.handler({ + ...mockContext, + input, + }); + + expect( + mockOctokit.rest.repos.createOrUpdateEnvironment, + ).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repository', + environment_name: 'envname', + deployment_branch_policy: null, + wait_timer: 0, + reviewers: null, + prevent_self_review: true, + }); + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).not.toHaveBeenCalled(); + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).not.toHaveBeenCalled(); + expect( + mockOctokit.rest.actions.getEnvironmentPublicKey, + ).not.toHaveBeenCalled(); + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).not.toHaveBeenCalled(); + }); + + it(`should ${examples[16].description}`, async () => { + const input = yaml.parse(examples[16].example).steps[0].input; + + await action.handler({ + ...mockContext, + input, + }); + + expect( + mockOctokit.rest.repos.createOrUpdateEnvironment, + ).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repository', + environment_name: 'envname', + deployment_branch_policy: null, + wait_timer: 0, + reviewers: [ + { + Type: 'User', + ID: 1, + }, + { + Type: 'Team', + ID: 2, + }, + ], + prevent_self_review: false, + }); + expect( + mockOctokit.rest.repos.createDeploymentBranchPolicy, + ).not.toHaveBeenCalled(); + expect( + mockOctokit.rest.actions.createEnvironmentVariable, + ).not.toHaveBeenCalled(); + expect( + mockOctokit.rest.actions.getEnvironmentPublicKey, + ).not.toHaveBeenCalled(); + expect( + mockOctokit.rest.actions.createOrUpdateEnvironmentSecret, + ).not.toHaveBeenCalled(); + }); }); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.test.ts b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.test.ts index 139d8028eb..2c729e2e5a 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.test.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.test.ts @@ -94,6 +94,9 @@ describe('github:environment:create', () => { repo: 'repository', environment_name: 'envname', deployment_branch_policy: null, + reviewers: null, + wait_timer: 0, + prevent_self_review: false, }); }); @@ -119,6 +122,9 @@ describe('github:environment:create', () => { protected_branches: true, custom_branch_policies: false, }, + reviewers: null, + wait_timer: 0, + prevent_self_review: false, }); }); @@ -145,6 +151,9 @@ describe('github:environment:create', () => { protected_branches: false, custom_branch_policies: true, }, + reviewers: null, + wait_timer: 0, + prevent_self_review: false, }); expect( @@ -190,6 +199,9 @@ describe('github:environment:create', () => { protected_branches: false, custom_branch_policies: true, }, + reviewers: null, + wait_timer: 0, + prevent_self_review: false, }); expect( @@ -231,6 +243,9 @@ describe('github:environment:create', () => { repo: 'repository', environment_name: 'envname', deployment_branch_policy: null, + reviewers: null, + wait_timer: 0, + prevent_self_review: false, }); expect( @@ -277,6 +292,9 @@ describe('github:environment:create', () => { repo: 'repository', environment_name: 'envname', deployment_branch_policy: null, + reviewers: null, + wait_timer: 0, + prevent_self_review: false, }); expect( @@ -316,4 +334,110 @@ describe('github:environment:create', () => { environment_name: 'envname', }); }); + + it('should work with wait_timer', async () => { + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + wait_timer: 1000, + }, + }); + + expect( + mockOctokit.rest.repos.createOrUpdateEnvironment, + ).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repository', + environment_name: 'envname', + deployment_branch_policy: null, + reviewers: null, + wait_timer: 1000, + prevent_self_review: false, + }); + }); + + it('should work with prevent_self_review set to true', async () => { + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + prevent_self_review: true, + }, + }); + + expect( + mockOctokit.rest.repos.createOrUpdateEnvironment, + ).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repository', + environment_name: 'envname', + deployment_branch_policy: null, + reviewers: null, + wait_timer: 0, + prevent_self_review: true, + }); + }); + + it('should work with prevent_self_review set to false', async () => { + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + prevent_self_review: false, + }, + }); + + expect( + mockOctokit.rest.repos.createOrUpdateEnvironment, + ).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repository', + environment_name: 'envname', + deployment_branch_policy: null, + reviewers: null, + wait_timer: 0, + prevent_self_review: false, + }); + }); + + it('should work with reviewers', async () => { + await action.handler({ + ...mockContext, + input: { + ...mockContext.input, + reviewers: [ + { + Type: 'User', + ID: 1, + }, + { + Type: 'Team', + ID: 2, + }, + ], + }, + }); + + expect( + mockOctokit.rest.repos.createOrUpdateEnvironment, + ).toHaveBeenCalledWith({ + owner: 'owner', + repo: 'repository', + environment_name: 'envname', + deployment_branch_policy: null, + wait_timer: 0, + prevent_self_review: false, + reviewers: [ + { + Type: 'User', + ID: 1, + }, + { + Type: 'Team', + ID: 2, + }, + ], + }); + }); }); diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.ts b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.ts index d3e8d0e5d2..8861aa5bd3 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubEnvironment.ts @@ -48,6 +48,9 @@ export function createGithubEnvironmentAction(options: { environmentVariables?: { [key: string]: string }; secrets?: { [key: string]: string }; token?: string; + wait_timer?: number; + prevent_self_review?: boolean; + reviewers?: Array<{ type?: 'User' | 'Team'; id?: number }> | null; }>({ id: 'github:environment:create', description: 'Creates Deployment Environments', @@ -120,6 +123,35 @@ export function createGithubEnvironmentAction(options: { type: 'string', description: 'The token to use for authorization to GitHub', }, + wait_timer: { + title: 'Wait Timer', + type: 'integer', + description: + 'The time to wait before creating or updating the environment (in milliseconds)', + }, + prevent_self_review: { + title: 'Prevent Self Review', + type: 'boolean', + description: 'Whether to prevent self-review for this environment', + }, + reviewers: { + title: 'Reviewers', + type: 'array', + description: 'Reviewers for this environment', + items: { + type: 'object', + properties: { + type: { + title: 'Type', + type: 'string', + }, + id: { + title: 'ID', + type: 'integer', + }, + }, + }, + }, }, }, }, @@ -133,8 +165,16 @@ export function createGithubEnvironmentAction(options: { environmentVariables, secrets, token: providedToken, + wait_timer, + prevent_self_review, + reviewers, } = ctx.input; + // Wait for the specified time before creating or updating the environment + if (wait_timer) { + await new Promise(resolve => setTimeout(resolve, wait_timer)); + } + const octokitOptions = await getOctokitOptions({ integrations, token: providedToken, @@ -158,6 +198,9 @@ export function createGithubEnvironmentAction(options: { repo: repo, environment_name: name, deployment_branch_policy: deploymentBranchPolicy ?? null, + wait_timer: wait_timer ?? 0, + prevent_self_review: prevent_self_review ?? false, + reviewers: reviewers ?? null, }); if (customBranchPolicyNames) {