update gitlab scaffolder

Signed-off-by: Dominik Pfaffenbauer <dominik@pfaffenbauer.at>
This commit is contained in:
Dominik Pfaffenbauer
2023-02-16 08:41:04 +01:00
parent 7153033b86
commit 6068251a8e
9 changed files with 120 additions and 66 deletions
@@ -6,14 +6,58 @@ 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):
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 {
createGitlabProjectVariable,
createGitlabProjectAccessToken,
createGitlabProjectDeployToken,
} 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,
createGitlabProjectVariable({
integrations: integrations,
}),
createGitlabProjectAccessToken({
integrations: integrations,
}),
createGitlabProjectDeployToken({
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:
@@ -51,6 +51,4 @@ export const createGitlabProjectVariable: (options: {
environmentScope: string;
token?: string | undefined;
}>;
// (No @packageDocumentation comment for this package)
```
@@ -40,17 +40,11 @@
"@gitbeaker/node": "^35.8.0",
"fs-extra": "10.1.0"
},
"peerDependencies": {
"react": "^16.13.1 || ^17.0.0"
},
"devDependencies": {
"@backstage/cli": "workspace:^",
"@backstage/core-app-api": "workspace:^",
"@backstage/dev-utils": "workspace:^",
"@backstage/test-utils": "workspace:^",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^14.0.0",
"@types/node": "*",
"cross-fetch": "^3.1.5",
"msw": "^0.49.0"
@@ -16,8 +16,7 @@
import { createTemplateAction } from '@backstage/plugin-scaffolder-backend';
import { ScmIntegrationRegistry } from '@backstage/integration';
import { InputError } from '@backstage/errors';
import { parseRepoHost } from '../util';
import { getToken } from '../util';
export const createGitlabProjectAccessToken = (options: {
integrations: ScmIntegrationRegistry;
@@ -64,26 +63,24 @@ export const createGitlabProjectAccessToken = (options: {
},
},
},
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 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 = ctx.input.token || integrationConfig.config.token!;
const tokenType = ctx.input.token ? 'oauthToken' : 'token';
if (tokenType === 'oauthToken') {
throw new InputError(`OAuth Token is currently not supported`);
}
const { token, integrationConfig } = getToken(
repoUrl,
ctx.input.token,
integrations,
);
const response = await fetch(
`${integrationConfig.config.baseUrl}/api/v4/projects/${projectId}/access_tokens`,
@@ -18,7 +18,6 @@ import { createGitlabProjectDeployToken } from './createProjectDeployToken';
import { ScmIntegrations } from '@backstage/integration';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
// eslint-disable-next-line no-restricted-imports
import { PassThrough } from 'stream';
const mockGitlabClient = {
@@ -17,9 +17,8 @@
import { createTemplateAction } from '@backstage/plugin-scaffolder-backend';
import { Gitlab } from '@gitbeaker/node';
import { ScmIntegrationRegistry } from '@backstage/integration';
import { InputError } from '@backstage/errors';
import { DeployTokenScope } from '@gitbeaker/core/dist/types/templates/ResourceDeployTokens';
import { parseRepoHost } from '../util';
import { getToken } from '../util';
export const createGitlabProjectDeployToken = (options: {
integrations: ScmIntegrationRegistry;
@@ -66,26 +65,28 @@ export const createGitlabProjectDeployToken = (options: {
},
},
},
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 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 = ctx.input.token || integrationConfig.config.token!;
const tokenType = ctx.input.token ? 'oauthToken' : 'token';
if (tokenType === 'oauthToken') {
throw new InputError(`OAuth Token is currently not supported`);
}
const { token, integrationConfig } = getToken(
repoUrl,
ctx.input.token,
integrations,
);
const api = new Gitlab({
host: integrationConfig.config.baseUrl,
@@ -16,8 +16,7 @@
import { createTemplateAction } from '@backstage/plugin-scaffolder-backend';
import { ScmIntegrationRegistry } from '@backstage/integration';
import { InputError } from '@backstage/errors';
import { parseRepoHost } from '../util';
import { getToken } from '../util';
import { Gitlab } from '@gitbeaker/node';
export const createGitlabProjectVariable = (options: {
@@ -104,22 +103,11 @@ export const createGitlabProjectVariable = (options: {
raw,
environmentScope,
} = ctx.input;
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 = ctx.input.token || integrationConfig.config.token!;
const tokenType = ctx.input.token ? 'oauthToken' : 'token';
if (tokenType === 'oauthToken') {
throw new InputError(`OAuth Token is currently not supported`);
}
const { token, integrationConfig } = getToken(
repoUrl,
ctx.input.token,
integrations,
);
const api = new Gitlab({
host: integrationConfig.config.baseUrl,
@@ -13,6 +13,11 @@
* 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/createProjectDeployToken';
export * from './actions/createProjectAccessToken';
@@ -15,6 +15,10 @@
*/
import { InputError } from '@backstage/errors';
import {
GitLabIntegration,
ScmIntegrationRegistry,
} from '@backstage/integration';
export const parseRepoHost = (repoUrl: string): string => {
let parsed;
@@ -27,3 +31,27 @@ export const parseRepoHost = (repoUrl: string): string => {
}
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 };
};