From 439e2986be1edba30d66d569de09e40ac6bd953b Mon Sep 17 00:00:00 2001 From: Andreas Berger Date: Tue, 21 Mar 2023 09:52:44 +0100 Subject: [PATCH] add new scaffolder action to ensure a gitlab group exists Signed-off-by: Andreas Berger --- .changeset/moody-shrimps-train.md | 5 + .../README.md | 14 +- .../api-report.md | 28 +++- .../package.json | 3 +- ...reateGitlabGroupEnsureExistsAction.test.ts | 140 ++++++++++++++++++ .../createGitlabGroupEnsureExistsAction.ts | 93 ++++++++++++ .../createGitlabProjectAccessTokenAction.ts | 79 +++------- .../createGitlabProjectDeployTokenAction.ts | 82 +++------- .../createGitlabProjectVariableAction.ts | 125 +++++----------- .../src/commonGitlabConfig.ts | 26 ++++ .../src/index.ts | 5 +- .../src/util.ts | 11 +- yarn.lock | 8 + 13 files changed, 401 insertions(+), 218 deletions(-) create mode 100644 .changeset/moody-shrimps-train.md create mode 100644 plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.test.ts create mode 100644 plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.ts create mode 100644 plugins/scaffolder-backend-module-gitlab/src/commonGitlabConfig.ts diff --git a/.changeset/moody-shrimps-train.md b/.changeset/moody-shrimps-train.md new file mode 100644 index 0000000000..397500e2cb --- /dev/null +++ b/.changeset/moody-shrimps-train.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend-module-gitlab': minor +--- + +Add a new scaffolder action for gitlab to ensure a group exists diff --git a/plugins/scaffolder-backend-module-gitlab/README.md b/plugins/scaffolder-backend-module-gitlab/README.md index 35353cf9c1..d071ca0cf6 100644 --- a/plugins/scaffolder-backend-module-gitlab/README.md +++ b/plugins/scaffolder-backend-module-gitlab/README.md @@ -45,6 +45,9 @@ const actions = [ createGitlabProjectDeployTokenAction({ integrations: integrations, }), + createGitlabGroupEnsureExistsAction({ + integrations: integrations, + }), ]; // Create Scaffolder Router @@ -104,13 +107,22 @@ spec: url: https://github.com/TEMPLATE values: name: ${{ parameters.name }} + - id: createGitlabGroup + name: Ensure Gitlab group exists + action: gitlab:group:ensureExists + input: + repoUrl: ${{ parameters.repoUrl }} + path: + - path + - to + - group - id: publish name: Publish action: publish:gitlab input: description: This is ${{ parameters.name }} - repoUrl: ${{ parameters.repoUrl }} + repoUrl: ${{ parameters.repoUrl }}?owner=${{ steps.createGitlabGroup.output.groupId }} sourcePath: pimcore defaultBranch: main diff --git a/plugins/scaffolder-backend-module-gitlab/api-report.md b/plugins/scaffolder-backend-module-gitlab/api-report.md index 2ec05e74de..ee7f1b3a21 100644 --- a/plugins/scaffolder-backend-module-gitlab/api-report.md +++ b/plugins/scaffolder-backend-module-gitlab/api-report.md @@ -7,6 +7,18 @@ import { JsonObject } from '@backstage/types'; import { ScmIntegrationRegistry } from '@backstage/integration'; import { TemplateAction } from '@backstage/plugin-scaffolder-node'; +// @public +export const createGitlabGroupEnsureExistsAction: (options: { + integrations: ScmIntegrationRegistry; +}) => TemplateAction< + { + repoUrl: string; + token?: string | undefined; + } & { + path: string[]; + } +>; + // @public export const createGitlabProjectAccessTokenAction: (options: { integrations: ScmIntegrationRegistry; @@ -43,16 +55,18 @@ export const createGitlabProjectVariableAction: (options: { }) => TemplateAction< { repoUrl: string; - projectId: string | number; + token?: string | undefined; + } & { key: string; value: string; + projectId: string | number; variableType: string; - variableProtected: boolean; - masked: boolean; - raw: boolean; - environmentScope: string; - token?: string | undefined; - }, + variableProtected?: boolean | undefined; + masked?: boolean | undefined; + raw?: boolean | undefined; + environmentScope?: string | undefined; + } +, JsonObject >; ``` diff --git a/plugins/scaffolder-backend-module-gitlab/package.json b/plugins/scaffolder-backend-module-gitlab/package.json index e870ba57a0..22038427ad 100644 --- a/plugins/scaffolder-backend-module-gitlab/package.json +++ b/plugins/scaffolder-backend-module-gitlab/package.json @@ -35,7 +35,8 @@ "@backstage/errors": "workspace:^", "@backstage/integration": "workspace:^", "@backstage/plugin-scaffolder-node": "workspace:^", - "@gitbeaker/node": "^35.8.0" + "@gitbeaker/node": "^35.8.0", + "zod": "^3.21.4" }, "devDependencies": { "@backstage/backend-common": "workspace:^", diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.test.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.test.ts new file mode 100644 index 0000000000..6fb119413f --- /dev/null +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.test.ts @@ -0,0 +1,140 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { PassThrough } from 'stream'; +import { createGitlabGroupEnsureExistsAction } from './createGitlabGroupEnsureExistsAction'; +import { getVoidLogger } from '@backstage/backend-common'; +import { ConfigReader } from '@backstage/core-app-api'; +import { ScmIntegrations } from '@backstage/integration'; + +const mockGitlabClient = { + Groups: { + search: jest.fn(), + create: jest.fn(), + }, +}; +jest.mock('@gitbeaker/node', () => ({ + Gitlab: class { + constructor() { + return mockGitlabClient; + } + }, +})); + +describe('gitlab:group:ensureExists', () => { + const mockContext = { + workspacePath: 'lol', + logger: getVoidLogger(), + logStream: new PassThrough(), + output: jest.fn(), + createTemporaryDirectory: jest.fn(), + }; + + afterEach(() => { + jest.resetAllMocks(); + }); + + it('should create a new group if it does not exists', async () => { + mockGitlabClient.Groups.search.mockResolvedValue([ + { + id: 1, + full_path: 'repos/bar', + }, + { + id: 2, + full_path: 'repos/foo', + }, + ]); + + mockGitlabClient.Groups.create.mockResolvedValue({ + id: 3, + full_path: 'repos/foo/bar', + }); + + const config = new ConfigReader({ + integrations: { + gitlab: [ + { + host: 'gitlab.com', + token: 'tokenlols', + apiBaseUrl: 'https://api.gitlab.com', + }, + ], + }, + }); + const integrations = ScmIntegrations.fromConfig(config); + + const action = createGitlabGroupEnsureExistsAction({ integrations }); + + await action.handler({ + ...mockContext, + input: { + repoUrl: 'gitlab.com', + path: ['foo', 'bar'], + }, + }); + + expect(mockGitlabClient.Groups.create).toHaveBeenCalledWith('bar', 'bar', { + parent_id: 2, + }); + + expect(mockContext.output).toHaveBeenCalledWith('groupId', 3); + }); + + it('should return existing group if it does exists', async () => { + mockGitlabClient.Groups.search.mockResolvedValue([ + { + id: 1, + full_path: 'repos/bar', + }, + { + id: 2, + full_path: 'repos/foo', + }, + { + id: 42, + full_path: 'repos/foo/bar', + }, + ]); + + const config = new ConfigReader({ + integrations: { + gitlab: [ + { + host: 'gitlab.com', + token: 'tokenlols', + apiBaseUrl: 'https://api.gitlab.com', + }, + ], + }, + }); + const integrations = ScmIntegrations.fromConfig(config); + + const action = createGitlabGroupEnsureExistsAction({ integrations }); + + await action.handler({ + ...mockContext, + input: { + repoUrl: 'gitlab.com', + path: ['foo', 'bar'], + }, + }); + + expect(mockGitlabClient.Groups.create).not.toHaveBeenCalled(); + + expect(mockContext.output).toHaveBeenCalledWith('groupId', 42); + }); +}); diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.ts new file mode 100644 index 0000000000..8161b4d006 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabGroupEnsureExistsAction.ts @@ -0,0 +1,93 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; +import { ScmIntegrationRegistry } from '@backstage/integration'; +import { Gitlab } from '@gitbeaker/node'; +import { GroupSchema } from '@gitbeaker/core/dist/types/resources/Groups'; +import commonGitlabConfig from '../commonGitlabConfig'; +import { getToken } from '../util'; +import { z } from 'zod'; + +const input = commonGitlabConfig.and( + z.object({ + path: z + .array(z.string(), { + description: 'A path of group names that is ensured to exist', + }) + .min(1), + }), +); + +const output = z.object({ + groupId: z.string({ description: 'The id of the innermost sub-group' }), +}); + +/** + * Creates an `gitlab:group:ensureExists` Scaffolder action. + * + * @public + */ +export const createGitlabGroupEnsureExistsAction = (options: { + integrations: ScmIntegrationRegistry; +}) => { + const { integrations } = options; + + return createTemplateAction>({ + id: 'gitlab:group:ensureExists', + description: 'Ensures a Gitlab group exists', + schema: { input, output }, + async handler(ctx) { + const { path } = ctx.input; + const { token, integrationConfig } = getToken(ctx.input, integrations); + + const api = new Gitlab({ + host: integrationConfig.config.baseUrl, + token: token, + }); + + let currentPath: string = 'repos'; + let parent: GroupSchema | null = null; + for (const pathElement of path) { + const fullPath = `${currentPath}/${pathElement}`; + const result = (await api.Groups.search( + fullPath, + )) as any as Array; + const subGroup = result.find( + searchPathElem => searchPathElem.full_path === fullPath, + ); + if (!subGroup) { + ctx.logger.info(`creating missing group ${fullPath}`); + parent = await api.Groups.create( + pathElement, + pathElement, + parent + ? { + parent_id: parent.id, + } + : {}, + ); + } else { + parent = subGroup; + } + currentPath = fullPath; + } + if (parent !== null) { + ctx.output('groupId', parent?.id); + } + }, + }); +}; diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectAccessTokenAction.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectAccessTokenAction.ts index 0f39e3bc33..d295d7cc07 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectAccessTokenAction.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectAccessTokenAction.ts @@ -16,10 +16,27 @@ import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import { ScmIntegrationRegistry } from '@backstage/integration'; +import commonGitlabConfig from '../commonGitlabConfig'; import { getToken } from '../util'; +import { z } from 'zod'; + +const input = commonGitlabConfig.and( + z.object({ + projectId: z.union([z.number(), z.string()], { description: 'Project ID' }), + name: z.string({ description: 'Deploy Token Name' }).optional(), + accessLevel: z + .string({ description: 'Access Level of the Token' }) + .optional(), + scopes: z.array(z.string(), { description: 'Scopes' }).optional(), + }), +); + +const output = z.object({ + access_token: z.string({ description: 'Access Token' }), +}); /** - * Creates a `gitlab:create-project-access-token` Scaffolder action. + * Creates a `gitlab:projectAccessToken:create` Scaffolder action. * * @param options - Templating configuration. * @public @@ -28,65 +45,13 @@ export const createGitlabProjectAccessTokenAction = (options: { integrations: ScmIntegrationRegistry; }) => { const { integrations } = options; - return createTemplateAction<{ - repoUrl: string; - projectId: string | number; - name: string; - accessLevel: number; - scopes: string[]; - token?: string; - }>({ + return createTemplateAction>({ id: 'gitlab:projectAccessToken:create', - schema: { - input: { - required: ['projectId', 'repoUrl'], - type: 'object', - properties: { - repoUrl: { - title: 'Repository Location', - type: 'string', - }, - projectId: { - title: 'Project ID', - type: ['string', 'number'], - }, - name: { - title: 'Deploy Token Name', - type: 'string', - }, - accessLevel: { - title: 'Access Level of the Token', - type: 'number', - }, - scopes: { - title: 'Scopes', - type: 'array', - }, - token: { - title: 'Authentication Token', - type: 'string', - description: 'The token to use for authorization to GitLab', - }, - }, - }, - output: { - type: 'object', - properties: { - access_token: { - title: 'Access Token', - type: 'string', - }, - }, - }, - }, + schema: { input, output }, async handler(ctx) { ctx.logger.info(`Creating Token for Project "${ctx.input.projectId}"`); - const { repoUrl, projectId, name, accessLevel, scopes } = ctx.input; - const { token, integrationConfig } = getToken( - repoUrl, - ctx.input.token, - integrations, - ); + const { projectId, name, accessLevel, scopes } = ctx.input; + const { token, integrationConfig } = getToken(ctx.input, integrations); const response = await fetch( `${integrationConfig.config.baseUrl}/api/v4/projects/${projectId}/access_tokens`, diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.ts index 35a53c87e2..46feaad39f 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectDeployTokenAction.ts @@ -18,11 +18,27 @@ import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import { Gitlab } from '@gitbeaker/node'; import { ScmIntegrationRegistry } from '@backstage/integration'; import { DeployTokenScope } from '@gitbeaker/core/dist/types/templates/ResourceDeployTokens'; +import commonGitlabConfig from '../commonGitlabConfig'; import { getToken } from '../util'; import { InputError } from '@backstage/errors'; +import { z } from 'zod'; + +const input = commonGitlabConfig.and( + z.object({ + projectId: z.union([z.number(), z.string()], { description: 'Project ID' }), + name: z.string({ description: 'Deploy Token Name' }), + username: z.string({ description: 'Deploy Token Username' }).optional(), + scopes: z.array(z.string(), { description: 'Scopes' }).optional(), + }), +); + +const output = z.object({ + deploy_token: z.string({ description: 'Deploy Token' }), + user: z.string({ description: 'User' }), +}); /** - * Creates a `gitlab:create-project-deploy-token` Scaffolder action. + * Creates a `gitlab:projectDeployToken:create` Scaffolder action. * * @param options - Templating configuration. * @public @@ -31,69 +47,13 @@ export const createGitlabProjectDeployTokenAction = (options: { integrations: ScmIntegrationRegistry; }) => { const { integrations } = options; - return createTemplateAction<{ - repoUrl: string; - projectId: string | number; - name: string; - username: string; - scopes: string[]; - token?: string; - }>({ + return createTemplateAction>({ id: 'gitlab:projectDeployToken:create', - schema: { - input: { - required: ['projectId', 'repoUrl'], - type: 'object', - properties: { - repoUrl: { - title: 'Repository Location', - type: 'string', - }, - projectId: { - title: 'Project ID', - type: ['string', 'number'], - }, - name: { - title: 'Deploy Token Name', - type: 'string', - }, - username: { - title: 'Deploy Token Username', - type: 'string', - }, - scopes: { - title: 'Scopes', - type: 'array', - }, - token: { - title: 'Authentication Token', - type: 'string', - description: 'The token to use for authorization to GitLab', - }, - }, - }, - output: { - type: 'object', - properties: { - deploy_token: { - title: 'Deploy Token', - type: 'string', - }, - user: { - title: 'User', - type: 'string', - }, - }, - }, - }, + schema: { input, output }, async handler(ctx) { ctx.logger.info(`Creating Token for Project "${ctx.input.projectId}"`); - const { repoUrl, projectId, name, username, scopes } = ctx.input; - const { token, integrationConfig } = getToken( - repoUrl, - ctx.input.token, - integrations, - ); + const { projectId, name, username, scopes } = ctx.input; + const { token, integrationConfig } = getToken(ctx.input, integrations); const api = new Gitlab({ host: integrationConfig.config.baseUrl, diff --git a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectVariableAction.ts b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectVariableAction.ts index 847bbc2057..a66d6242ee 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectVariableAction.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/actions/createGitlabProjectVariableAction.ts @@ -16,11 +16,43 @@ import { createTemplateAction } from '@backstage/plugin-scaffolder-node'; import { ScmIntegrationRegistry } from '@backstage/integration'; -import { getToken } from '../util'; import { Gitlab } from '@gitbeaker/node'; +import { getToken } from '../util'; +import commonGitlabConfig from '../commonGitlabConfig'; +import { z } from 'zod'; + +const input = commonGitlabConfig.and( + z.object({ + projectId: z.union([z.number(), z.string()], { description: 'Project ID' }), + key: z + .string({ + description: + 'The key of a variable; must have no more than 255 characters; only A-Z, a-z, 0-9, and _ are allowed', + }) + .regex(/^[A-Za-z0-9_]{1,255}$/), + value: z.string({ description: 'The value of a variable' }), + variableType: z.string({ description: 'Variable Type (env_var or file)' }), + variableProtected: z + .boolean({ description: 'Whether the variable is protected' }) + .default(false) + .optional(), + masked: z + .boolean({ description: 'Whether the variable is masked' }) + .default(false) + .optional(), + raw: z + .boolean({ description: 'Whether the variable is expandable' }) + .default(false) + .optional(), + environmentScope: z + .string({ description: 'The environment_scope of the variable' }) + .default('*') + .optional(), + }), +); /** - * Creates a `gitlab:create-project-variable` Scaffolder action. + * Creates a `gitlab:projectVariable:create` Scaffolder action. * * @param options - Templating configuration. * @public @@ -29,96 +61,21 @@ export const createGitlabProjectVariableAction = (options: { integrations: ScmIntegrationRegistry; }) => { const { integrations } = options; - return createTemplateAction<{ - repoUrl: string; - projectId: string | number; - key: string; - value: string; - variableType: string; - variableProtected: boolean; - masked: boolean; - raw: boolean; - environmentScope: string; - token?: string; - }>({ + return createTemplateAction>({ id: 'gitlab:projectVariable:create', - schema: { - input: { - required: [ - 'repoUrl', - 'projectId', - 'key', - 'value', - 'variableType', - 'variableProtected', - 'masked', - 'raw', - 'environmentScope', - ], - type: 'object', - properties: { - repoUrl: { - title: 'Repository Location', - type: 'string', - }, - projectId: { - title: 'Project ID', - type: ['string', 'number'], - }, - key: { - title: - 'The key of a variable; must have no more than 255 characters; only A-Z, a-z, 0-9, and _ are allowed', - type: 'string', - }, - value: { - title: 'The value of a variable', - type: 'string', - }, - variableType: { - title: 'Variable Type (env_var or file)', - type: 'string', - }, - variableProtected: { - title: 'Whether the variable is protected. Default: false', - type: 'boolean', - }, - masked: { - title: 'Whether the variable is masked. Default: false', - type: 'boolean', - }, - raw: { - title: 'Whether the variable is expandable. Default: false', - type: 'boolean', - }, - environmentScope: { - title: 'The environment_scope of the variable. Default: *', - type: 'string', - }, - token: { - title: 'Authentication Token', - type: 'string', - description: 'The token to use for authorization to GitLab', - }, - }, - }, - }, + schema: { input }, async handler(ctx) { const { - repoUrl, projectId, key, value, variableType, - variableProtected, - masked, - raw, - environmentScope, + variableProtected = false, + masked = false, + raw = false, + environmentScope = '*', } = ctx.input; - const { token, integrationConfig } = getToken( - repoUrl, - ctx.input.token, - integrations, - ); + const { token, integrationConfig } = getToken(ctx.input, integrations); const api = new Gitlab({ host: integrationConfig.config.baseUrl, diff --git a/plugins/scaffolder-backend-module-gitlab/src/commonGitlabConfig.ts b/plugins/scaffolder-backend-module-gitlab/src/commonGitlabConfig.ts new file mode 100644 index 0000000000..02724a3674 --- /dev/null +++ b/plugins/scaffolder-backend-module-gitlab/src/commonGitlabConfig.ts @@ -0,0 +1,26 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { z } from 'zod'; + +const commonGitlabConfig = z.object({ + repoUrl: z.string({ description: 'Repository Location' }), + token: z + .string({ description: 'The token to use for authorization to GitLab' }) + .optional(), +}); + +export default commonGitlabConfig; diff --git a/plugins/scaffolder-backend-module-gitlab/src/index.ts b/plugins/scaffolder-backend-module-gitlab/src/index.ts index 11209e19bd..4fd4dee35b 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/index.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/index.ts @@ -13,12 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + /** - * A module for the scaffolder backend that lets you create gitlab project access tokens or deploy tokens + * A module for the scaffolder backend that lets you interact with gitlab * * @packageDocumentation */ - +export * from './actions/createGitlabGroupEnsureExistsAction'; export * from './actions/createGitlabProjectDeployTokenAction'; export * from './actions/createGitlabProjectAccessTokenAction'; export * from './actions/createGitlabProjectVariableAction'; diff --git a/plugins/scaffolder-backend-module-gitlab/src/util.ts b/plugins/scaffolder-backend-module-gitlab/src/util.ts index fc6667d6d3..13c95e48e8 100644 --- a/plugins/scaffolder-backend-module-gitlab/src/util.ts +++ b/plugins/scaffolder-backend-module-gitlab/src/util.ts @@ -19,6 +19,8 @@ import { GitLabIntegration, ScmIntegrationRegistry, } from '@backstage/integration'; +import { z } from 'zod'; +import commonGitlabConfig from './commonGitlabConfig'; export const parseRepoHost = (repoUrl: string): string => { let parsed; @@ -33,11 +35,10 @@ export const parseRepoHost = (repoUrl: string): string => { }; export const getToken = ( - repoUrl: string, - inputToken: string | null | undefined, + config: z.infer, integrations: ScmIntegrationRegistry, ): { token: string; integrationConfig: GitLabIntegration } => { - const host = parseRepoHost(repoUrl); + const host = parseRepoHost(config.repoUrl); const integrationConfig = integrations.gitlab.byHost(host); if (!integrationConfig) { @@ -46,8 +47,8 @@ export const getToken = ( ); } - const token = inputToken || integrationConfig.config.token!; - const tokenType = inputToken ? 'oauthToken' : 'token'; + const token = config.token || integrationConfig.config.token!; + const tokenType = config.token ? 'oauthToken' : 'token'; if (tokenType === 'oauthToken') { throw new InputError(`OAuth Token is currently not supported`); diff --git a/yarn.lock b/yarn.lock index 9c8dd2b64e..70a7ed3f3c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7855,6 +7855,7 @@ __metadata: "@backstage/integration": "workspace:^" "@backstage/plugin-scaffolder-node": "workspace:^" "@gitbeaker/node": ^35.8.0 + zod: ^3.21.4 languageName: unknown linkType: soft @@ -40593,6 +40594,13 @@ __metadata: languageName: node linkType: hard +"zod@npm:^3.21.4": + version: 3.21.4 + resolution: "zod@npm:3.21.4" + checksum: f185ba87342ff16f7a06686767c2b2a7af41110c7edf7c1974095d8db7a73792696bcb4a00853de0d2edeb34a5b2ea6a55871bc864227dace682a0a28de33e1f + languageName: node + linkType: hard + "zod@npm:~3.18.0": version: 3.18.0 resolution: "zod@npm:3.18.0"