@backstage/plugin-scaffolder-backend-module-sentry 0.0.0-nightly-20230112022659

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # @backstage/plugin-scaffolder-backend-module-sentry
2
+
3
+ ## 0.0.0-nightly-20230112022659
4
+
5
+ ### Minor Changes
6
+
7
+ - 66ff367af6: Add Sentry "Create Project" Scaffolder as new package
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies
12
+ - @backstage/plugin-scaffolder-backend@0.0.0-nightly-20230112022659
13
+ - @backstage/config@0.0.0-nightly-20230112022659
14
+ - @backstage/errors@1.1.4
15
+ - @backstage/integration@0.0.0-nightly-20230112022659
package/README.md ADDED
@@ -0,0 +1,160 @@
1
+ # scaffolder-backend-module-sentry
2
+
3
+ Welcome to the Sentry Module for Scaffolder.
4
+
5
+ Here you can find all Sentry related features to improve your scaffolder:
6
+
7
+ ## Getting started
8
+
9
+ You need to configure the action in your backend:
10
+
11
+ ## From your Backstage root directory
12
+
13
+ ```bash
14
+ # From your Backstage root directory
15
+ yarn add --cwd packages/backend @backstage/plugin-scaffolder-backend-module-sentry
16
+ ```
17
+
18
+ Configure the action (you can check
19
+ the [docs](https://backstage.io/docs/features/software-templates/writing-custom-actions#registering-custom-actions) to
20
+ see all options):
21
+
22
+ ```typescript
23
+ const actions = [
24
+ createSentryCreateProjectAction({
25
+ integrations,
26
+ reader: env.reader,
27
+ containerRunner,
28
+ }),
29
+ ];
30
+
31
+ return await createRouter({
32
+ containerRunner,
33
+ catalogClient,
34
+ actions,
35
+ logger: env.logger,
36
+ config: env.config,
37
+ database: env.database,
38
+ reader: env.reader,
39
+ });
40
+ ```
41
+
42
+ You need to define your Sentry API Token in your `app-config.yaml`:
43
+
44
+ ```yaml
45
+ scaffolder:
46
+ sentry:
47
+ token: ${SENTRY_TOKEN}
48
+ ```
49
+
50
+ After that you can use the action in your template:
51
+
52
+ ```yaml
53
+ apiVersion: scaffolder.backstage.io/v1beta3
54
+ kind: Template
55
+ metadata:
56
+ name: sentry-demo
57
+ title: Sentry template
58
+ description: scaffolder sentry app
59
+ spec:
60
+ owner: backstage/techdocs-core
61
+ type: service
62
+
63
+ parameters:
64
+ - title: Fill in some steps
65
+ required:
66
+ - name
67
+ - owner
68
+ properties:
69
+ name:
70
+ title: Name
71
+ type: string
72
+ description: Unique name of the component
73
+ ui:autofocus: true
74
+ ui:options:
75
+ rows: 5
76
+ owner:
77
+ title: Owner
78
+ type: string
79
+ description: Owner of the component
80
+ ui:field: OwnerPicker
81
+ ui:options:
82
+ catalogFilter:
83
+ kind: Group
84
+ system:
85
+ title: System
86
+ type: string
87
+ description: System of the component
88
+ ui:field: EntityPicker
89
+ ui:options:
90
+ catalogFilter:
91
+ kind: System
92
+ defaultKind: System
93
+
94
+ - title: Choose a location
95
+ required:
96
+ - repoUrl
97
+ - dryRun
98
+ properties:
99
+ repoUrl:
100
+ title: Repository Location
101
+ type: string
102
+ ui:field: RepoUrlPicker
103
+ ui:options:
104
+ allowedHosts:
105
+ - github.com
106
+ dryRun:
107
+ title: Only perform a dry run, don't publish anything
108
+ type: boolean
109
+ default: false
110
+
111
+ steps:
112
+ - id: fetch
113
+ name: Fetch
114
+ action: fetch:template
115
+ input:
116
+ url: https://github.com/TEMPLATE
117
+ values:
118
+ name: ${{ parameters.name }}
119
+
120
+ - id: create-sentry-project
121
+ if: ${{ parameters.dryRun !== true }}
122
+ name: Create Sentry Project
123
+ action: sentry:create-project
124
+ input:
125
+ organizationSlug: ORG-SLUG
126
+ teamSlug: TEAM-SLUG
127
+ name: ${{ parameters.name }}
128
+
129
+ - id: publish
130
+ if: ${{ parameters.dryRun !== true }}
131
+ name: Publish
132
+ action: publish:github
133
+ input:
134
+ allowedHosts:
135
+ - github.com
136
+ description: This is ${{ parameters.name }}
137
+ repoUrl: ${{ parameters.repoUrl }}
138
+
139
+ - id: register
140
+ if: ${{ parameters.dryRun !== true }}
141
+ name: Register
142
+ action: catalog:register
143
+ input:
144
+ repoContentsUrl: ${{ steps['publish'].output.repoContentsUrl }}
145
+ catalogInfoPath: '/catalog-info.yaml'
146
+
147
+ - name: Results
148
+ if: ${{ parameters.dryRun }}
149
+ action: debug:log
150
+ input:
151
+ listWorkspace: true
152
+
153
+ output:
154
+ links:
155
+ - title: Repository
156
+ url: ${{ steps['publish'].output.remoteUrl }}
157
+ - title: Open in catalog
158
+ icon: catalog
159
+ entityRef: ${{ steps['register'].output.entityRef }}
160
+ ```
@@ -0,0 +1,24 @@
1
+ import * as _backstage_plugin_scaffolder_backend from '@backstage/plugin-scaffolder-backend';
2
+ import { Config } from '@backstage/config';
3
+
4
+ /**
5
+ * Creates the `sentry:craete-project` Scaffolder action.
6
+ *
7
+ * @remarks
8
+ *
9
+ * See {@link https://backstage.io/docs/features/software-templates/writing-custom-actions}.
10
+ *
11
+ * @param options - Configuration of the Sentry API.
12
+ * @public
13
+ */
14
+ declare function createSentryCreateProjectAction(options: {
15
+ config: Config;
16
+ }): _backstage_plugin_scaffolder_backend.TemplateAction<{
17
+ organizationSlug: string;
18
+ teamSlug: string;
19
+ name: string;
20
+ slug?: string | undefined;
21
+ authToken?: string | undefined;
22
+ }>;
23
+
24
+ export { createSentryCreateProjectAction };
@@ -0,0 +1,77 @@
1
+ import { createTemplateAction } from '@backstage/plugin-scaffolder-backend';
2
+ import { InputError } from '@backstage/errors';
3
+
4
+ function createSentryCreateProjectAction(options) {
5
+ const { config } = options;
6
+ return createTemplateAction({
7
+ id: "sentry:project:create",
8
+ schema: {
9
+ input: {
10
+ required: ["organizationSlug", "teamSlug", "name"],
11
+ type: "object",
12
+ properties: {
13
+ organizationSlug: {
14
+ title: "The slug of the organization the team belongs to",
15
+ type: "string"
16
+ },
17
+ teamSlug: {
18
+ title: "The slug of the team to create a new project for",
19
+ type: "string"
20
+ },
21
+ name: {
22
+ title: "The name for the new project",
23
+ type: "string"
24
+ },
25
+ slug: {
26
+ title: "Optional slug for the new project. If not provided a slug is generated from the name",
27
+ type: "string"
28
+ },
29
+ authToken: {
30
+ title: "authenticate via bearer auth token. Requires scope: project:write",
31
+ type: "string"
32
+ }
33
+ }
34
+ }
35
+ },
36
+ async handler(ctx) {
37
+ const { organizationSlug, teamSlug, name, slug, authToken } = ctx.input;
38
+ const body = {
39
+ name
40
+ };
41
+ if (slug) {
42
+ body.slug = slug;
43
+ }
44
+ const token = authToken ? authToken : config.getOptionalString("scaffolder.sentry.token");
45
+ if (!token) {
46
+ throw new InputError(`No valid sentry token given`);
47
+ }
48
+ const response = await fetch(
49
+ `https://sentry.io/api/0/teams/${organizationSlug}/${teamSlug}/projects/`,
50
+ {
51
+ method: "POST",
52
+ headers: {
53
+ Authorization: `Bearer ${token}`,
54
+ "Content-Type": "application/json"
55
+ },
56
+ body: JSON.stringify(body)
57
+ }
58
+ );
59
+ const contentType = response.headers.get("content-type");
60
+ if (contentType !== "application/json") {
61
+ throw new InputError(
62
+ `Unexpected Sentry Response Type: ${await response.text()}`
63
+ );
64
+ }
65
+ const code = response.status;
66
+ const result = await response.json();
67
+ if (code !== 201) {
68
+ throw new InputError(`Sentry Response was: ${await result.detail}`);
69
+ }
70
+ ctx.output("id", result.id);
71
+ ctx.output("result", result);
72
+ }
73
+ });
74
+ }
75
+
76
+ export { createSentryCreateProjectAction };
77
+ //# sourceMappingURL=index.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.esm.js","sources":["../src/actions/createProject.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createTemplateAction } from '@backstage/plugin-scaffolder-backend';\nimport { InputError } from '@backstage/errors';\nimport { Config } from '@backstage/config';\n\n/**\n * Creates the `sentry:craete-project` Scaffolder action.\n *\n * @remarks\n *\n * See {@link https://backstage.io/docs/features/software-templates/writing-custom-actions}.\n *\n * @param options - Configuration of the Sentry API.\n * @public\n */\nexport function createSentryCreateProjectAction(options: { config: Config }) {\n const { config } = options;\n\n return createTemplateAction<{\n organizationSlug: string;\n teamSlug: string;\n name: string;\n slug?: string;\n authToken?: string;\n }>({\n id: 'sentry:project:create',\n schema: {\n input: {\n required: ['organizationSlug', 'teamSlug', 'name'],\n type: 'object',\n properties: {\n organizationSlug: {\n title: 'The slug of the organization the team belongs to',\n type: 'string',\n },\n teamSlug: {\n title: 'The slug of the team to create a new project for',\n type: 'string',\n },\n name: {\n title: 'The name for the new project',\n type: 'string',\n },\n slug: {\n title:\n 'Optional slug for the new project. If not provided a slug is generated from the name',\n type: 'string',\n },\n authToken: {\n title:\n 'authenticate via bearer auth token. Requires scope: project:write',\n type: 'string',\n },\n },\n },\n },\n async handler(ctx) {\n const { organizationSlug, teamSlug, name, slug, authToken } = ctx.input;\n\n const body: any = {\n name: name,\n };\n\n if (slug) {\n body.slug = slug;\n }\n\n const token = authToken\n ? authToken\n : config.getOptionalString('scaffolder.sentry.token');\n\n if (!token) {\n throw new InputError(`No valid sentry token given`);\n }\n\n const response = await fetch(\n `https://sentry.io/api/0/teams/${organizationSlug}/${teamSlug}/projects/`,\n {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(body),\n },\n );\n\n const contentType = response.headers.get('content-type');\n\n if (contentType !== 'application/json') {\n throw new InputError(\n `Unexpected Sentry Response Type: ${await response.text()}`,\n );\n }\n\n const code = response.status;\n const result = await response.json();\n\n if (code !== 201) {\n throw new InputError(`Sentry Response was: ${await result.detail}`);\n }\n\n ctx.output('id', result.id);\n ctx.output('result', result);\n },\n });\n}\n"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@backstage/plugin-scaffolder-backend-module-sentry",
3
+ "version": "0.0.0-nightly-20230112022659",
4
+ "main": "dist/index.esm.js",
5
+ "types": "dist/index.d.ts",
6
+ "license": "Apache-2.0",
7
+ "publishConfig": {
8
+ "access": "public",
9
+ "main": "dist/index.esm.js",
10
+ "types": "dist/index.d.ts"
11
+ },
12
+ "backstage": {
13
+ "role": "frontend-plugin"
14
+ },
15
+ "scripts": {
16
+ "start": "backstage-cli package start",
17
+ "build": "backstage-cli package build",
18
+ "lint": "backstage-cli package lint",
19
+ "test": "backstage-cli package test",
20
+ "clean": "backstage-cli package clean",
21
+ "prepack": "backstage-cli package prepack",
22
+ "postpack": "backstage-cli package postpack"
23
+ },
24
+ "dependencies": {
25
+ "@backstage/config": "^0.0.0-nightly-20230112022659",
26
+ "@backstage/errors": "^1.1.4",
27
+ "@backstage/integration": "^0.0.0-nightly-20230112022659",
28
+ "@backstage/plugin-scaffolder-backend": "^0.0.0-nightly-20230112022659"
29
+ },
30
+ "peerDependencies": {
31
+ "react": "^16.13.1 || ^17.0.0"
32
+ },
33
+ "devDependencies": {
34
+ "@backstage/cli": "^0.0.0-nightly-20230112022659",
35
+ "@backstage/core-app-api": "^0.0.0-nightly-20230112022659",
36
+ "@backstage/dev-utils": "^0.0.0-nightly-20230112022659",
37
+ "@backstage/test-utils": "^0.0.0-nightly-20230112022659",
38
+ "@testing-library/jest-dom": "^5.10.1",
39
+ "@testing-library/react": "^12.1.3",
40
+ "@testing-library/user-event": "^14.0.0",
41
+ "@types/node": "*",
42
+ "cross-fetch": "^3.1.5",
43
+ "msw": "^0.49.0"
44
+ },
45
+ "files": [
46
+ "dist"
47
+ ]
48
+ }