@backstage/plugin-scaffolder-backend-module-github 0.5.6-next.1 → 0.6.0
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 +67 -0
- package/dist/actions/githubActionsDispatch.cjs.js +2 -2
- package/dist/actions/githubActionsDispatch.cjs.js.map +1 -1
- package/dist/actions/githubAutolinks.cjs.js +5 -4
- package/dist/actions/githubAutolinks.cjs.js.map +1 -1
- package/dist/actions/githubDeployKey.cjs.js +4 -4
- package/dist/actions/githubDeployKey.cjs.js.map +1 -1
- package/dist/actions/githubEnvironment.cjs.js +6 -6
- package/dist/actions/githubEnvironment.cjs.js.map +1 -1
- package/dist/actions/githubIssuesLabel.cjs.js +2 -2
- package/dist/actions/githubIssuesLabel.cjs.js.map +1 -1
- package/dist/actions/githubPagesEnable.cjs.js +8 -3
- package/dist/actions/githubPagesEnable.cjs.js.map +1 -1
- package/dist/actions/githubPullRequest.cjs.js +18 -7
- package/dist/actions/githubPullRequest.cjs.js.map +1 -1
- package/dist/actions/githubPullRequest.examples.cjs.js +33 -14
- package/dist/actions/githubPullRequest.examples.cjs.js.map +1 -1
- package/dist/actions/githubWebhook.cjs.js +10 -6
- package/dist/actions/githubWebhook.cjs.js.map +1 -1
- package/dist/actions/inputProperties.cjs.js +39 -21
- package/dist/actions/inputProperties.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/package.json +11 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,72 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder-backend-module-github
|
|
2
2
|
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- bb8302b: **BREAKING**: The `remoteUrl` output is no longer required, it can be empty only when using the new `createWhenEmpty` boolean flag.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 5c187f9: **DEPRECATION**: The `getOctokitOptions` function signature with `repoUrl` option has been deprecated in favour of a function signature with individual `host`, `owner`, and `repo` parameters:
|
|
12
|
+
|
|
13
|
+
```diff
|
|
14
|
+
const octokitOptions = await getOctokitOptions({
|
|
15
|
+
integrations,
|
|
16
|
+
credentialsProvider,
|
|
17
|
+
token,
|
|
18
|
+
- repoUrl,
|
|
19
|
+
+ host,
|
|
20
|
+
+ owner,
|
|
21
|
+
+ repo,
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- b98d511: clean up github action schemas
|
|
26
|
+
- 5d469c9: Added support for autocompletion of GitHub branches in scaffolder
|
|
27
|
+
- 8e67e4a: Added support for autocompletion to GithubRepoPicker component
|
|
28
|
+
- Updated dependencies
|
|
29
|
+
- @backstage/backend-plugin-api@1.2.0
|
|
30
|
+
- @backstage/plugin-scaffolder-node@0.7.0
|
|
31
|
+
- @backstage/catalog-client@1.9.1
|
|
32
|
+
- @backstage/catalog-model@1.7.3
|
|
33
|
+
- @backstage/config@1.3.2
|
|
34
|
+
- @backstage/errors@1.2.7
|
|
35
|
+
- @backstage/integration@1.16.1
|
|
36
|
+
|
|
37
|
+
## 0.6.0-next.2
|
|
38
|
+
|
|
39
|
+
### Minor Changes
|
|
40
|
+
|
|
41
|
+
- bb8302b: **BREAKING**: The `remoteUrl` output is no longer required, it can be empty only when using the new `createWhenEmpty` boolean flag.
|
|
42
|
+
|
|
43
|
+
### Patch Changes
|
|
44
|
+
|
|
45
|
+
- 5c187f9: **DEPRECATION**: The `getOctokitOptions` function signature with `repoUrl` option has been deprecated in favour of a function signature with individual `host`, `owner`, and `repo` parameters:
|
|
46
|
+
|
|
47
|
+
```diff
|
|
48
|
+
const octokitOptions = await getOctokitOptions({
|
|
49
|
+
integrations,
|
|
50
|
+
credentialsProvider,
|
|
51
|
+
token,
|
|
52
|
+
- repoUrl,
|
|
53
|
+
+ host,
|
|
54
|
+
+ owner,
|
|
55
|
+
+ repo,
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
- 5d469c9: Added support for autocompletion of GitHub branches in scaffolder
|
|
60
|
+
- 8e67e4a: Added support for autocompletion to GithubRepoPicker component
|
|
61
|
+
- Updated dependencies
|
|
62
|
+
- @backstage/plugin-scaffolder-node@0.7.0-next.2
|
|
63
|
+
- @backstage/backend-plugin-api@1.2.0-next.2
|
|
64
|
+
- @backstage/catalog-client@1.9.1
|
|
65
|
+
- @backstage/catalog-model@1.7.3
|
|
66
|
+
- @backstage/config@1.3.2
|
|
67
|
+
- @backstage/errors@1.2.7
|
|
68
|
+
- @backstage/integration@1.16.1
|
|
69
|
+
|
|
3
70
|
## 0.5.6-next.1
|
|
4
71
|
|
|
5
72
|
### Patch Changes
|
|
@@ -19,7 +19,7 @@ function createGithubActionsDispatchAction(options) {
|
|
|
19
19
|
properties: {
|
|
20
20
|
repoUrl: {
|
|
21
21
|
title: "Repository Location",
|
|
22
|
-
description:
|
|
22
|
+
description: "Accepts the format `github.com?repo=reponame&owner=owner` where `reponame` is the new repository name and `owner` is an organization or username",
|
|
23
23
|
type: "string"
|
|
24
24
|
},
|
|
25
25
|
workflowId: {
|
|
@@ -40,7 +40,7 @@ function createGithubActionsDispatchAction(options) {
|
|
|
40
40
|
token: {
|
|
41
41
|
title: "Authentication Token",
|
|
42
42
|
type: "string",
|
|
43
|
-
description: "The GITHUB_TOKEN to use for authorization to GitHub"
|
|
43
|
+
description: "The `GITHUB_TOKEN` to use for authorization to GitHub"
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"githubActionsDispatch.cjs.js","sources":["../../src/actions/githubActionsDispatch.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 { InputError } from '@backstage/errors';\nimport {\n GithubCredentialsProvider,\n ScmIntegrations,\n} from '@backstage/integration';\nimport {\n createTemplateAction,\n parseRepoUrl,\n} from '@backstage/plugin-scaffolder-node';\nimport { Octokit } from 'octokit';\nimport { getOctokitOptions } from '../util';\nimport { examples } from './githubActionsDispatch.examples';\n\n/**\n * Creates a new action that dispatches a GitHub Action workflow for a given branch or tag.\n * @public\n */\nexport function createGithubActionsDispatchAction(options: {\n integrations: ScmIntegrations;\n githubCredentialsProvider?: GithubCredentialsProvider;\n}) {\n const { integrations, githubCredentialsProvider } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n workflowId: string;\n branchOrTagName: string;\n workflowInputs?: { [key: string]: string };\n token?: string;\n }>({\n id: 'github:actions:dispatch',\n description:\n 'Dispatches a GitHub Action workflow for a given branch or tag',\n examples,\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl', 'workflowId', 'branchOrTagName'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description
|
|
1
|
+
{"version":3,"file":"githubActionsDispatch.cjs.js","sources":["../../src/actions/githubActionsDispatch.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 { InputError } from '@backstage/errors';\nimport {\n GithubCredentialsProvider,\n ScmIntegrations,\n} from '@backstage/integration';\nimport {\n createTemplateAction,\n parseRepoUrl,\n} from '@backstage/plugin-scaffolder-node';\nimport { Octokit } from 'octokit';\nimport { getOctokitOptions } from '../util';\nimport { examples } from './githubActionsDispatch.examples';\n\n/**\n * Creates a new action that dispatches a GitHub Action workflow for a given branch or tag.\n * @public\n */\nexport function createGithubActionsDispatchAction(options: {\n integrations: ScmIntegrations;\n githubCredentialsProvider?: GithubCredentialsProvider;\n}) {\n const { integrations, githubCredentialsProvider } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n workflowId: string;\n branchOrTagName: string;\n workflowInputs?: { [key: string]: string };\n token?: string;\n }>({\n id: 'github:actions:dispatch',\n description:\n 'Dispatches a GitHub Action workflow for a given branch or tag',\n examples,\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl', 'workflowId', 'branchOrTagName'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description:\n 'Accepts the format `github.com?repo=reponame&owner=owner` where `reponame` is the new repository name and `owner` is an organization or username',\n type: 'string',\n },\n workflowId: {\n title: 'Workflow ID',\n description: 'The GitHub Action Workflow filename',\n type: 'string',\n },\n branchOrTagName: {\n title: 'Branch or Tag name',\n description:\n 'The git branch or tag name used to dispatch the workflow',\n type: 'string',\n },\n workflowInputs: {\n title: 'Workflow Inputs',\n description:\n 'Inputs keys and values to send to GitHub Action configured on the workflow file. The maximum number of properties is 10. ',\n type: 'object',\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description:\n 'The `GITHUB_TOKEN` to use for authorization to GitHub',\n },\n },\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n workflowId,\n branchOrTagName,\n workflowInputs,\n token: providedToken,\n } = ctx.input;\n\n ctx.logger.info(\n `Dispatching workflow ${workflowId} for repo ${repoUrl} on ${branchOrTagName}`,\n );\n\n const { host, owner, repo } = parseRepoUrl(repoUrl, integrations);\n\n if (!owner) {\n throw new InputError('Invalid repository owner provided in repoUrl');\n }\n\n const client = new Octokit(\n await getOctokitOptions({\n integrations,\n host,\n owner,\n repo,\n credentialsProvider: githubCredentialsProvider,\n token: providedToken,\n }),\n );\n\n await client.rest.actions.createWorkflowDispatch({\n owner,\n repo,\n workflow_id: workflowId,\n ref: branchOrTagName,\n inputs: workflowInputs,\n });\n\n ctx.logger.info(`Workflow ${workflowId} dispatched successfully`);\n },\n });\n}\n"],"names":["createTemplateAction","examples","parseRepoUrl","InputError","Octokit","getOctokitOptions"],"mappings":";;;;;;;;AAiCO,SAAS,kCAAkC,OAG/C,EAAA;AACD,EAAM,MAAA,EAAE,YAAc,EAAA,yBAAA,EAA8B,GAAA,OAAA;AAEpD,EAAA,OAAOA,yCAMJ,CAAA;AAAA,IACD,EAAI,EAAA,yBAAA;AAAA,IACJ,WACE,EAAA,+DAAA;AAAA,cACFC,uCAAA;AAAA,IACA,MAAQ,EAAA;AAAA,MACN,KAAO,EAAA;AAAA,QACL,IAAM,EAAA,QAAA;AAAA,QACN,QAAU,EAAA,CAAC,SAAW,EAAA,YAAA,EAAc,iBAAiB,CAAA;AAAA,QACrD,UAAY,EAAA;AAAA,UACV,OAAS,EAAA;AAAA,YACP,KAAO,EAAA,qBAAA;AAAA,YACP,WACE,EAAA,kJAAA;AAAA,YACF,IAAM,EAAA;AAAA,WACR;AAAA,UACA,UAAY,EAAA;AAAA,YACV,KAAO,EAAA,aAAA;AAAA,YACP,WAAa,EAAA,qCAAA;AAAA,YACb,IAAM,EAAA;AAAA,WACR;AAAA,UACA,eAAiB,EAAA;AAAA,YACf,KAAO,EAAA,oBAAA;AAAA,YACP,WACE,EAAA,0DAAA;AAAA,YACF,IAAM,EAAA;AAAA,WACR;AAAA,UACA,cAAgB,EAAA;AAAA,YACd,KAAO,EAAA,iBAAA;AAAA,YACP,WACE,EAAA,2HAAA;AAAA,YACF,IAAM,EAAA;AAAA,WACR;AAAA,UACA,KAAO,EAAA;AAAA,YACL,KAAO,EAAA,sBAAA;AAAA,YACP,IAAM,EAAA,QAAA;AAAA,YACN,WACE,EAAA;AAAA;AACJ;AACF;AACF,KACF;AAAA,IACA,MAAM,QAAQ,GAAK,EAAA;AACjB,MAAM,MAAA;AAAA,QACJ,OAAA;AAAA,QACA,UAAA;AAAA,QACA,eAAA;AAAA,QACA,cAAA;AAAA,QACA,KAAO,EAAA;AAAA,UACL,GAAI,CAAA,KAAA;AAER,MAAA,GAAA,CAAI,MAAO,CAAA,IAAA;AAAA,QACT,CAAwB,qBAAA,EAAA,UAAU,CAAa,UAAA,EAAA,OAAO,OAAO,eAAe,CAAA;AAAA,OAC9E;AAEA,MAAA,MAAM,EAAE,IAAM,EAAA,KAAA,EAAO,MAAS,GAAAC,iCAAA,CAAa,SAAS,YAAY,CAAA;AAEhE,MAAA,IAAI,CAAC,KAAO,EAAA;AACV,QAAM,MAAA,IAAIC,kBAAW,8CAA8C,CAAA;AAAA;AAGrE,MAAA,MAAM,SAAS,IAAIC,eAAA;AAAA,QACjB,MAAMC,sBAAkB,CAAA;AAAA,UACtB,YAAA;AAAA,UACA,IAAA;AAAA,UACA,KAAA;AAAA,UACA,IAAA;AAAA,UACA,mBAAqB,EAAA,yBAAA;AAAA,UACrB,KAAO,EAAA;AAAA,SACR;AAAA,OACH;AAEA,MAAM,MAAA,MAAA,CAAO,IAAK,CAAA,OAAA,CAAQ,sBAAuB,CAAA;AAAA,QAC/C,KAAA;AAAA,QACA,IAAA;AAAA,QACA,WAAa,EAAA,UAAA;AAAA,QACb,GAAK,EAAA,eAAA;AAAA,QACL,MAAQ,EAAA;AAAA,OACT,CAAA;AAED,MAAA,GAAA,CAAI,MAAO,CAAA,IAAA,CAAK,CAAY,SAAA,EAAA,UAAU,CAA0B,wBAAA,CAAA,CAAA;AAAA;AAClE,GACD,CAAA;AACH;;;;"}
|
|
@@ -19,7 +19,7 @@ function createGithubAutolinksAction(options) {
|
|
|
19
19
|
properties: {
|
|
20
20
|
repoUrl: {
|
|
21
21
|
title: "Repository Location",
|
|
22
|
-
description:
|
|
22
|
+
description: "Accepts the format `github.com?repo=reponame&owner=owner` where `reponame` is the new repository name and `owner` is an organization or username",
|
|
23
23
|
type: "string"
|
|
24
24
|
},
|
|
25
25
|
keyPrefix: {
|
|
@@ -29,13 +29,14 @@ function createGithubAutolinksAction(options) {
|
|
|
29
29
|
},
|
|
30
30
|
urlTemplate: {
|
|
31
31
|
title: "URL Template",
|
|
32
|
-
description: "The URL must contain
|
|
32
|
+
description: "The URL must contain `<num>` for the reference number. `<num>` matches different characters depending on the value of isAlphanumeric.",
|
|
33
33
|
type: "string"
|
|
34
34
|
},
|
|
35
35
|
isAlphanumeric: {
|
|
36
36
|
title: "Alphanumeric",
|
|
37
|
-
description: "Whether this autolink reference matches alphanumeric characters. If true
|
|
38
|
-
type: "boolean"
|
|
37
|
+
description: "Whether this autolink reference matches alphanumeric characters. If `true`, the `<num>` parameter of the `url_template` matches alphanumeric characters `A-Z` (case insensitive), `0-9`, and `-`. If `false`, this autolink reference only matches numeric characters. Default: `true`",
|
|
38
|
+
type: "boolean",
|
|
39
|
+
default: true
|
|
39
40
|
},
|
|
40
41
|
token: {
|
|
41
42
|
title: "Authentication Token",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"githubAutolinks.cjs.js","sources":["../../src/actions/githubAutolinks.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 { InputError } from '@backstage/errors';\nimport {\n GithubCredentialsProvider,\n ScmIntegrations,\n} from '@backstage/integration';\nimport {\n createTemplateAction,\n parseRepoUrl,\n} from '@backstage/plugin-scaffolder-node';\nimport { Octokit } from 'octokit';\nimport { examples } from './githubAutolinks.examples';\nimport { getOctokitOptions } from '../util';\n\n/**\n * Create an autolink reference for a repository\n * @public\n */\nexport function createGithubAutolinksAction(options: {\n integrations: ScmIntegrations;\n githubCredentialsProvider?: GithubCredentialsProvider;\n}) {\n const { integrations, githubCredentialsProvider } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n keyPrefix: string;\n urlTemplate: string;\n isAlphanumeric?: boolean;\n token?: string;\n }>({\n id: 'github:autolinks:create',\n description: 'Create an autolink reference for a repository',\n examples,\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl', 'keyPrefix', 'urlTemplate'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description
|
|
1
|
+
{"version":3,"file":"githubAutolinks.cjs.js","sources":["../../src/actions/githubAutolinks.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 { InputError } from '@backstage/errors';\nimport {\n GithubCredentialsProvider,\n ScmIntegrations,\n} from '@backstage/integration';\nimport {\n createTemplateAction,\n parseRepoUrl,\n} from '@backstage/plugin-scaffolder-node';\nimport { Octokit } from 'octokit';\nimport { examples } from './githubAutolinks.examples';\nimport { getOctokitOptions } from '../util';\n\n/**\n * Create an autolink reference for a repository\n * @public\n */\nexport function createGithubAutolinksAction(options: {\n integrations: ScmIntegrations;\n githubCredentialsProvider?: GithubCredentialsProvider;\n}) {\n const { integrations, githubCredentialsProvider } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n keyPrefix: string;\n urlTemplate: string;\n isAlphanumeric?: boolean;\n token?: string;\n }>({\n id: 'github:autolinks:create',\n description: 'Create an autolink reference for a repository',\n examples,\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl', 'keyPrefix', 'urlTemplate'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description:\n 'Accepts the format `github.com?repo=reponame&owner=owner` where `reponame` is the new repository name and `owner` is an organization or username',\n type: 'string',\n },\n keyPrefix: {\n title: 'Key Prefix',\n description:\n 'This prefix appended by certain characters will generate a link any time it is found in an issue, pull request, or commit.',\n type: 'string',\n },\n urlTemplate: {\n title: 'URL Template',\n description:\n 'The URL must contain `<num>` for the reference number. `<num>` matches different characters depending on the value of isAlphanumeric.',\n type: 'string',\n },\n isAlphanumeric: {\n title: 'Alphanumeric',\n description:\n 'Whether this autolink reference matches alphanumeric characters. If `true`, the `<num>` parameter of the `url_template` matches alphanumeric characters `A-Z` (case insensitive), `0-9`, and `-`. If `false`, this autolink reference only matches numeric characters. Default: `true`',\n type: 'boolean',\n default: true,\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The token to use for authorization to GitHub',\n },\n },\n },\n },\n async handler(ctx) {\n const { repoUrl, keyPrefix, urlTemplate, isAlphanumeric, token } =\n ctx.input;\n\n ctx.logger.info(`Creating autolink reference for repo ${repoUrl}`);\n\n const { host, owner, repo } = parseRepoUrl(repoUrl, integrations);\n\n if (!owner) {\n throw new InputError('Invalid repository owner provided in repoUrl');\n }\n\n const client = new Octokit(\n await getOctokitOptions({\n integrations,\n host,\n owner,\n repo,\n credentialsProvider: githubCredentialsProvider,\n token,\n }),\n );\n\n await client.rest.repos.createAutolink({\n owner,\n repo,\n key_prefix: keyPrefix,\n url_template: urlTemplate,\n is_alphanumeric: isAlphanumeric,\n });\n\n ctx.logger.info(`Autolink reference created successfully`);\n },\n });\n}\n"],"names":["createTemplateAction","examples","parseRepoUrl","InputError","Octokit","getOctokitOptions"],"mappings":";;;;;;;;AAiCO,SAAS,4BAA4B,OAGzC,EAAA;AACD,EAAM,MAAA,EAAE,YAAc,EAAA,yBAAA,EAA8B,GAAA,OAAA;AAEpD,EAAA,OAAOA,yCAMJ,CAAA;AAAA,IACD,EAAI,EAAA,yBAAA;AAAA,IACJ,WAAa,EAAA,+CAAA;AAAA,cACbC,iCAAA;AAAA,IACA,MAAQ,EAAA;AAAA,MACN,KAAO,EAAA;AAAA,QACL,IAAM,EAAA,QAAA;AAAA,QACN,QAAU,EAAA,CAAC,SAAW,EAAA,WAAA,EAAa,aAAa,CAAA;AAAA,QAChD,UAAY,EAAA;AAAA,UACV,OAAS,EAAA;AAAA,YACP,KAAO,EAAA,qBAAA;AAAA,YACP,WACE,EAAA,kJAAA;AAAA,YACF,IAAM,EAAA;AAAA,WACR;AAAA,UACA,SAAW,EAAA;AAAA,YACT,KAAO,EAAA,YAAA;AAAA,YACP,WACE,EAAA,4HAAA;AAAA,YACF,IAAM,EAAA;AAAA,WACR;AAAA,UACA,WAAa,EAAA;AAAA,YACX,KAAO,EAAA,cAAA;AAAA,YACP,WACE,EAAA,uIAAA;AAAA,YACF,IAAM,EAAA;AAAA,WACR;AAAA,UACA,cAAgB,EAAA;AAAA,YACd,KAAO,EAAA,cAAA;AAAA,YACP,WACE,EAAA,wRAAA;AAAA,YACF,IAAM,EAAA,SAAA;AAAA,YACN,OAAS,EAAA;AAAA,WACX;AAAA,UACA,KAAO,EAAA;AAAA,YACL,KAAO,EAAA,sBAAA;AAAA,YACP,IAAM,EAAA,QAAA;AAAA,YACN,WAAa,EAAA;AAAA;AACf;AACF;AACF,KACF;AAAA,IACA,MAAM,QAAQ,GAAK,EAAA;AACjB,MAAA,MAAM,EAAE,OAAS,EAAA,SAAA,EAAW,aAAa,cAAgB,EAAA,KAAA,KACvD,GAAI,CAAA,KAAA;AAEN,MAAA,GAAA,CAAI,MAAO,CAAA,IAAA,CAAK,CAAwC,qCAAA,EAAA,OAAO,CAAE,CAAA,CAAA;AAEjE,MAAA,MAAM,EAAE,IAAM,EAAA,KAAA,EAAO,MAAS,GAAAC,iCAAA,CAAa,SAAS,YAAY,CAAA;AAEhE,MAAA,IAAI,CAAC,KAAO,EAAA;AACV,QAAM,MAAA,IAAIC,kBAAW,8CAA8C,CAAA;AAAA;AAGrE,MAAA,MAAM,SAAS,IAAIC,eAAA;AAAA,QACjB,MAAMC,sBAAkB,CAAA;AAAA,UACtB,YAAA;AAAA,UACA,IAAA;AAAA,UACA,KAAA;AAAA,UACA,IAAA;AAAA,UACA,mBAAqB,EAAA,yBAAA;AAAA,UACrB;AAAA,SACD;AAAA,OACH;AAEA,MAAM,MAAA,MAAA,CAAO,IAAK,CAAA,KAAA,CAAM,cAAe,CAAA;AAAA,QACrC,KAAA;AAAA,QACA,IAAA;AAAA,QACA,UAAY,EAAA,SAAA;AAAA,QACZ,YAAc,EAAA,WAAA;AAAA,QACd,eAAiB,EAAA;AAAA,OAClB,CAAA;AAED,MAAI,GAAA,CAAA,MAAA,CAAO,KAAK,CAAyC,uCAAA,CAAA,CAAA;AAAA;AAC3D,GACD,CAAA;AACH;;;;"}
|
|
@@ -24,17 +24,17 @@ function createGithubDeployKeyAction(options) {
|
|
|
24
24
|
properties: {
|
|
25
25
|
repoUrl: {
|
|
26
26
|
title: "Repository Location",
|
|
27
|
-
description:
|
|
27
|
+
description: "Accepts the format `github.com?repo=reponame&owner=owner` where `reponame` is the new repository name and `owner` is an organization or username",
|
|
28
28
|
type: "string"
|
|
29
29
|
},
|
|
30
30
|
publicKey: {
|
|
31
31
|
title: "SSH Public Key",
|
|
32
|
-
description:
|
|
32
|
+
description: "Generated from `ssh-keygen`. Begins with `ssh-rsa`, `ecdsa-sha2-nistp256`, `ecdsa-sha2-nistp384`, `ecdsa-sha2-nistp521`, `ssh-ed25519`, `sk-ecdsa-sha2-nistp256@openssh.com`, or `sk-ssh-ed25519@openssh.com`.",
|
|
33
33
|
type: "string"
|
|
34
34
|
},
|
|
35
35
|
privateKey: {
|
|
36
36
|
title: "SSH Private Key",
|
|
37
|
-
description:
|
|
37
|
+
description: "SSH Private Key generated from `ssh-keygen`",
|
|
38
38
|
type: "string"
|
|
39
39
|
},
|
|
40
40
|
deployKeyName: {
|
|
@@ -44,7 +44,7 @@ function createGithubDeployKeyAction(options) {
|
|
|
44
44
|
},
|
|
45
45
|
privateKeySecretName: {
|
|
46
46
|
title: "Private Key GitHub Secret Name",
|
|
47
|
-
description:
|
|
47
|
+
description: "Name of the GitHub Secret to store the private key related to the Deploy Key. Defaults to: `KEY_NAME_PRIVATE_KEY` where `KEY_NAME` is the name of the Deploy Key",
|
|
48
48
|
type: "string"
|
|
49
49
|
},
|
|
50
50
|
token: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"githubDeployKey.cjs.js","sources":["../../src/actions/githubDeployKey.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 { InputError } from '@backstage/errors';\nimport {\n createTemplateAction,\n parseRepoUrl,\n} from '@backstage/plugin-scaffolder-node';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { getOctokitOptions } from '../util';\nimport { Octokit } from 'octokit';\nimport Sodium from 'libsodium-wrappers';\nimport { examples } from './githubDeployKey.examples';\n\n/**\n * Creates an `github:deployKey:create` Scaffolder action that creates a Deploy Key\n *\n * @public\n */\nexport function createGithubDeployKeyAction(options: {\n integrations: ScmIntegrationRegistry;\n}) {\n const { integrations } = options;\n // For more information on how to define custom actions, see\n // https://backstage.io/docs/features/software-templates/writing-custom-actions\n return createTemplateAction<{\n repoUrl: string;\n publicKey: string;\n privateKey: string;\n deployKeyName: string;\n privateKeySecretName?: string;\n token?: string;\n }>({\n id: 'github:deployKey:create',\n description: 'Creates and stores Deploy Keys',\n examples,\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl', 'publicKey', 'privateKey', 'deployKeyName'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description
|
|
1
|
+
{"version":3,"file":"githubDeployKey.cjs.js","sources":["../../src/actions/githubDeployKey.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 { InputError } from '@backstage/errors';\nimport {\n createTemplateAction,\n parseRepoUrl,\n} from '@backstage/plugin-scaffolder-node';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { getOctokitOptions } from '../util';\nimport { Octokit } from 'octokit';\nimport Sodium from 'libsodium-wrappers';\nimport { examples } from './githubDeployKey.examples';\n\n/**\n * Creates an `github:deployKey:create` Scaffolder action that creates a Deploy Key\n *\n * @public\n */\nexport function createGithubDeployKeyAction(options: {\n integrations: ScmIntegrationRegistry;\n}) {\n const { integrations } = options;\n // For more information on how to define custom actions, see\n // https://backstage.io/docs/features/software-templates/writing-custom-actions\n return createTemplateAction<{\n repoUrl: string;\n publicKey: string;\n privateKey: string;\n deployKeyName: string;\n privateKeySecretName?: string;\n token?: string;\n }>({\n id: 'github:deployKey:create',\n description: 'Creates and stores Deploy Keys',\n examples,\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl', 'publicKey', 'privateKey', 'deployKeyName'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description:\n 'Accepts the format `github.com?repo=reponame&owner=owner` where `reponame` is the new repository name and `owner` is an organization or username',\n type: 'string',\n },\n publicKey: {\n title: 'SSH Public Key',\n description:\n 'Generated from `ssh-keygen`. Begins with `ssh-rsa`, `ecdsa-sha2-nistp256`, `ecdsa-sha2-nistp384`, `ecdsa-sha2-nistp521`, `ssh-ed25519`, `sk-ecdsa-sha2-nistp256@openssh.com`, or `sk-ssh-ed25519@openssh.com`.',\n type: 'string',\n },\n privateKey: {\n title: 'SSH Private Key',\n description: 'SSH Private Key generated from `ssh-keygen`',\n type: 'string',\n },\n deployKeyName: {\n title: 'Deploy Key Name',\n description: `Name of the Deploy Key`,\n type: 'string',\n },\n privateKeySecretName: {\n title: 'Private Key GitHub Secret Name',\n description:\n 'Name of the GitHub Secret to store the private key related to the Deploy Key. Defaults to: `KEY_NAME_PRIVATE_KEY` where `KEY_NAME` is the name of the Deploy Key',\n type: 'string',\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The token to use for authorization to GitHub',\n },\n },\n },\n output: {\n type: 'object',\n properties: {\n privateKeySecretName: {\n title: 'The GitHub Action Repo Secret Name for the Private Key',\n type: 'string',\n },\n },\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n publicKey,\n privateKey,\n deployKeyName,\n privateKeySecretName = `${deployKeyName\n .split(' ')\n .join('_')\n .toLocaleUpperCase('en-US')}_PRIVATE_KEY`,\n token: providedToken,\n } = ctx.input;\n\n const { host, owner, repo } = parseRepoUrl(repoUrl, integrations);\n\n if (!owner) {\n throw new InputError(`No owner provided for repo ${repoUrl}`);\n }\n\n const octokitOptions = await getOctokitOptions({\n integrations,\n token: providedToken,\n host,\n owner,\n repo,\n });\n\n const client = new Octokit(octokitOptions);\n\n await client.rest.repos.createDeployKey({\n owner: owner,\n repo: repo,\n title: deployKeyName,\n key: publicKey,\n });\n const publicKeyResponse = await client.rest.actions.getRepoPublicKey({\n owner: owner,\n repo: repo,\n });\n\n await Sodium.ready;\n const binaryKey = Sodium.from_base64(\n publicKeyResponse.data.key,\n Sodium.base64_variants.ORIGINAL,\n );\n const binarySecret = Sodium.from_string(privateKey);\n const encryptedBinarySecret = Sodium.crypto_box_seal(\n binarySecret,\n binaryKey,\n );\n const encryptedBase64Secret = Sodium.to_base64(\n encryptedBinarySecret,\n Sodium.base64_variants.ORIGINAL,\n );\n\n await client.rest.actions.createOrUpdateRepoSecret({\n owner: owner,\n repo: repo,\n secret_name: privateKeySecretName,\n encrypted_value: encryptedBase64Secret,\n key_id: publicKeyResponse.data.key_id,\n });\n\n ctx.output('privateKeySecretName', privateKeySecretName);\n },\n });\n}\n"],"names":["createTemplateAction","examples","parseRepoUrl","InputError","getOctokitOptions","Octokit","Sodium"],"mappings":"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"}
|
|
@@ -24,7 +24,7 @@ function createGithubEnvironmentAction(options) {
|
|
|
24
24
|
properties: {
|
|
25
25
|
repoUrl: {
|
|
26
26
|
title: "Repository Location",
|
|
27
|
-
description:
|
|
27
|
+
description: "Accepts the format `github.com?repo=reponame&owner=owner` where `reponame` is the new repository name and `owner` is an organization or username",
|
|
28
28
|
type: "string"
|
|
29
29
|
},
|
|
30
30
|
name: {
|
|
@@ -34,18 +34,18 @@ function createGithubEnvironmentAction(options) {
|
|
|
34
34
|
},
|
|
35
35
|
deploymentBranchPolicy: {
|
|
36
36
|
title: "Deployment Branch Policy",
|
|
37
|
-
description:
|
|
37
|
+
description: "The type of deployment branch policy for this environment. To allow all branches to deploy, set to `null`.",
|
|
38
38
|
type: "object",
|
|
39
39
|
required: ["protected_branches", "custom_branch_policies"],
|
|
40
40
|
properties: {
|
|
41
41
|
protected_branches: {
|
|
42
42
|
title: "Protected Branches",
|
|
43
|
-
description:
|
|
43
|
+
description: "Whether only branches with branch protection rules can deploy to this environment. If `protected_branches` is `true`, `custom_branch_policies` must be `false`; if `protected_branches` is `false`, `custom_branch_policies` must be `true`.",
|
|
44
44
|
type: "boolean"
|
|
45
45
|
},
|
|
46
46
|
custom_branch_policies: {
|
|
47
47
|
title: "Custom Branch Policies",
|
|
48
|
-
description:
|
|
48
|
+
description: "Whether only branches that match the specified name patterns can deploy to this environment. If `custom_branch_policies` is `true`, `protected_branches` must be `false`; if `custom_branch_policies` is `false`, `protected_branches` must be `true`.",
|
|
49
49
|
type: "boolean"
|
|
50
50
|
}
|
|
51
51
|
}
|
|
@@ -54,7 +54,7 @@ function createGithubEnvironmentAction(options) {
|
|
|
54
54
|
title: "Custom Branch Policy Name",
|
|
55
55
|
description: `The name pattern that branches must match in order to deploy to the environment.
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
Wildcard characters will not match \`/\`. For example, to match branches that begin with \`release/\` and contain an additional single slash, use \`release/*/*\`. For more information about pattern matching syntax, see the Ruby File.fnmatch documentation.`,
|
|
58
58
|
type: "array",
|
|
59
59
|
items: {
|
|
60
60
|
type: "string"
|
|
@@ -64,7 +64,7 @@ function createGithubEnvironmentAction(options) {
|
|
|
64
64
|
title: "Custom Tag Policy Name",
|
|
65
65
|
description: `The name pattern that tags must match in order to deploy to the environment.
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
Wildcard characters will not match \`/\`. For example, to match tags that begin with \`release/\` and contain an additional single slash, use \`release/*/*\`. For more information about pattern matching syntax, see the Ruby File.fnmatch documentation.`,
|
|
68
68
|
type: "array",
|
|
69
69
|
items: {
|
|
70
70
|
type: "string"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"githubEnvironment.cjs.js","sources":["../../src/actions/githubEnvironment.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 { InputError } from '@backstage/errors';\nimport {\n createTemplateAction,\n parseRepoUrl,\n} from '@backstage/plugin-scaffolder-node';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { getOctokitOptions } from '../util';\nimport { Octokit } from 'octokit';\nimport Sodium from 'libsodium-wrappers';\nimport { examples } from './gitHubEnvironment.examples';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { Entity } from '@backstage/catalog-model';\nimport { AuthService } from '@backstage/backend-plugin-api';\n\n/**\n * Creates an `github:environment:create` Scaffolder action that creates a Github Environment.\n *\n * @public\n */\nexport function createGithubEnvironmentAction(options: {\n integrations: ScmIntegrationRegistry;\n catalogClient?: CatalogApi;\n auth?: AuthService;\n}) {\n const { integrations, catalogClient, auth } = options;\n // For more information on how to define custom actions, see\n // https://backstage.io/docs/features/software-templates/writing-custom-actions\n return createTemplateAction<{\n repoUrl: string;\n name: string;\n deploymentBranchPolicy?: {\n protected_branches: boolean;\n custom_branch_policies: boolean;\n };\n customBranchPolicyNames?: string[];\n customTagPolicyNames?: string[];\n environmentVariables?: { [key: string]: string };\n secrets?: { [key: string]: string };\n token?: string;\n waitTimer?: number;\n preventSelfReview?: boolean;\n reviewers?: string[];\n }>({\n id: 'github:environment:create',\n description: 'Creates Deployment Environments',\n examples,\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl', 'name'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description: `Accepts the format 'github.com?repo=reponame&owner=owner' where 'reponame' is the new repository name and 'owner' is an organization or username`,\n type: 'string',\n },\n name: {\n title: 'Environment Name',\n description: `Name of the deployment environment to create`,\n type: 'string',\n },\n deploymentBranchPolicy: {\n title: 'Deployment Branch Policy',\n description: `The type of deployment branch policy for this environment. To allow all branches to deploy, set to null.`,\n type: 'object',\n required: ['protected_branches', 'custom_branch_policies'],\n properties: {\n protected_branches: {\n title: 'Protected Branches',\n description: `Whether only branches with branch protection rules can deploy to this environment. If protected_branches is true, custom_branch_policies must be false; if protected_branches is false, custom_branch_policies must be true.`,\n type: 'boolean',\n },\n custom_branch_policies: {\n title: 'Custom Branch Policies',\n description: `Whether only branches that match the specified name patterns can deploy to this environment. If custom_branch_policies is true, protected_branches must be false; if custom_branch_policies is false, protected_branches must be true.`,\n type: 'boolean',\n },\n },\n },\n customBranchPolicyNames: {\n title: 'Custom Branch Policy Name',\n description: `The name pattern that branches must match in order to deploy to the environment.\n\n Wildcard characters will not match /. For example, to match branches that begin with release/ and contain an additional single slash, use release/*/*. For more information about pattern matching syntax, see the Ruby File.fnmatch documentation.`,\n type: 'array',\n items: {\n type: 'string',\n },\n },\n customTagPolicyNames: {\n title: 'Custom Tag Policy Name',\n description: `The name pattern that tags must match in order to deploy to the environment.\n\n Wildcard characters will not match /. For example, to match tags that begin with release/ and contain an additional single slash, use release/*/*. For more information about pattern matching syntax, see the Ruby File.fnmatch documentation.`,\n type: 'array',\n items: {\n type: 'string',\n },\n },\n environmentVariables: {\n title: 'Environment Variables',\n description: `Environment variables attached to the deployment environment`,\n type: 'object',\n },\n secrets: {\n title: 'Deployment Secrets',\n description: `Secrets attached to the deployment environment`,\n type: 'object',\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The token to use for authorization to GitHub',\n },\n waitTimer: {\n title: 'Wait Timer',\n type: 'integer',\n description:\n 'The time to wait before creating or updating the environment (in milliseconds)',\n },\n preventSelfReview: {\n title: 'Prevent Self Review',\n type: 'boolean',\n description: 'Whether to prevent self-review for this environment',\n },\n reviewers: {\n title: 'Reviewers',\n type: 'array',\n description:\n 'Reviewers for this environment. Must be a list of Backstage entity references.',\n items: {\n type: 'string',\n },\n },\n },\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n name,\n deploymentBranchPolicy,\n customBranchPolicyNames,\n customTagPolicyNames,\n environmentVariables,\n secrets,\n token: providedToken,\n waitTimer,\n preventSelfReview,\n reviewers,\n } = ctx.input;\n\n const { token } = (await auth?.getPluginRequestToken({\n onBehalfOf: await ctx.getInitiatorCredentials(),\n targetPluginId: 'catalog',\n })) ?? { token: ctx.secrets?.backstageToken };\n\n // When environment creation step is executed right after a repo publish step, the repository might not be available immediately.\n // Add a 2-second delay before initiating the steps in this action.\n await new Promise(resolve => setTimeout(resolve, 2000));\n\n const { host, owner, repo } = parseRepoUrl(repoUrl, integrations);\n\n if (!owner) {\n throw new InputError(`No owner provided for repo ${repoUrl}`);\n }\n\n const octokitOptions = await getOctokitOptions({\n integrations,\n token: providedToken,\n host,\n owner,\n repo,\n });\n\n const client = new Octokit(octokitOptions);\n const repository = await client.rest.repos.get({\n owner: owner,\n repo: repo,\n });\n\n // convert reviewers from catalog entity to Github user or team\n const githubReviewers: { type: 'User' | 'Team'; id: number }[] = [];\n if (reviewers) {\n let reviewersEntityRefs: Array<Entity | undefined> = [];\n // Fetch reviewers from Catalog\n const catalogResponse = await catalogClient?.getEntitiesByRefs(\n {\n entityRefs: reviewers,\n },\n {\n token,\n },\n );\n if (catalogResponse?.items?.length) {\n reviewersEntityRefs = catalogResponse.items;\n }\n\n for (const reviewerEntityRef of reviewersEntityRefs) {\n if (reviewerEntityRef?.kind === 'User') {\n try {\n const user = await client.rest.users.getByUsername({\n username: reviewerEntityRef.metadata.name,\n });\n githubReviewers.push({\n type: 'User',\n id: user.data.id,\n });\n } catch (error) {\n ctx.logger.error('User not found:', error);\n }\n } else if (reviewerEntityRef?.kind === 'Group') {\n try {\n const team = await client.rest.teams.getByName({\n org: owner,\n team_slug: reviewerEntityRef.metadata.name,\n });\n githubReviewers.push({\n type: 'Team',\n id: team.data.id,\n });\n } catch (error) {\n ctx.logger.error('Team not found:', error);\n }\n }\n }\n }\n\n await client.rest.repos.createOrUpdateEnvironment({\n owner: owner,\n repo: repo,\n environment_name: name,\n deployment_branch_policy: deploymentBranchPolicy ?? null,\n wait_timer: waitTimer ?? 0,\n prevent_self_review: preventSelfReview ?? false,\n reviewers: githubReviewers.length ? githubReviewers : null,\n });\n\n if (customBranchPolicyNames) {\n for (const item of customBranchPolicyNames) {\n await client.rest.repos.createDeploymentBranchPolicy({\n owner: owner,\n repo: repo,\n type: 'branch',\n environment_name: name,\n name: item,\n });\n }\n }\n\n if (customTagPolicyNames) {\n for (const item of customTagPolicyNames) {\n await client.rest.repos.createDeploymentBranchPolicy({\n owner: owner,\n repo: repo,\n type: 'tag',\n environment_name: name,\n name: item,\n });\n }\n }\n\n for (const [key, value] of Object.entries(environmentVariables ?? {})) {\n await client.rest.actions.createEnvironmentVariable({\n repository_id: repository.data.id,\n owner: owner,\n repo: repo,\n environment_name: name,\n name: key,\n value,\n });\n }\n\n if (secrets) {\n const publicKeyResponse =\n await client.rest.actions.getEnvironmentPublicKey({\n repository_id: repository.data.id,\n owner: owner,\n repo: repo,\n environment_name: name,\n });\n\n await Sodium.ready;\n const binaryKey = Sodium.from_base64(\n publicKeyResponse.data.key,\n Sodium.base64_variants.ORIGINAL,\n );\n for (const [key, value] of Object.entries(secrets)) {\n const binarySecret = Sodium.from_string(value);\n const encryptedBinarySecret = Sodium.crypto_box_seal(\n binarySecret,\n binaryKey,\n );\n const encryptedBase64Secret = Sodium.to_base64(\n encryptedBinarySecret,\n Sodium.base64_variants.ORIGINAL,\n );\n\n await client.rest.actions.createOrUpdateEnvironmentSecret({\n repository_id: repository.data.id,\n owner: owner,\n repo: repo,\n environment_name: name,\n secret_name: key,\n encrypted_value: encryptedBase64Secret,\n key_id: publicKeyResponse.data.key_id,\n });\n }\n }\n },\n });\n}\n"],"names":["createTemplateAction","examples","parseRepoUrl","InputError","getOctokitOptions","Octokit","Sodium"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"githubEnvironment.cjs.js","sources":["../../src/actions/githubEnvironment.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 { InputError } from '@backstage/errors';\nimport {\n createTemplateAction,\n parseRepoUrl,\n} from '@backstage/plugin-scaffolder-node';\nimport { ScmIntegrationRegistry } from '@backstage/integration';\nimport { getOctokitOptions } from '../util';\nimport { Octokit } from 'octokit';\nimport Sodium from 'libsodium-wrappers';\nimport { examples } from './gitHubEnvironment.examples';\nimport { CatalogApi } from '@backstage/catalog-client';\nimport { Entity } from '@backstage/catalog-model';\nimport { AuthService } from '@backstage/backend-plugin-api';\n\n/**\n * Creates an `github:environment:create` Scaffolder action that creates a Github Environment.\n *\n * @public\n */\nexport function createGithubEnvironmentAction(options: {\n integrations: ScmIntegrationRegistry;\n catalogClient?: CatalogApi;\n auth?: AuthService;\n}) {\n const { integrations, catalogClient, auth } = options;\n // For more information on how to define custom actions, see\n // https://backstage.io/docs/features/software-templates/writing-custom-actions\n return createTemplateAction<{\n repoUrl: string;\n name: string;\n deploymentBranchPolicy?: {\n protected_branches: boolean;\n custom_branch_policies: boolean;\n };\n customBranchPolicyNames?: string[];\n customTagPolicyNames?: string[];\n environmentVariables?: { [key: string]: string };\n secrets?: { [key: string]: string };\n token?: string;\n waitTimer?: number;\n preventSelfReview?: boolean;\n reviewers?: string[];\n }>({\n id: 'github:environment:create',\n description: 'Creates Deployment Environments',\n examples,\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl', 'name'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description:\n 'Accepts the format `github.com?repo=reponame&owner=owner` where `reponame` is the new repository name and `owner` is an organization or username',\n type: 'string',\n },\n name: {\n title: 'Environment Name',\n description: `Name of the deployment environment to create`,\n type: 'string',\n },\n deploymentBranchPolicy: {\n title: 'Deployment Branch Policy',\n description:\n 'The type of deployment branch policy for this environment. To allow all branches to deploy, set to `null`.',\n type: 'object',\n required: ['protected_branches', 'custom_branch_policies'],\n properties: {\n protected_branches: {\n title: 'Protected Branches',\n description:\n 'Whether only branches with branch protection rules can deploy to this environment. If `protected_branches` is `true`, `custom_branch_policies` must be `false`; if `protected_branches` is `false`, `custom_branch_policies` must be `true`.',\n type: 'boolean',\n },\n custom_branch_policies: {\n title: 'Custom Branch Policies',\n description:\n 'Whether only branches that match the specified name patterns can deploy to this environment. If `custom_branch_policies` is `true`, `protected_branches` must be `false`; if `custom_branch_policies` is `false`, `protected_branches` must be `true`.',\n type: 'boolean',\n },\n },\n },\n customBranchPolicyNames: {\n title: 'Custom Branch Policy Name',\n description: `The name pattern that branches must match in order to deploy to the environment.\n\nWildcard characters will not match \\`/\\`. For example, to match branches that begin with \\`release/\\` and contain an additional single slash, use \\`release/*/*\\`. For more information about pattern matching syntax, see the Ruby File.fnmatch documentation.`,\n type: 'array',\n items: {\n type: 'string',\n },\n },\n customTagPolicyNames: {\n title: 'Custom Tag Policy Name',\n description: `The name pattern that tags must match in order to deploy to the environment.\n\nWildcard characters will not match \\`/\\`. For example, to match tags that begin with \\`release/\\` and contain an additional single slash, use \\`release/*/*\\`. For more information about pattern matching syntax, see the Ruby File.fnmatch documentation.`,\n type: 'array',\n items: {\n type: 'string',\n },\n },\n environmentVariables: {\n title: 'Environment Variables',\n description: `Environment variables attached to the deployment environment`,\n type: 'object',\n },\n secrets: {\n title: 'Deployment Secrets',\n description: `Secrets attached to the deployment environment`,\n type: 'object',\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description: 'The token to use for authorization to GitHub',\n },\n waitTimer: {\n title: 'Wait Timer',\n type: 'integer',\n description:\n 'The time to wait before creating or updating the environment (in milliseconds)',\n },\n preventSelfReview: {\n title: 'Prevent Self Review',\n type: 'boolean',\n description: 'Whether to prevent self-review for this environment',\n },\n reviewers: {\n title: 'Reviewers',\n type: 'array',\n description:\n 'Reviewers for this environment. Must be a list of Backstage entity references.',\n items: {\n type: 'string',\n },\n },\n },\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n name,\n deploymentBranchPolicy,\n customBranchPolicyNames,\n customTagPolicyNames,\n environmentVariables,\n secrets,\n token: providedToken,\n waitTimer,\n preventSelfReview,\n reviewers,\n } = ctx.input;\n\n const { token } = (await auth?.getPluginRequestToken({\n onBehalfOf: await ctx.getInitiatorCredentials(),\n targetPluginId: 'catalog',\n })) ?? { token: ctx.secrets?.backstageToken };\n\n // When environment creation step is executed right after a repo publish step, the repository might not be available immediately.\n // Add a 2-second delay before initiating the steps in this action.\n await new Promise(resolve => setTimeout(resolve, 2000));\n\n const { host, owner, repo } = parseRepoUrl(repoUrl, integrations);\n\n if (!owner) {\n throw new InputError(`No owner provided for repo ${repoUrl}`);\n }\n\n const octokitOptions = await getOctokitOptions({\n integrations,\n token: providedToken,\n host,\n owner,\n repo,\n });\n\n const client = new Octokit(octokitOptions);\n const repository = await client.rest.repos.get({\n owner: owner,\n repo: repo,\n });\n\n // convert reviewers from catalog entity to Github user or team\n const githubReviewers: { type: 'User' | 'Team'; id: number }[] = [];\n if (reviewers) {\n let reviewersEntityRefs: Array<Entity | undefined> = [];\n // Fetch reviewers from Catalog\n const catalogResponse = await catalogClient?.getEntitiesByRefs(\n {\n entityRefs: reviewers,\n },\n {\n token,\n },\n );\n if (catalogResponse?.items?.length) {\n reviewersEntityRefs = catalogResponse.items;\n }\n\n for (const reviewerEntityRef of reviewersEntityRefs) {\n if (reviewerEntityRef?.kind === 'User') {\n try {\n const user = await client.rest.users.getByUsername({\n username: reviewerEntityRef.metadata.name,\n });\n githubReviewers.push({\n type: 'User',\n id: user.data.id,\n });\n } catch (error) {\n ctx.logger.error('User not found:', error);\n }\n } else if (reviewerEntityRef?.kind === 'Group') {\n try {\n const team = await client.rest.teams.getByName({\n org: owner,\n team_slug: reviewerEntityRef.metadata.name,\n });\n githubReviewers.push({\n type: 'Team',\n id: team.data.id,\n });\n } catch (error) {\n ctx.logger.error('Team not found:', error);\n }\n }\n }\n }\n\n await client.rest.repos.createOrUpdateEnvironment({\n owner: owner,\n repo: repo,\n environment_name: name,\n deployment_branch_policy: deploymentBranchPolicy ?? null,\n wait_timer: waitTimer ?? 0,\n prevent_self_review: preventSelfReview ?? false,\n reviewers: githubReviewers.length ? githubReviewers : null,\n });\n\n if (customBranchPolicyNames) {\n for (const item of customBranchPolicyNames) {\n await client.rest.repos.createDeploymentBranchPolicy({\n owner: owner,\n repo: repo,\n type: 'branch',\n environment_name: name,\n name: item,\n });\n }\n }\n\n if (customTagPolicyNames) {\n for (const item of customTagPolicyNames) {\n await client.rest.repos.createDeploymentBranchPolicy({\n owner: owner,\n repo: repo,\n type: 'tag',\n environment_name: name,\n name: item,\n });\n }\n }\n\n for (const [key, value] of Object.entries(environmentVariables ?? {})) {\n await client.rest.actions.createEnvironmentVariable({\n repository_id: repository.data.id,\n owner: owner,\n repo: repo,\n environment_name: name,\n name: key,\n value,\n });\n }\n\n if (secrets) {\n const publicKeyResponse =\n await client.rest.actions.getEnvironmentPublicKey({\n repository_id: repository.data.id,\n owner: owner,\n repo: repo,\n environment_name: name,\n });\n\n await Sodium.ready;\n const binaryKey = Sodium.from_base64(\n publicKeyResponse.data.key,\n Sodium.base64_variants.ORIGINAL,\n );\n for (const [key, value] of Object.entries(secrets)) {\n const binarySecret = Sodium.from_string(value);\n const encryptedBinarySecret = Sodium.crypto_box_seal(\n binarySecret,\n binaryKey,\n );\n const encryptedBase64Secret = Sodium.to_base64(\n encryptedBinarySecret,\n Sodium.base64_variants.ORIGINAL,\n );\n\n await client.rest.actions.createOrUpdateEnvironmentSecret({\n repository_id: repository.data.id,\n owner: owner,\n repo: repo,\n environment_name: name,\n secret_name: key,\n encrypted_value: encryptedBase64Secret,\n key_id: publicKeyResponse.data.key_id,\n });\n }\n }\n },\n });\n}\n"],"names":["createTemplateAction","examples","parseRepoUrl","InputError","getOctokitOptions","Octokit","Sodium"],"mappings":"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"}
|
|
@@ -19,7 +19,7 @@ function createGithubIssuesLabelAction(options) {
|
|
|
19
19
|
properties: {
|
|
20
20
|
repoUrl: {
|
|
21
21
|
title: "Repository Location",
|
|
22
|
-
description:
|
|
22
|
+
description: "Accepts the format `github.com?repo=reponame&owner=owner` where `reponame` is the repository name and `owner` is an organization or username",
|
|
23
23
|
type: "string"
|
|
24
24
|
},
|
|
25
25
|
number: {
|
|
@@ -38,7 +38,7 @@ function createGithubIssuesLabelAction(options) {
|
|
|
38
38
|
token: {
|
|
39
39
|
title: "Authentication Token",
|
|
40
40
|
type: "string",
|
|
41
|
-
description: "The GITHUB_TOKEN to use for authorization to GitHub"
|
|
41
|
+
description: "The `GITHUB_TOKEN` to use for authorization to GitHub"
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"githubIssuesLabel.cjs.js","sources":["../../src/actions/githubIssuesLabel.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 {\n GithubCredentialsProvider,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\nimport {\n createTemplateAction,\n parseRepoUrl,\n} from '@backstage/plugin-scaffolder-node';\nimport { assertError, InputError } from '@backstage/errors';\nimport { Octokit } from 'octokit';\nimport { getOctokitOptions } from '../util';\nimport { examples } from './githubIssuesLabel.examples';\n\n/**\n * Adds labels to a pull request or issue on GitHub\n * @public\n */\nexport function createGithubIssuesLabelAction(options: {\n integrations: ScmIntegrationRegistry;\n githubCredentialsProvider?: GithubCredentialsProvider;\n}) {\n const { integrations, githubCredentialsProvider } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n number: number;\n labels: string[];\n token?: string;\n }>({\n id: 'github:issues:label',\n description: 'Adds labels to a pull request or issue on GitHub.',\n examples,\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl', 'number', 'labels'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description
|
|
1
|
+
{"version":3,"file":"githubIssuesLabel.cjs.js","sources":["../../src/actions/githubIssuesLabel.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 {\n GithubCredentialsProvider,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\nimport {\n createTemplateAction,\n parseRepoUrl,\n} from '@backstage/plugin-scaffolder-node';\nimport { assertError, InputError } from '@backstage/errors';\nimport { Octokit } from 'octokit';\nimport { getOctokitOptions } from '../util';\nimport { examples } from './githubIssuesLabel.examples';\n\n/**\n * Adds labels to a pull request or issue on GitHub\n * @public\n */\nexport function createGithubIssuesLabelAction(options: {\n integrations: ScmIntegrationRegistry;\n githubCredentialsProvider?: GithubCredentialsProvider;\n}) {\n const { integrations, githubCredentialsProvider } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n number: number;\n labels: string[];\n token?: string;\n }>({\n id: 'github:issues:label',\n description: 'Adds labels to a pull request or issue on GitHub.',\n examples,\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl', 'number', 'labels'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description:\n 'Accepts the format `github.com?repo=reponame&owner=owner` where `reponame` is the repository name and `owner` is an organization or username',\n type: 'string',\n },\n number: {\n title: 'Pull Request or issue number',\n description: 'The pull request or issue number to add labels to',\n type: 'number',\n },\n labels: {\n title: 'Labels',\n description: 'The labels to add to the pull request or issue',\n type: 'array',\n items: {\n type: 'string',\n },\n },\n token: {\n title: 'Authentication Token',\n type: 'string',\n description:\n 'The `GITHUB_TOKEN` to use for authorization to GitHub',\n },\n },\n },\n },\n async handler(ctx) {\n const { repoUrl, number, labels, token: providedToken } = ctx.input;\n\n const { host, owner, repo } = parseRepoUrl(repoUrl, integrations);\n ctx.logger.info(`Adding labels to ${number} issue on repo ${repo}`);\n\n if (!owner) {\n throw new InputError('Invalid repository owner provided in repoUrl');\n }\n\n const client = new Octokit(\n await getOctokitOptions({\n integrations,\n credentialsProvider: githubCredentialsProvider,\n host,\n owner,\n repo,\n token: providedToken,\n }),\n );\n\n try {\n await client.rest.issues.addLabels({\n owner,\n repo,\n issue_number: number,\n labels,\n });\n } catch (e) {\n assertError(e);\n ctx.logger.warn(\n `Failed: adding labels to issue: '${number}' on repo: '${repo}', ${e.message}`,\n );\n }\n },\n });\n}\n"],"names":["createTemplateAction","examples","parseRepoUrl","InputError","Octokit","getOctokitOptions","assertError"],"mappings":";;;;;;;;AAiCO,SAAS,8BAA8B,OAG3C,EAAA;AACD,EAAM,MAAA,EAAE,YAAc,EAAA,yBAAA,EAA8B,GAAA,OAAA;AAEpD,EAAA,OAAOA,yCAKJ,CAAA;AAAA,IACD,EAAI,EAAA,qBAAA;AAAA,IACJ,WAAa,EAAA,mDAAA;AAAA,cACbC,mCAAA;AAAA,IACA,MAAQ,EAAA;AAAA,MACN,KAAO,EAAA;AAAA,QACL,IAAM,EAAA,QAAA;AAAA,QACN,QAAU,EAAA,CAAC,SAAW,EAAA,QAAA,EAAU,QAAQ,CAAA;AAAA,QACxC,UAAY,EAAA;AAAA,UACV,OAAS,EAAA;AAAA,YACP,KAAO,EAAA,qBAAA;AAAA,YACP,WACE,EAAA,8IAAA;AAAA,YACF,IAAM,EAAA;AAAA,WACR;AAAA,UACA,MAAQ,EAAA;AAAA,YACN,KAAO,EAAA,8BAAA;AAAA,YACP,WAAa,EAAA,mDAAA;AAAA,YACb,IAAM,EAAA;AAAA,WACR;AAAA,UACA,MAAQ,EAAA;AAAA,YACN,KAAO,EAAA,QAAA;AAAA,YACP,WAAa,EAAA,gDAAA;AAAA,YACb,IAAM,EAAA,OAAA;AAAA,YACN,KAAO,EAAA;AAAA,cACL,IAAM,EAAA;AAAA;AACR,WACF;AAAA,UACA,KAAO,EAAA;AAAA,YACL,KAAO,EAAA,sBAAA;AAAA,YACP,IAAM,EAAA,QAAA;AAAA,YACN,WACE,EAAA;AAAA;AACJ;AACF;AACF,KACF;AAAA,IACA,MAAM,QAAQ,GAAK,EAAA;AACjB,MAAA,MAAM,EAAE,OAAS,EAAA,MAAA,EAAQ,QAAQ,KAAO,EAAA,aAAA,KAAkB,GAAI,CAAA,KAAA;AAE9D,MAAA,MAAM,EAAE,IAAM,EAAA,KAAA,EAAO,MAAS,GAAAC,iCAAA,CAAa,SAAS,YAAY,CAAA;AAChE,MAAA,GAAA,CAAI,OAAO,IAAK,CAAA,CAAA,iBAAA,EAAoB,MAAM,CAAA,eAAA,EAAkB,IAAI,CAAE,CAAA,CAAA;AAElE,MAAA,IAAI,CAAC,KAAO,EAAA;AACV,QAAM,MAAA,IAAIC,kBAAW,8CAA8C,CAAA;AAAA;AAGrE,MAAA,MAAM,SAAS,IAAIC,eAAA;AAAA,QACjB,MAAMC,sBAAkB,CAAA;AAAA,UACtB,YAAA;AAAA,UACA,mBAAqB,EAAA,yBAAA;AAAA,UACrB,IAAA;AAAA,UACA,KAAA;AAAA,UACA,IAAA;AAAA,UACA,KAAO,EAAA;AAAA,SACR;AAAA,OACH;AAEA,MAAI,IAAA;AACF,QAAM,MAAA,MAAA,CAAO,IAAK,CAAA,MAAA,CAAO,SAAU,CAAA;AAAA,UACjC,KAAA;AAAA,UACA,IAAA;AAAA,UACA,YAAc,EAAA,MAAA;AAAA,UACd;AAAA,SACD,CAAA;AAAA,eACM,CAAG,EAAA;AACV,QAAAC,kBAAA,CAAY,CAAC,CAAA;AACb,QAAA,GAAA,CAAI,MAAO,CAAA,IAAA;AAAA,UACT,oCAAoC,MAAM,CAAA,YAAA,EAAe,IAAI,CAAA,GAAA,EAAM,EAAE,OAAO,CAAA;AAAA,SAC9E;AAAA;AACF;AACF,GACD,CAAA;AACH;;;;"}
|
|
@@ -19,23 +19,28 @@ function createGithubPagesEnableAction(options) {
|
|
|
19
19
|
properties: {
|
|
20
20
|
repoUrl: {
|
|
21
21
|
title: "Repository Location",
|
|
22
|
-
description:
|
|
22
|
+
description: "Accepts the format `github.com?repo=reponame&owner=owner` where `reponame` is the new repository name and `owner` is an organization or username",
|
|
23
23
|
type: "string"
|
|
24
24
|
},
|
|
25
25
|
buildType: {
|
|
26
26
|
title: "Build Type",
|
|
27
27
|
type: "string",
|
|
28
|
-
|
|
28
|
+
default: "workflow",
|
|
29
|
+
description: "The GitHub Pages build type - `legacy` or `workflow`. Default is `workflow`",
|
|
30
|
+
enum: ["legacy", "workflow"]
|
|
29
31
|
},
|
|
30
32
|
sourceBranch: {
|
|
31
33
|
title: "Source Branch",
|
|
32
34
|
type: "string",
|
|
35
|
+
default: "main",
|
|
33
36
|
description: 'The GitHub Pages source branch. Default is "main"'
|
|
34
37
|
},
|
|
35
38
|
sourcePath: {
|
|
36
39
|
title: "Source Path",
|
|
37
40
|
type: "string",
|
|
38
|
-
|
|
41
|
+
default: "/",
|
|
42
|
+
description: 'The GitHub Pages source path - "/" or "/docs". Default is "/"',
|
|
43
|
+
enum: ["/", "/docs"]
|
|
39
44
|
},
|
|
40
45
|
token: {
|
|
41
46
|
title: "Authorization Token",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"githubPagesEnable.cjs.js","sources":["../../src/actions/githubPagesEnable.ts"],"sourcesContent":["/*\n * Copyright 2024 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 { InputError } from '@backstage/errors';\nimport {\n GithubCredentialsProvider,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\nimport { Octokit } from 'octokit';\nimport {\n createTemplateAction,\n parseRepoUrl,\n} from '@backstage/plugin-scaffolder-node';\nimport { examples } from './githubPagesEnable.examples';\nimport { getOctokitOptions } from '../util';\n\n/**\n * Creates a new action that enables GitHub Pages for a repository.\n *\n * @public\n */\nexport function createGithubPagesEnableAction(options: {\n integrations: ScmIntegrationRegistry;\n githubCredentialsProvider?: GithubCredentialsProvider;\n}) {\n const { integrations, githubCredentialsProvider } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n buildType?: 'legacy' | 'workflow';\n sourceBranch?: string;\n sourcePath?: '/' | '/docs';\n token?: string;\n }>({\n id: 'github:pages:enable',\n examples,\n description: 'Enables GitHub Pages for a repository.',\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description
|
|
1
|
+
{"version":3,"file":"githubPagesEnable.cjs.js","sources":["../../src/actions/githubPagesEnable.ts"],"sourcesContent":["/*\n * Copyright 2024 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 { InputError } from '@backstage/errors';\nimport {\n GithubCredentialsProvider,\n ScmIntegrationRegistry,\n} from '@backstage/integration';\nimport { Octokit } from 'octokit';\nimport {\n createTemplateAction,\n parseRepoUrl,\n} from '@backstage/plugin-scaffolder-node';\nimport { examples } from './githubPagesEnable.examples';\nimport { getOctokitOptions } from '../util';\n\n/**\n * Creates a new action that enables GitHub Pages for a repository.\n *\n * @public\n */\nexport function createGithubPagesEnableAction(options: {\n integrations: ScmIntegrationRegistry;\n githubCredentialsProvider?: GithubCredentialsProvider;\n}) {\n const { integrations, githubCredentialsProvider } = options;\n\n return createTemplateAction<{\n repoUrl: string;\n buildType?: 'legacy' | 'workflow';\n sourceBranch?: string;\n sourcePath?: '/' | '/docs';\n token?: string;\n }>({\n id: 'github:pages:enable',\n examples,\n description: 'Enables GitHub Pages for a repository.',\n schema: {\n input: {\n type: 'object',\n required: ['repoUrl'],\n properties: {\n repoUrl: {\n title: 'Repository Location',\n description:\n 'Accepts the format `github.com?repo=reponame&owner=owner` where `reponame` is the new repository name and `owner` is an organization or username',\n type: 'string',\n },\n buildType: {\n title: 'Build Type',\n type: 'string',\n default: 'workflow',\n description:\n 'The GitHub Pages build type - `legacy` or `workflow`. Default is `workflow`',\n enum: ['legacy', 'workflow'],\n },\n sourceBranch: {\n title: 'Source Branch',\n type: 'string',\n default: 'main',\n description: 'The GitHub Pages source branch. Default is \"main\"',\n },\n sourcePath: {\n title: 'Source Path',\n type: 'string',\n default: '/',\n description:\n 'The GitHub Pages source path - \"/\" or \"/docs\". Default is \"/\"',\n enum: ['/', '/docs'],\n },\n token: {\n title: 'Authorization Token',\n type: 'string',\n description: 'The token to use for authorization to GitHub',\n },\n },\n },\n },\n async handler(ctx) {\n const {\n repoUrl,\n buildType = 'workflow',\n sourceBranch = 'main',\n sourcePath = '/',\n token: providedToken,\n } = ctx.input;\n\n const { host, owner, repo } = parseRepoUrl(repoUrl, integrations);\n\n if (!owner) {\n throw new InputError('Invalid repository owner provided in repoUrl');\n }\n\n const octokitOptions = await getOctokitOptions({\n integrations,\n credentialsProvider: githubCredentialsProvider,\n token: providedToken,\n host,\n owner,\n repo,\n });\n const client = new Octokit(octokitOptions);\n\n ctx.logger.info(\n `Attempting to enable GitHub Pages for ${owner}/${repo} with \"${buildType}\" build type, on source branch \"${sourceBranch}\" and source path \"${sourcePath}\"`,\n );\n\n await client.request('POST /repos/{owner}/{repo}/pages', {\n owner: owner,\n repo: repo,\n build_type: buildType,\n source: {\n branch: sourceBranch,\n path: sourcePath,\n },\n headers: {\n 'X-GitHub-Api-Version': '2022-11-28',\n },\n });\n\n ctx.logger.info('Completed enabling GitHub Pages');\n },\n });\n}\n"],"names":["createTemplateAction","examples","parseRepoUrl","InputError","getOctokitOptions","Octokit"],"mappings":"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"}
|
|
@@ -55,7 +55,7 @@ const createPublishGithubPullRequestAction = (options) => {
|
|
|
55
55
|
properties: {
|
|
56
56
|
repoUrl: {
|
|
57
57
|
title: "Repository Location",
|
|
58
|
-
description:
|
|
58
|
+
description: "Accepts the format `github.com?repo=reponame&owner=owner` where `reponame` is the repository name and `owner` is an organization or username",
|
|
59
59
|
type: "string"
|
|
60
60
|
},
|
|
61
61
|
branchName: {
|
|
@@ -66,7 +66,7 @@ const createPublishGithubPullRequestAction = (options) => {
|
|
|
66
66
|
targetBranchName: {
|
|
67
67
|
type: "string",
|
|
68
68
|
title: "Target Branch Name",
|
|
69
|
-
description: "The target branch name of the
|
|
69
|
+
description: "The target branch name of the pull request"
|
|
70
70
|
},
|
|
71
71
|
title: {
|
|
72
72
|
type: "string",
|
|
@@ -132,22 +132,27 @@ const createPublishGithubPullRequestAction = (options) => {
|
|
|
132
132
|
gitAuthorName: {
|
|
133
133
|
type: "string",
|
|
134
134
|
title: "Default Author Name",
|
|
135
|
-
description: "Sets the default author name for the commit. The default value is the authenticated user or
|
|
135
|
+
description: "Sets the default author name for the commit. The default value is the authenticated user or `Scaffolder`"
|
|
136
136
|
},
|
|
137
137
|
gitAuthorEmail: {
|
|
138
138
|
type: "string",
|
|
139
139
|
title: "Default Author Email",
|
|
140
|
-
description: "Sets the default author email for the commit. The default value is the authenticated user or
|
|
140
|
+
description: "Sets the default author email for the commit. The default value is the authenticated user or `scaffolder@backstage.io`"
|
|
141
141
|
},
|
|
142
142
|
forceEmptyGitAuthor: {
|
|
143
143
|
type: "boolean",
|
|
144
144
|
title: "Force Empty Git Author",
|
|
145
145
|
description: "Forces the author to be empty. This is useful when using a Github App, it permit the commit to be verified on Github"
|
|
146
|
+
},
|
|
147
|
+
createWhenEmpty: {
|
|
148
|
+
type: "boolean",
|
|
149
|
+
title: "Create When Empty",
|
|
150
|
+
description: "Set whether to create pull request when there are no changes to commit. The default value is true. If set to false, remoteUrl is no longer a required output."
|
|
146
151
|
}
|
|
147
152
|
}
|
|
148
153
|
},
|
|
149
154
|
output: {
|
|
150
|
-
required: [
|
|
155
|
+
required: [],
|
|
151
156
|
type: "object",
|
|
152
157
|
properties: {
|
|
153
158
|
targetBranchName: {
|
|
@@ -185,7 +190,8 @@ const createPublishGithubPullRequestAction = (options) => {
|
|
|
185
190
|
forceFork,
|
|
186
191
|
gitAuthorEmail,
|
|
187
192
|
gitAuthorName,
|
|
188
|
-
forceEmptyGitAuthor
|
|
193
|
+
forceEmptyGitAuthor,
|
|
194
|
+
createWhenEmpty
|
|
189
195
|
} = ctx.input;
|
|
190
196
|
const { owner, repo, host } = pluginScaffolderNode.parseRepoUrl(repoUrl, integrations);
|
|
191
197
|
if (!owner) {
|
|
@@ -253,7 +259,8 @@ const createPublishGithubPullRequestAction = (options) => {
|
|
|
253
259
|
head: branchName,
|
|
254
260
|
draft,
|
|
255
261
|
update,
|
|
256
|
-
forceFork
|
|
262
|
+
forceFork,
|
|
263
|
+
createWhenEmpty
|
|
257
264
|
};
|
|
258
265
|
const gitAuthorInfo = {
|
|
259
266
|
name: gitAuthorName ?? config?.getOptionalString("scaffolder.defaultAuthor.name"),
|
|
@@ -284,6 +291,10 @@ const createPublishGithubPullRequestAction = (options) => {
|
|
|
284
291
|
createOptions.base = targetBranchName;
|
|
285
292
|
}
|
|
286
293
|
const response = await client.createPullRequest(createOptions);
|
|
294
|
+
if (createWhenEmpty === false && !response) {
|
|
295
|
+
ctx.logger.info("No changes to commit, pull request was not created");
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
287
298
|
if (!response) {
|
|
288
299
|
throw new GithubResponseError("null response from Github");
|
|
289
300
|
}
|