Merge pull request #15641 from dpfaffenbauer/scaffolder-gitlab
Add Scaffolder Gitlab Plugin
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-gitlab': minor
|
||||
---
|
||||
|
||||
Add Gitlab Scaffolder Plugin
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
|
||||
@@ -0,0 +1,162 @@
|
||||
# scaffolder-backend-module-gitlab
|
||||
|
||||
Welcome to the Gitlab Module for Scaffolder.
|
||||
|
||||
Here you can find all Gitlab related features to improve your scaffolder:
|
||||
|
||||
## Getting started
|
||||
|
||||
## From your Backstage root directory
|
||||
|
||||
```bash
|
||||
# From your Backstage root directory
|
||||
yarn add --cwd packages/backend @backstage/plugin-scaffolder-backend-module-gitlab
|
||||
```
|
||||
|
||||
Configure the action:
|
||||
(you can check the [docs](https://backstage.io/docs/features/software-templates/writing-custom-actions#registering-custom-actions) to see all options):
|
||||
|
||||
```typescript
|
||||
// packages/backend/src/plugins/scaffolder.ts
|
||||
|
||||
import {
|
||||
createGitlabProjectAccessTokenAction,
|
||||
createGitlabProjectAccessTokenAction,
|
||||
createGitlabProjectDeployTokenAction,
|
||||
} from '@backstage/plugin-scaffolder-backend-module-gitlab';
|
||||
|
||||
// Create BuiltIn Actions
|
||||
const builtInActions = createBuiltinActions({
|
||||
integrations,
|
||||
catalogClient,
|
||||
config: env.config,
|
||||
reader: env.reader,
|
||||
});
|
||||
|
||||
// Add Gitlab Actions
|
||||
const actions = [
|
||||
...builtInActions,
|
||||
createGitlabProjectAccessTokenAction({
|
||||
integrations: integrations,
|
||||
}),
|
||||
createGitlabProjectAccessTokenAction({
|
||||
integrations: integrations,
|
||||
}),
|
||||
createGitlabProjectDeployTokenAction({
|
||||
integrations: integrations,
|
||||
}),
|
||||
];
|
||||
|
||||
// Create Scaffolder Router
|
||||
return await createRouter({
|
||||
containerRunner,
|
||||
catalogClient,
|
||||
actions,
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
database: env.database,
|
||||
reader: env.reader,
|
||||
});
|
||||
```
|
||||
|
||||
After that you can use the action in your template:
|
||||
|
||||
```yaml
|
||||
apiVersion: scaffolder.backstage.io/v1beta3
|
||||
kind: Template
|
||||
metadata:
|
||||
name: gitlab-demo
|
||||
title: Gitlab DEMO
|
||||
description: Scaffolder Gitlab Demo
|
||||
spec:
|
||||
owner: backstage/techdocs-core
|
||||
type: service
|
||||
|
||||
parameters:
|
||||
- title: Fill in some steps
|
||||
required:
|
||||
- name
|
||||
properties:
|
||||
name:
|
||||
title: Name
|
||||
type: string
|
||||
description: Unique name of the component
|
||||
ui:autofocus: true
|
||||
ui:options:
|
||||
rows: 5
|
||||
- title: Choose a location
|
||||
required:
|
||||
- repoUrl
|
||||
properties:
|
||||
repoUrl:
|
||||
title: Repository Location
|
||||
type: string
|
||||
ui:field: RepoUrlPicker
|
||||
ui:options:
|
||||
allowedHosts:
|
||||
- gitlab.com
|
||||
|
||||
steps:
|
||||
- id: fetch
|
||||
name: Fetch
|
||||
action: fetch:template
|
||||
input:
|
||||
url: https://github.com/TEMPLATE
|
||||
values:
|
||||
name: ${{ parameters.name }}
|
||||
|
||||
- id: publish
|
||||
name: Publish
|
||||
action: publish:gitlab
|
||||
input:
|
||||
description: This is ${{ parameters.name }}
|
||||
repoUrl: ${{ parameters.repoUrl }}
|
||||
sourcePath: pimcore
|
||||
defaultBranch: main
|
||||
|
||||
- id: gitlab-deploy-token
|
||||
name: Create Deploy Token
|
||||
action: gitlab:projectDeployToken:create
|
||||
input:
|
||||
repoUrl: ${{ parameters.repoUrl }}
|
||||
projectId: "${{ steps['publish'].output.projectId }}"
|
||||
name: ${{ parameters.name }}-secret
|
||||
username: ${{ parameters.name }}-secret
|
||||
scopes: ['read_registry']
|
||||
|
||||
- id: gitlab-access-token
|
||||
name: Gitlab Project Access Token
|
||||
action: gitlab:projectAccessToken:create
|
||||
input:
|
||||
repoUrl: ${{ parameters.repoUrl }}
|
||||
projectId: "${{ steps['publish-manifest'].output.projectId }}"
|
||||
name: ${{ parameters.name }}-access-token
|
||||
accessLevel: 40
|
||||
scopes: ['read_repository', 'write_repository']
|
||||
|
||||
- id: gitlab-project-variable
|
||||
name: Gitlab Project Variable
|
||||
action: gitlab:projectVariable:create
|
||||
input:
|
||||
repoUrl: ${{ parameters.repoUrl }}
|
||||
projectId: "${{ steps['publish'].output.projectId }}"
|
||||
key: 'VARIABLE_NAME'
|
||||
value: "${{ steps['gitlab-access-token'].output.access_token }}"
|
||||
variableType: 'env_var'
|
||||
masked: true
|
||||
variableProtected: false
|
||||
raw: false
|
||||
environmentScope: '*'
|
||||
|
||||
- id: register
|
||||
name: Register
|
||||
action: catalog:register
|
||||
input:
|
||||
repoContentsUrl: ${{ steps['publish'].output.repoContentsUrl }}
|
||||
catalogInfoPath: '/catalog-info.yaml'
|
||||
|
||||
output:
|
||||
links:
|
||||
- title: Repository
|
||||
url: ${{ steps['publish'].output.remoteUrl }}
|
||||
```
|
||||
@@ -0,0 +1,48 @@
|
||||
## API Report File for "@backstage/plugin-scaffolder-backend-module-gitlab"
|
||||
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { ScmIntegrationRegistry } from '@backstage/integration';
|
||||
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
|
||||
|
||||
// @public
|
||||
export const createGitlabProjectAccessTokenAction: (options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
}) => TemplateAction<{
|
||||
repoUrl: string;
|
||||
projectId: string | number;
|
||||
name: string;
|
||||
accessLevel: number;
|
||||
scopes: string[];
|
||||
token?: string | undefined;
|
||||
}>;
|
||||
|
||||
// @public
|
||||
export const createGitlabProjectDeployTokenAction: (options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
}) => TemplateAction<{
|
||||
repoUrl: string;
|
||||
projectId: string | number;
|
||||
name: string;
|
||||
username: string;
|
||||
scopes: string[];
|
||||
token?: string | undefined;
|
||||
}>;
|
||||
|
||||
// @public
|
||||
export const createGitlabProjectVariableAction: (options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
}) => TemplateAction<{
|
||||
repoUrl: string;
|
||||
projectId: string | number;
|
||||
key: string;
|
||||
value: string;
|
||||
variableType: string;
|
||||
variableProtected: boolean;
|
||||
masked: boolean;
|
||||
raw: boolean;
|
||||
environmentScope: string;
|
||||
token?: string | undefined;
|
||||
}>;
|
||||
```
|
||||
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "@backstage/plugin-scaffolder-backend-module-gitlab",
|
||||
"version": "0.0.0",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.esm.js",
|
||||
"types": "dist/index.d.ts"
|
||||
},
|
||||
"backstage": {
|
||||
"role": "backend-plugin-module"
|
||||
},
|
||||
"homepage": "https://backstage.io",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/backstage/backstage",
|
||||
"directory": "plugins/scaffolder-backend-module-gitlab"
|
||||
},
|
||||
"keywords": [
|
||||
"backstage"
|
||||
],
|
||||
"scripts": {
|
||||
"start": "backstage-cli package start",
|
||||
"build": "backstage-cli package build",
|
||||
"lint": "backstage-cli package lint",
|
||||
"test": "backstage-cli package test",
|
||||
"clean": "backstage-cli package clean",
|
||||
"prepack": "backstage-cli package prepack",
|
||||
"postpack": "backstage-cli package postpack"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/config": "workspace:^",
|
||||
"@backstage/errors": "workspace:^",
|
||||
"@backstage/integration": "workspace:^",
|
||||
"@backstage/plugin-scaffolder-node": "workspace:^",
|
||||
"@gitbeaker/node": "^35.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-common": "workspace:^",
|
||||
"@backstage/cli": "workspace:^",
|
||||
"@backstage/core-app-api": "workspace:^"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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 { getToken } from '../util';
|
||||
|
||||
/**
|
||||
* Creates a `gitlab:create-project-access-token` Scaffolder action.
|
||||
*
|
||||
* @param options - Templating configuration.
|
||||
* @public
|
||||
*/
|
||||
export const createGitlabProjectAccessTokenAction = (options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
}) => {
|
||||
const { integrations } = options;
|
||||
return createTemplateAction<{
|
||||
repoUrl: string;
|
||||
projectId: string | number;
|
||||
name: string;
|
||||
accessLevel: number;
|
||||
scopes: string[];
|
||||
token?: string;
|
||||
}>({
|
||||
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',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
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 response = await fetch(
|
||||
`${integrationConfig.config.baseUrl}/api/v4/projects/${projectId}/access_tokens`,
|
||||
{
|
||||
method: 'POST', // *GET, POST, PUT, DELETE, etc.
|
||||
headers: {
|
||||
'PRIVATE-TOKEN': token,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: name,
|
||||
scopes: scopes,
|
||||
access_level: accessLevel,
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
ctx.output('access_token', result.token);
|
||||
},
|
||||
});
|
||||
};
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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 { createGitlabProjectDeployTokenAction } from './createGitlabProjectDeployTokenAction';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { getVoidLogger } from '@backstage/backend-common';
|
||||
import { PassThrough } from 'stream';
|
||||
|
||||
const mockGitlabClient = {
|
||||
ProjectDeployTokens: {
|
||||
add: jest.fn(),
|
||||
},
|
||||
};
|
||||
jest.mock('@gitbeaker/node', () => ({
|
||||
Gitlab: class {
|
||||
constructor() {
|
||||
return mockGitlabClient;
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
describe('gitlab:create-deploy-token', () => {
|
||||
const config = new ConfigReader({
|
||||
integrations: {
|
||||
gitlab: [
|
||||
{
|
||||
host: 'gitlab.com',
|
||||
token: 'tokenlols',
|
||||
apiBaseUrl: 'https://api.gitlab.com',
|
||||
},
|
||||
{
|
||||
host: 'hosted.gitlab.com',
|
||||
apiBaseUrl: 'https://api.hosted.gitlab.com',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
const action = createGitlabProjectDeployTokenAction({ integrations });
|
||||
const mockContext = {
|
||||
input: {
|
||||
repoUrl: 'gitlab.com?repo=repo&owner=owner',
|
||||
projectId: '123',
|
||||
name: 'tokenname',
|
||||
username: 'tokenuser',
|
||||
scopes: ['read_repository'],
|
||||
},
|
||||
workspacePath: 'lol',
|
||||
logger: getVoidLogger(),
|
||||
logStream: new PassThrough(),
|
||||
output: jest.fn(),
|
||||
createTemporaryDirectory: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it('should work when there is a token provided through ctx.input', async () => {
|
||||
mockGitlabClient.ProjectDeployTokens.add.mockResolvedValue({
|
||||
token: 'TOKEN',
|
||||
username: 'User',
|
||||
});
|
||||
|
||||
await action.handler({
|
||||
...mockContext,
|
||||
input: {
|
||||
repoUrl: 'hosted.gitlab.com?repo=bob&owner=owner',
|
||||
projectId: '123',
|
||||
name: 'tokenname',
|
||||
username: 'tokenuser',
|
||||
scopes: ['read_repository'],
|
||||
},
|
||||
});
|
||||
|
||||
expect(mockGitlabClient.ProjectDeployTokens.add).toHaveBeenCalledWith(
|
||||
'123',
|
||||
'tokenname',
|
||||
['read_repository'],
|
||||
{ username: 'tokenuser' },
|
||||
);
|
||||
|
||||
expect(mockContext.output).toHaveBeenCalledWith('deploy_token', 'TOKEN');
|
||||
expect(mockContext.output).toHaveBeenCalledWith('user', 'User');
|
||||
});
|
||||
});
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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 { Gitlab } from '@gitbeaker/node';
|
||||
import { ScmIntegrationRegistry } from '@backstage/integration';
|
||||
import { DeployTokenScope } from '@gitbeaker/core/dist/types/templates/ResourceDeployTokens';
|
||||
import { getToken } from '../util';
|
||||
import { InputError } from '@backstage/errors';
|
||||
|
||||
/**
|
||||
* Creates a `gitlab:create-project-deploy-token` Scaffolder action.
|
||||
*
|
||||
* @param options - Templating configuration.
|
||||
* @public
|
||||
*/
|
||||
export const createGitlabProjectDeployTokenAction = (options: {
|
||||
integrations: ScmIntegrationRegistry;
|
||||
}) => {
|
||||
const { integrations } = options;
|
||||
return createTemplateAction<{
|
||||
repoUrl: string;
|
||||
projectId: string | number;
|
||||
name: string;
|
||||
username: string;
|
||||
scopes: string[];
|
||||
token?: string;
|
||||
}>({
|
||||
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',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
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 api = new Gitlab({
|
||||
host: integrationConfig.config.baseUrl,
|
||||
token: token,
|
||||
});
|
||||
|
||||
const deployToken = await api.ProjectDeployTokens.add(
|
||||
projectId,
|
||||
name,
|
||||
scopes as DeployTokenScope[],
|
||||
{
|
||||
username: username,
|
||||
},
|
||||
);
|
||||
|
||||
if (!deployToken.hasOwnProperty('token')) {
|
||||
throw new InputError(`No deploy_token given from gitlab instance`);
|
||||
}
|
||||
|
||||
ctx.output('deploy_token', deployToken.token as string);
|
||||
ctx.output('user', deployToken.username);
|
||||
},
|
||||
});
|
||||
};
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* 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 { getToken } from '../util';
|
||||
import { Gitlab } from '@gitbeaker/node';
|
||||
|
||||
/**
|
||||
* Creates a `gitlab:create-project-variable` Scaffolder action.
|
||||
*
|
||||
* @param options - Templating configuration.
|
||||
* @public
|
||||
*/
|
||||
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;
|
||||
}>({
|
||||
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',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
async handler(ctx) {
|
||||
const {
|
||||
repoUrl,
|
||||
projectId,
|
||||
key,
|
||||
value,
|
||||
variableType,
|
||||
variableProtected,
|
||||
masked,
|
||||
raw,
|
||||
environmentScope,
|
||||
} = ctx.input;
|
||||
const { token, integrationConfig } = getToken(
|
||||
repoUrl,
|
||||
ctx.input.token,
|
||||
integrations,
|
||||
);
|
||||
|
||||
const api = new Gitlab({
|
||||
host: integrationConfig.config.baseUrl,
|
||||
token: token,
|
||||
});
|
||||
|
||||
await api.ProjectVariables.create(projectId, {
|
||||
key: key,
|
||||
value: value,
|
||||
variable_type: variableType,
|
||||
protected: variableProtected,
|
||||
masked: masked,
|
||||
raw: raw,
|
||||
environment_scope: environmentScope,
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* A module for the scaffolder backend that lets you create gitlab project access tokens or deploy tokens
|
||||
*
|
||||
* @packageDocumentation
|
||||
*/
|
||||
|
||||
export * from './actions/createGitlabProjectDeployTokenAction';
|
||||
export * from './actions/createGitlabProjectAccessTokenAction';
|
||||
export * from './actions/createGitlabProjectVariableAction';
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 { InputError } from '@backstage/errors';
|
||||
import {
|
||||
GitLabIntegration,
|
||||
ScmIntegrationRegistry,
|
||||
} from '@backstage/integration';
|
||||
|
||||
export const parseRepoHost = (repoUrl: string): string => {
|
||||
let parsed;
|
||||
try {
|
||||
parsed = new URL(`https://${repoUrl}`);
|
||||
} catch (error) {
|
||||
throw new InputError(
|
||||
`Invalid repo URL passed to publisher, got ${repoUrl}, ${error}`,
|
||||
);
|
||||
}
|
||||
return parsed.host;
|
||||
};
|
||||
|
||||
export const getToken = (
|
||||
repoUrl: string,
|
||||
inputToken: string | null | undefined,
|
||||
integrations: ScmIntegrationRegistry,
|
||||
): { token: string; integrationConfig: GitLabIntegration } => {
|
||||
const host = parseRepoHost(repoUrl);
|
||||
const integrationConfig = integrations.gitlab.byHost(host);
|
||||
|
||||
if (!integrationConfig) {
|
||||
throw new InputError(
|
||||
`No matching integration configuration for host ${host}, please check your integrations config`,
|
||||
);
|
||||
}
|
||||
|
||||
const token = inputToken || integrationConfig.config.token!;
|
||||
const tokenType = inputToken ? 'oauthToken' : 'token';
|
||||
|
||||
if (tokenType === 'oauthToken') {
|
||||
throw new InputError(`OAuth Token is currently not supported`);
|
||||
}
|
||||
|
||||
return { token: token, integrationConfig: integrationConfig };
|
||||
};
|
||||
@@ -7500,6 +7500,21 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@backstage/plugin-scaffolder-backend-module-gitlab@workspace:plugins/scaffolder-backend-module-gitlab":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@backstage/plugin-scaffolder-backend-module-gitlab@workspace:plugins/scaffolder-backend-module-gitlab"
|
||||
dependencies:
|
||||
"@backstage/backend-common": "workspace:^"
|
||||
"@backstage/cli": "workspace:^"
|
||||
"@backstage/config": "workspace:^"
|
||||
"@backstage/core-app-api": "workspace:^"
|
||||
"@backstage/errors": "workspace:^"
|
||||
"@backstage/integration": "workspace:^"
|
||||
"@backstage/plugin-scaffolder-node": "workspace:^"
|
||||
"@gitbeaker/node": ^35.8.0
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@backstage/plugin-scaffolder-backend-module-rails@workspace:^, @backstage/plugin-scaffolder-backend-module-rails@workspace:plugins/scaffolder-backend-module-rails":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@backstage/plugin-scaffolder-backend-module-rails@workspace:plugins/scaffolder-backend-module-rails"
|
||||
@@ -9856,7 +9871,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@gitbeaker/node@npm:^35.1.0":
|
||||
"@gitbeaker/node@npm:^35.1.0, @gitbeaker/node@npm:^35.8.0":
|
||||
version: 35.8.1
|
||||
resolution: "@gitbeaker/node@npm:35.8.1"
|
||||
dependencies:
|
||||
|
||||
Reference in New Issue
Block a user