diff --git a/.changeset/giant-donkeys-punch.md b/.changeset/giant-donkeys-punch.md new file mode 100644 index 0000000000..522055832a --- /dev/null +++ b/.changeset/giant-donkeys-punch.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-azure': patch +--- + +Made "publish:azure" action idempotent diff --git a/plugins/scaffolder-backend-module-azure/src/actions/azure.ts b/plugins/scaffolder-backend-module-azure/src/actions/azure.ts index acb4754520..8c1f5afec8 100644 --- a/plugins/scaffolder-backend-module-azure/src/actions/azure.ts +++ b/plugins/scaffolder-backend-module-azure/src/actions/azure.ts @@ -174,37 +174,49 @@ export function createPublishAzureAction(options: { const webApi = new WebApi(url, authHandler); const client = await webApi.getGitApi(); const createOptions: GitRepositoryCreateOptions = { name: repo }; - const returnedRepo = await client.createRepository( - createOptions, - project, - ); - if (!returnedRepo) { - throw new InputError( - `Unable to create the repository with Organization ${organization}, Project ${project} and Repo ${repo}. + const { remoteUrl, repositoryId, repoContentsUrl } = await ctx.checkpoint( + { + key: `create.repo.${repo}`, + fn: async () => { + const returnedRepo = await client.createRepository( + createOptions, + project, + ); + + if (!returnedRepo) { + throw new InputError( + `Unable to create the repository with Organization ${organization}, Project ${project} and Repo ${repo}. Please make sure that both the Org and Project are typed corrected and exist.`, - ); - } - const remoteUrl = returnedRepo.remoteUrl; + ); + } - if (!remoteUrl) { - throw new InputError( - 'No remote URL returned from create repository for Azure', - ); - } - const repositoryId = returnedRepo.id; + if (!returnedRepo.remoteUrl) { + throw new InputError( + 'No remote URL returned from create repository for Azure', + ); + } - if (!repositoryId) { - throw new InputError('No Id returned from create repository for Azure'); - } + if (!returnedRepo.id) { + throw new InputError( + 'No Id returned from create repository for Azure', + ); + } - const repoContentsUrl = returnedRepo.webUrl; + if (!returnedRepo.webUrl) { + throw new InputError( + 'No web URL returned from create repository for Azure', + ); + } - if (!repoContentsUrl) { - throw new InputError( - 'No web URL returned from create repository for Azure', - ); - } + return { + remoteUrl: returnedRepo.remoteUrl, + repositoryId: returnedRepo.id, + repoContentsUrl: returnedRepo.webUrl, + }; + }, + }, + ); const gitAuthorInfo = { name: gitAuthorName @@ -229,20 +241,30 @@ export function createPublishAzureAction(options: { ); } - const commitResult = await initRepoAndPush({ - dir: getRepoSourceDirectory(ctx.workspacePath, ctx.input.sourcePath), - remoteUrl, - defaultBranch, - auth: auth, - logger: ctx.logger, - commitMessage: gitCommitMessage - ? gitCommitMessage - : config.getOptionalString('scaffolder.defaultCommitMessage'), - gitAuthorInfo, - signingKey: signCommit ? signingKey : undefined, + const commitHash = await ctx.checkpoint({ + key: `init.repo.and.push.${remoteUrl}`, + fn: async () => { + const commitResult = await initRepoAndPush({ + dir: getRepoSourceDirectory( + ctx.workspacePath, + ctx.input.sourcePath, + ), + remoteUrl, + defaultBranch, + auth: auth, + logger: ctx.logger, + commitMessage: gitCommitMessage + ? gitCommitMessage + : config.getOptionalString('scaffolder.defaultCommitMessage'), + gitAuthorInfo, + signingKey: signCommit ? signingKey : undefined, + }); + + return commitResult?.commitHash; + }, }); - ctx.output('commitHash', commitResult?.commitHash); + ctx.output('commitHash', commitHash); ctx.output('remoteUrl', remoteUrl); ctx.output('repoContentsUrl', repoContentsUrl); ctx.output('repositoryId', repositoryId);