From e52cee61e9e8662b6556061b0cef4601a16b54b0 Mon Sep 17 00:00:00 2001 From: Bogdan Nechyporenko Date: Thu, 6 Feb 2025 19:05:08 +0100 Subject: [PATCH 1/3] Made gitlab:issues:create action idempotent. Signed-off-by: Bogdan Nechyporenko --- .changeset/khaki-doors-jog.md | 5 ++ .../src/actions/gitlabIssueCreate.ts | 48 +++++++++++++------ .../src/actions/mockActionContext.ts | 9 +++- 3 files changed, 45 insertions(+), 17 deletions(-) create mode 100644 .changeset/khaki-doors-jog.md diff --git a/.changeset/khaki-doors-jog.md b/.changeset/khaki-doors-jog.md new file mode 100644 index 0000000000..2ff6b44bf3 --- /dev/null +++ b/.changeset/khaki-doors-jog.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitlab': patch +--- + +Made gitlab:issues:create action idempotent. diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabIssueCreate.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabIssueCreate.ts index 30aa2c3d8c..b387bf4e8a 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabIssueCreate.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/gitlabIssueCreate.ts @@ -139,17 +139,24 @@ export const createGitlabIssueAction = (options: { let isEpicScoped = false; - if (epicId) { - isEpicScoped = await checkEpicScope(api, projectId, epicId); + isEpicScoped = await ctx.checkpoint({ + key: `is.epic.scoped.${projectId}.${title}`, + fn: async () => { + if (epicId) { + isEpicScoped = await checkEpicScope(api, projectId, epicId); + + if (isEpicScoped) { + ctx.logger.info('Epic is within Project Scope'); + } else { + ctx.logger.warn( + 'Chosen epic is not within the Project Scope. The issue will be created without an associated epic.', + ); + } + } + return isEpicScoped; + }, + }); - if (isEpicScoped) { - ctx.logger.info('Epic is within Project Scope'); - } else { - ctx.logger.warn( - 'Chosen epic is not within the Project Scope. The issue will be created without an associated epic.', - ); - } - } const mappedCreatedAt = convertDate( String(createdAt), new Date().toISOString(), @@ -173,11 +180,22 @@ export const createGitlabIssueAction = (options: { weight, }; - const response = (await api.Issues.create( - projectId, - title, - issueOptions, - )) as IssueSchema; + const response = await ctx.checkpoint({ + key: `issue.${projectId}.${title}`, + fn: async () => { + const issue = (await api.Issues.create( + projectId, + title, + issueOptions, + )) as IssueSchema; + + return { + id: issue.id, + web_url: issue.web_url, + iid: issue.iid, + }; + }, + }); ctx.output('issueId', response.id); ctx.output('issueUrl', response.web_url); diff --git a/plugins/scaffolder-node-test-utils/src/actions/mockActionContext.ts b/plugins/scaffolder-node-test-utils/src/actions/mockActionContext.ts index 1d45051753..076bb0ce22 100644 --- a/plugins/scaffolder-node-test-utils/src/actions/mockActionContext.ts +++ b/plugins/scaffolder-node-test-utils/src/actions/mockActionContext.ts @@ -21,7 +21,7 @@ import { mockCredentials, mockServices, } from '@backstage/backend-test-utils'; -import { JsonObject } from '@backstage/types'; +import { JsonObject, JsonValue } from '@backstage/types'; import { ActionContext } from '@backstage/plugin-scaffolder-node'; /** @@ -43,7 +43,12 @@ export const createMockActionContext = < output: jest.fn(), createTemporaryDirectory: jest.fn(), input: {} as TActionInput, - checkpoint: jest.fn(), + async checkpoint(opts: { + key: string; + fn: () => Promise | T; + }): Promise { + return opts.fn(); + }, getInitiatorCredentials: () => Promise.resolve(credentials), task: { id: 'mock-task-id', From afd90afb3799e120fef15d8e6a667920ef4b86b0 Mon Sep 17 00:00:00 2001 From: Bogdan Nechyporenko Date: Thu, 6 Feb 2025 19:20:45 +0100 Subject: [PATCH 2/3] wip Signed-off-by: Bogdan Nechyporenko --- .changeset/khaki-doors-jog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.changeset/khaki-doors-jog.md b/.changeset/khaki-doors-jog.md index 2ff6b44bf3..91ccc59ad5 100644 --- a/.changeset/khaki-doors-jog.md +++ b/.changeset/khaki-doors-jog.md @@ -1,5 +1,6 @@ --- '@backstage/plugin-scaffolder-backend-module-gitlab': patch +'@backstage/scaffolder-node-test-utils': patch --- Made gitlab:issues:create action idempotent. From acd13fe94d108e4ac672f6bf32f98fe893ff0aed Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 18 Feb 2025 09:08:54 +0100 Subject: [PATCH 3/3] chore: remove package from changesfet Signed-off-by: blam --- .changeset/khaki-doors-jog.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.changeset/khaki-doors-jog.md b/.changeset/khaki-doors-jog.md index 91ccc59ad5..2ff6b44bf3 100644 --- a/.changeset/khaki-doors-jog.md +++ b/.changeset/khaki-doors-jog.md @@ -1,6 +1,5 @@ --- '@backstage/plugin-scaffolder-backend-module-gitlab': patch -'@backstage/scaffolder-node-test-utils': patch --- Made gitlab:issues:create action idempotent.