From 79dc5accffcc9a02dbb1bd72a8e222d298abb4a5 Mon Sep 17 00:00:00 2001 From: Bogdan Nechyporenko Date: Tue, 18 Mar 2025 20:15:45 +0100 Subject: [PATCH] Made "github:deployKey:create" action idempotent Signed-off-by: Bogdan Nechyporenko --- .changeset/short-cloths-decide.md | 5 ++ .../src/actions/githubDeployKey.ts | 50 +++++++++++++------ 2 files changed, 40 insertions(+), 15 deletions(-) create mode 100644 .changeset/short-cloths-decide.md diff --git a/.changeset/short-cloths-decide.md b/.changeset/short-cloths-decide.md new file mode 100644 index 0000000000..ae8b9f6c6d --- /dev/null +++ b/.changeset/short-cloths-decide.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-github': patch +--- + +Made "github:deployKey:create" action idempotent diff --git a/plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.ts b/plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.ts index 7e674a3e52..7eba3b94c8 100644 --- a/plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.ts +++ b/plugins/scaffolder-backend-module-github/src/actions/githubDeployKey.ts @@ -126,20 +126,35 @@ export function createGithubDeployKeyAction(options: { const client = new Octokit(octokitOptions); - await client.rest.repos.createDeployKey({ - owner: owner, - repo: repo, - title: deployKeyName, - key: publicKey, + await ctx.checkpoint({ + key: `create.deploy.key.${owner}.${repo}.${publicKey}`, + fn: async () => { + await client.rest.repos.createDeployKey({ + owner: owner, + repo: repo, + title: deployKeyName, + key: publicKey, + }); + }, }); - const publicKeyResponse = await client.rest.actions.getRepoPublicKey({ - owner: owner, - repo: repo, + + const { key, keyId } = await ctx.checkpoint({ + key: `get.repo.public.key.${owner}.${repo}`, + fn: async () => { + const publicKeyResponse = await client.rest.actions.getRepoPublicKey({ + owner: owner, + repo: repo, + }); + return { + key: publicKeyResponse.data.key, + keyId: publicKeyResponse.data.key_id, + }; + }, }); await Sodium.ready; const binaryKey = Sodium.from_base64( - publicKeyResponse.data.key, + key, Sodium.base64_variants.ORIGINAL, ); const binarySecret = Sodium.from_string(privateKey); @@ -152,12 +167,17 @@ export function createGithubDeployKeyAction(options: { Sodium.base64_variants.ORIGINAL, ); - await client.rest.actions.createOrUpdateRepoSecret({ - owner: owner, - repo: repo, - secret_name: privateKeySecretName, - encrypted_value: encryptedBase64Secret, - key_id: publicKeyResponse.data.key_id, + await ctx.checkpoint({ + key: `create.or.update.repo.secret.${owner}.${repo}.${keyId}`, + fn: async () => { + await client.rest.actions.createOrUpdateRepoSecret({ + owner: owner, + repo: repo, + secret_name: privateKeySecretName, + encrypted_value: encryptedBase64Secret, + key_id: keyId, + }); + }, }); ctx.output('privateKeySecretName', privateKeySecretName);