Merge pull request #15639 from dpfaffenbauer/scaffolder-sentry

Add Scaffolder Sentry Plugin
This commit is contained in:
Ben Lambert
2023-01-11 16:34:27 +01:00
committed by GitHub
8 changed files with 397 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend-module-sentry': minor
---
Add Sentry "Create Project" Scaffolder as new package
@@ -0,0 +1 @@
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
@@ -0,0 +1,160 @@
# scaffolder-backend-module-sentry
Welcome to the Sentry Module for Scaffolder.
Here you can find all Sentry related features to improve your scaffolder:
## Getting started
You need to configure the action in your backend:
## From your Backstage root directory
```bash
# From your Backstage root directory
yarn add --cwd packages/backend @backstage/plugin-scaffolder-backend-module-sentry
```
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
const actions = [
createSentryCreateProjectAction({
integrations,
reader: env.reader,
containerRunner,
}),
];
return await createRouter({
containerRunner,
catalogClient,
actions,
logger: env.logger,
config: env.config,
database: env.database,
reader: env.reader,
});
```
You need to define your Sentry API Token in your `app-config.yaml`:
```yaml
scaffolder:
sentry:
token: ${SENTRY_TOKEN}
```
After that you can use the action in your template:
```yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: sentry-demo
title: Sentry template
description: scaffolder sentry app
spec:
owner: backstage/techdocs-core
type: service
parameters:
- title: Fill in some steps
required:
- name
- owner
properties:
name:
title: Name
type: string
description: Unique name of the component
ui:autofocus: true
ui:options:
rows: 5
owner:
title: Owner
type: string
description: Owner of the component
ui:field: OwnerPicker
ui:options:
catalogFilter:
kind: Group
system:
title: System
type: string
description: System of the component
ui:field: EntityPicker
ui:options:
catalogFilter:
kind: System
defaultKind: System
- title: Choose a location
required:
- repoUrl
- dryRun
properties:
repoUrl:
title: Repository Location
type: string
ui:field: RepoUrlPicker
ui:options:
allowedHosts:
- github.com
dryRun:
title: Only perform a dry run, don't publish anything
type: boolean
default: false
steps:
- id: fetch
name: Fetch
action: fetch:template
input:
url: https://github.com/TEMPLATE
values:
name: ${{ parameters.name }}
- id: create-sentry-project
if: ${{ parameters.dryRun !== true }}
name: Create Sentry Project
action: sentry:create-project
input:
organizationSlug: ORG-SLUG
teamSlug: TEAM-SLUG
name: ${{ parameters.name }}
- id: publish
if: ${{ parameters.dryRun !== true }}
name: Publish
action: publish:github
input:
allowedHosts:
- github.com
description: This is ${{ parameters.name }}
repoUrl: ${{ parameters.repoUrl }}
- id: register
if: ${{ parameters.dryRun !== true }}
name: Register
action: catalog:register
input:
repoContentsUrl: ${{ steps['publish'].output.repoContentsUrl }}
catalogInfoPath: '/catalog-info.yaml'
- name: Results
if: ${{ parameters.dryRun }}
action: debug:log
input:
listWorkspace: true
output:
links:
- title: Repository
url: ${{ steps['publish'].output.remoteUrl }}
- title: Open in catalog
icon: catalog
entityRef: ${{ steps['register'].output.entityRef }}
```
@@ -0,0 +1,21 @@
## API Report File for "@backstage/plugin-scaffolder-backend-module-sentry"
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { Config } from '@backstage/config';
import { TemplateAction } from '@backstage/plugin-scaffolder-backend';
// @public
export function createSentryCreateProjectAction(options: {
config: Config;
}): TemplateAction<{
organizationSlug: string;
teamSlug: string;
name: string;
slug?: string | undefined;
authToken?: string | undefined;
}>;
// (No @packageDocumentation comment for this package)
```
@@ -0,0 +1,48 @@
{
"name": "@backstage/plugin-scaffolder-backend-module-sentry",
"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": "frontend-plugin"
},
"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-backend": "workspace:^"
},
"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"
},
"files": [
"dist"
]
}
@@ -0,0 +1,122 @@
/*
* 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-backend';
import { InputError } from '@backstage/errors';
import { Config } from '@backstage/config';
/**
* Creates the `sentry:craete-project` Scaffolder action.
*
* @remarks
*
* See {@link https://backstage.io/docs/features/software-templates/writing-custom-actions}.
*
* @param options - Configuration of the Sentry API.
* @public
*/
export function createSentryCreateProjectAction(options: { config: Config }) {
const { config } = options;
return createTemplateAction<{
organizationSlug: string;
teamSlug: string;
name: string;
slug?: string;
authToken?: string;
}>({
id: 'sentry:project:create',
schema: {
input: {
required: ['organizationSlug', 'teamSlug', 'name'],
type: 'object',
properties: {
organizationSlug: {
title: 'The slug of the organization the team belongs to',
type: 'string',
},
teamSlug: {
title: 'The slug of the team to create a new project for',
type: 'string',
},
name: {
title: 'The name for the new project',
type: 'string',
},
slug: {
title:
'Optional slug for the new project. If not provided a slug is generated from the name',
type: 'string',
},
authToken: {
title:
'authenticate via bearer auth token. Requires scope: project:write',
type: 'string',
},
},
},
},
async handler(ctx) {
const { organizationSlug, teamSlug, name, slug, authToken } = ctx.input;
const body: any = {
name: name,
};
if (slug) {
body.slug = slug;
}
const token = authToken
? authToken
: config.getOptionalString('scaffolder.sentry.token');
if (!token) {
throw new InputError(`No valid sentry token given`);
}
const response = await fetch(
`https://sentry.io/api/0/teams/${organizationSlug}/${teamSlug}/projects/`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
},
);
const contentType = response.headers.get('content-type');
if (contentType !== 'application/json') {
throw new InputError(
`Unexpected Sentry Response Type: ${await response.text()}`,
);
}
const code = response.status;
const result = await response.json();
if (code !== 201) {
throw new InputError(`Sentry Response was: ${await result.detail}`);
}
ctx.output('id', result.id);
ctx.output('result', result);
},
});
}
@@ -0,0 +1,17 @@
/*
* 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.
*/
export { createSentryCreateProjectAction } from './actions/createProject';
+23
View File
@@ -7330,6 +7330,29 @@ __metadata:
languageName: unknown
linkType: soft
"@backstage/plugin-scaffolder-backend-module-sentry@workspace:plugins/scaffolder-backend-module-sentry":
version: 0.0.0-use.local
resolution: "@backstage/plugin-scaffolder-backend-module-sentry@workspace:plugins/scaffolder-backend-module-sentry"
dependencies:
"@backstage/cli": "workspace:^"
"@backstage/config": "workspace:^"
"@backstage/core-app-api": "workspace:^"
"@backstage/dev-utils": "workspace:^"
"@backstage/errors": "workspace:^"
"@backstage/integration": "workspace:^"
"@backstage/plugin-scaffolder-backend": "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
peerDependencies:
react: ^16.13.1 || ^17.0.0
languageName: unknown
linkType: soft
"@backstage/plugin-scaffolder-backend-module-yeoman@workspace:plugins/scaffolder-backend-module-yeoman":
version: 0.0.0-use.local
resolution: "@backstage/plugin-scaffolder-backend-module-yeoman@workspace:plugins/scaffolder-backend-module-yeoman"