Made "github:environment:create" action idempotent
Signed-off-by: Bogdan Nechyporenko <bnechyporenko@bol.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-github': patch
|
||||
---
|
||||
|
||||
Made "github:environment:create" action idempotent
|
||||
@@ -194,9 +194,16 @@ Wildcard characters will not match \`/\`. For example, to match tags that begin
|
||||
});
|
||||
|
||||
const client = new Octokit(octokitOptions);
|
||||
const repository = await client.rest.repos.get({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
|
||||
const repositoryId = await ctx.checkpoint({
|
||||
key: `get.repo.${owner}.${repo}`,
|
||||
fn: async () => {
|
||||
const repository = await client.rest.repos.get({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
});
|
||||
return repository.data.id;
|
||||
},
|
||||
});
|
||||
|
||||
// convert reviewers from catalog entity to Github user or team
|
||||
@@ -219,25 +226,39 @@ Wildcard characters will not match \`/\`. For example, to match tags that begin
|
||||
for (const reviewerEntityRef of reviewersEntityRefs) {
|
||||
if (reviewerEntityRef?.kind === 'User') {
|
||||
try {
|
||||
const user = await client.rest.users.getByUsername({
|
||||
username: reviewerEntityRef.metadata.name,
|
||||
const userId = await ctx.checkpoint({
|
||||
key: `get.user.${reviewerEntityRef.metadata.name}`,
|
||||
fn: async () => {
|
||||
const user = await client.rest.users.getByUsername({
|
||||
username: reviewerEntityRef.metadata.name,
|
||||
});
|
||||
return user.data.id;
|
||||
},
|
||||
});
|
||||
|
||||
githubReviewers.push({
|
||||
type: 'User',
|
||||
id: user.data.id,
|
||||
id: userId,
|
||||
});
|
||||
} catch (error) {
|
||||
ctx.logger.error('User not found:', error);
|
||||
}
|
||||
} else if (reviewerEntityRef?.kind === 'Group') {
|
||||
try {
|
||||
const team = await client.rest.teams.getByName({
|
||||
org: owner,
|
||||
team_slug: reviewerEntityRef.metadata.name,
|
||||
const teamId = await ctx.checkpoint({
|
||||
key: `get.team.${reviewerEntityRef.metadata.name}`,
|
||||
fn: async () => {
|
||||
const team = await client.rest.teams.getByName({
|
||||
org: owner,
|
||||
team_slug: reviewerEntityRef.metadata.name,
|
||||
});
|
||||
return team.data.id;
|
||||
},
|
||||
});
|
||||
|
||||
githubReviewers.push({
|
||||
type: 'Team',
|
||||
id: team.data.id,
|
||||
id: teamId,
|
||||
});
|
||||
} catch (error) {
|
||||
ctx.logger.error('Team not found:', error);
|
||||
@@ -246,63 +267,92 @@ Wildcard characters will not match \`/\`. For example, to match tags that begin
|
||||
}
|
||||
}
|
||||
|
||||
await client.rest.repos.createOrUpdateEnvironment({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
environment_name: name,
|
||||
deployment_branch_policy: deploymentBranchPolicy ?? undefined,
|
||||
wait_timer: waitTimer ?? undefined,
|
||||
prevent_self_review: preventSelfReview ?? undefined,
|
||||
reviewers: githubReviewers.length ? githubReviewers : undefined,
|
||||
await ctx.checkpoint({
|
||||
key: `create.or.update.environment.${owner}.${repo}.${name}`,
|
||||
fn: async () => {
|
||||
await client.rest.repos.createOrUpdateEnvironment({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
environment_name: name,
|
||||
deployment_branch_policy: deploymentBranchPolicy ?? undefined,
|
||||
wait_timer: waitTimer ?? undefined,
|
||||
prevent_self_review: preventSelfReview ?? undefined,
|
||||
reviewers: githubReviewers.length ? githubReviewers : undefined,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
if (customBranchPolicyNames) {
|
||||
for (const item of customBranchPolicyNames) {
|
||||
await client.rest.repos.createDeploymentBranchPolicy({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
type: 'branch',
|
||||
environment_name: name,
|
||||
name: item,
|
||||
await ctx.checkpoint({
|
||||
key: `create.deployment.branch.policy.branch.${owner}.${repo}.${name}.${item}`,
|
||||
fn: async () => {
|
||||
await client.rest.repos.createDeploymentBranchPolicy({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
type: 'branch',
|
||||
environment_name: name,
|
||||
name: item,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (customTagPolicyNames) {
|
||||
for (const item of customTagPolicyNames) {
|
||||
await client.rest.repos.createDeploymentBranchPolicy({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
type: 'tag',
|
||||
environment_name: name,
|
||||
name: item,
|
||||
await ctx.checkpoint({
|
||||
key: `create.deployment.branch.policy.tag.${owner}.${repo}.${name}.${item}`,
|
||||
fn: async () => {
|
||||
await client.rest.repos.createDeploymentBranchPolicy({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
type: 'tag',
|
||||
environment_name: name,
|
||||
name: item,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (const [key, value] of Object.entries(environmentVariables ?? {})) {
|
||||
await client.rest.actions.createEnvironmentVariable({
|
||||
repository_id: repository.data.id,
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
environment_name: name,
|
||||
name: key,
|
||||
value,
|
||||
await ctx.checkpoint({
|
||||
key: `create.env.variable.${owner}.${repo}.${name}.${key}`,
|
||||
fn: async () => {
|
||||
await client.rest.actions.createEnvironmentVariable({
|
||||
repository_id: repositoryId,
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
environment_name: name,
|
||||
name: key,
|
||||
value,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (secrets) {
|
||||
const publicKeyResponse =
|
||||
await client.rest.actions.getEnvironmentPublicKey({
|
||||
repository_id: repository.data.id,
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
environment_name: name,
|
||||
});
|
||||
const { publicKey, publicKeyId } = await ctx.checkpoint({
|
||||
key: `get.env.public.key.${owner}.${repo}.${name}`,
|
||||
fn: async () => {
|
||||
const publicKeyResponse =
|
||||
await client.rest.actions.getEnvironmentPublicKey({
|
||||
repository_id: repositoryId,
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
environment_name: name,
|
||||
});
|
||||
return {
|
||||
publicKey: publicKeyResponse.data.key,
|
||||
publicKeyId: publicKeyResponse.data.key_id,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
await Sodium.ready;
|
||||
const binaryKey = Sodium.from_base64(
|
||||
publicKeyResponse.data.key,
|
||||
publicKey,
|
||||
Sodium.base64_variants.ORIGINAL,
|
||||
);
|
||||
for (const [key, value] of Object.entries(secrets)) {
|
||||
@@ -316,14 +366,19 @@ Wildcard characters will not match \`/\`. For example, to match tags that begin
|
||||
Sodium.base64_variants.ORIGINAL,
|
||||
);
|
||||
|
||||
await client.rest.actions.createOrUpdateEnvironmentSecret({
|
||||
repository_id: repository.data.id,
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
environment_name: name,
|
||||
secret_name: key,
|
||||
encrypted_value: encryptedBase64Secret,
|
||||
key_id: publicKeyResponse.data.key_id,
|
||||
await ctx.checkpoint({
|
||||
key: `create.or.update.env.secret.${owner}.${repo}.${name}.${key}`,
|
||||
fn: async () => {
|
||||
await client.rest.actions.createOrUpdateEnvironmentSecret({
|
||||
repository_id: repositoryId,
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
environment_name: name,
|
||||
secret_name: key,
|
||||
encrypted_value: encryptedBase64Secret,
|
||||
key_id: publicKeyId,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user