@backstage/cli-module-github 0.0.0-nightly-20260317031259
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 +13 -0
- package/README.md +14 -0
- package/bin/backstage-cli-module-github +32 -0
- package/dist/commands/create-github-app/GithubCreateAppServer.cjs.js +127 -0
- package/dist/commands/create-github-app/GithubCreateAppServer.cjs.js.map +1 -0
- package/dist/commands/create-github-app/index.cjs.js +126 -0
- package/dist/commands/create-github-app/index.cjs.js.map +1 -0
- package/dist/index.cjs.js +20 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/package.json.cjs.js +89 -0
- package/dist/package.json.cjs.js.map +1 -0
- package/package.json +59 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# @backstage/cli-module-github
|
|
2
|
+
|
|
3
|
+
## 0.0.0-nightly-20260317031259
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 329f394: Initial release of the CLI module packages. Each module provides a set of commands that can be discovered automatically by `@backstage/cli` or executed standalone.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
- @backstage/cli-node@0.0.0-nightly-20260317031259
|
|
13
|
+
- @backstage/cli-common@0.0.0-nightly-20260317031259
|
package/README.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# @backstage/cli-module-github
|
|
2
|
+
|
|
3
|
+
CLI module that provides the `create-github-app` command for the Backstage CLI, used to create a new GitHub App in your organization for use with Backstage.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
| Command | Description |
|
|
8
|
+
| :------------------ | :----------------------------------------- |
|
|
9
|
+
| `create-github-app` | Create new GitHub App in your organization |
|
|
10
|
+
|
|
11
|
+
## Documentation
|
|
12
|
+
|
|
13
|
+
- [Backstage Readme](https://github.com/backstage/backstage/blob/master/README.md)
|
|
14
|
+
- [Backstage Documentation](https://backstage.io/docs)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/*
|
|
3
|
+
* Copyright 2024 The Backstage Authors
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const path = require('node:path');
|
|
19
|
+
|
|
20
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
|
21
|
+
const isLocal = require('node:fs').existsSync(
|
|
22
|
+
path.resolve(__dirname, '../src'),
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
if (isLocal) {
|
|
26
|
+
require('@backstage/cli-node/config/nodeTransform.cjs');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const { runCliModule } = require('@backstage/cli-node');
|
|
30
|
+
const cliModule = require(isLocal ? '../src/index' : '..').default;
|
|
31
|
+
const pkg = require('../package.json');
|
|
32
|
+
runCliModule({ module: cliModule, name: pkg.name, version: pkg.version });
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var crypto = require('node:crypto');
|
|
4
|
+
var openBrowser = require('react-dev-utils/openBrowser');
|
|
5
|
+
var request = require('@octokit/request');
|
|
6
|
+
var express = require('express');
|
|
7
|
+
|
|
8
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
9
|
+
|
|
10
|
+
var crypto__default = /*#__PURE__*/_interopDefaultCompat(crypto);
|
|
11
|
+
var openBrowser__default = /*#__PURE__*/_interopDefaultCompat(openBrowser);
|
|
12
|
+
var express__default = /*#__PURE__*/_interopDefaultCompat(express);
|
|
13
|
+
|
|
14
|
+
const FORM_PAGE = `
|
|
15
|
+
<html>
|
|
16
|
+
<body>
|
|
17
|
+
<form id="form" action="ACTION_URL" method="post">
|
|
18
|
+
<input type="hidden" name="manifest" value="MANIFEST_JSON">
|
|
19
|
+
<input type="submit" value="Continue">
|
|
20
|
+
</form>
|
|
21
|
+
<script>
|
|
22
|
+
document.getElementById("form").submit()
|
|
23
|
+
<\/script>
|
|
24
|
+
</body>
|
|
25
|
+
</html>
|
|
26
|
+
`;
|
|
27
|
+
class GithubCreateAppServer {
|
|
28
|
+
baseUrl;
|
|
29
|
+
webhookUrl;
|
|
30
|
+
static async run(options) {
|
|
31
|
+
const encodedOrg = encodeURIComponent(options.org);
|
|
32
|
+
const actionUrl = `https://github.com/organizations/${encodedOrg}/settings/apps/new`;
|
|
33
|
+
const server = new GithubCreateAppServer(actionUrl, options.permissions);
|
|
34
|
+
return server.start();
|
|
35
|
+
}
|
|
36
|
+
actionUrl;
|
|
37
|
+
permissions;
|
|
38
|
+
constructor(actionUrl, permissions) {
|
|
39
|
+
this.actionUrl = actionUrl;
|
|
40
|
+
this.permissions = permissions;
|
|
41
|
+
const webhookId = crypto__default.default.randomBytes(15).toString("base64").replace(/[\+\/]/g, "");
|
|
42
|
+
this.webhookUrl = `https://smee.io/${webhookId}`;
|
|
43
|
+
}
|
|
44
|
+
async start() {
|
|
45
|
+
const app = express__default.default();
|
|
46
|
+
app.get("/", this.formHandler);
|
|
47
|
+
const callPromise = new Promise((resolve, reject) => {
|
|
48
|
+
app.get("/callback", (req, res) => {
|
|
49
|
+
request.request(
|
|
50
|
+
`POST /app-manifests/${encodeURIComponent(
|
|
51
|
+
req.query.code
|
|
52
|
+
)}/conversions`
|
|
53
|
+
).then(({ data }) => {
|
|
54
|
+
resolve({
|
|
55
|
+
name: data.name,
|
|
56
|
+
slug: data.slug,
|
|
57
|
+
appId: data.id,
|
|
58
|
+
webhookUrl: this.webhookUrl,
|
|
59
|
+
clientId: data.client_id,
|
|
60
|
+
clientSecret: data.client_secret,
|
|
61
|
+
webhookSecret: data.webhook_secret,
|
|
62
|
+
privateKey: data.pem
|
|
63
|
+
});
|
|
64
|
+
res.redirect(302, `${data.html_url}/installations/new`);
|
|
65
|
+
}, reject);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
this.baseUrl = await this.listen(app);
|
|
69
|
+
openBrowser__default.default(this.baseUrl);
|
|
70
|
+
return callPromise;
|
|
71
|
+
}
|
|
72
|
+
formHandler = (_req, res) => {
|
|
73
|
+
const baseUrl = this.baseUrl;
|
|
74
|
+
if (!baseUrl) {
|
|
75
|
+
throw new Error("baseUrl is not set");
|
|
76
|
+
}
|
|
77
|
+
const manifest = {
|
|
78
|
+
default_events: ["create", "delete", "push", "repository"],
|
|
79
|
+
default_permissions: {
|
|
80
|
+
metadata: "read",
|
|
81
|
+
...this.permissions.includes("members") && {
|
|
82
|
+
members: "read"
|
|
83
|
+
},
|
|
84
|
+
...this.permissions.includes("read") && {
|
|
85
|
+
contents: "read",
|
|
86
|
+
checks: "read"
|
|
87
|
+
},
|
|
88
|
+
...this.permissions.includes("write") && {
|
|
89
|
+
contents: "write",
|
|
90
|
+
checks: "read",
|
|
91
|
+
actions: "write"
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
name: "Backstage-<changeme>",
|
|
95
|
+
url: "https://backstage.io",
|
|
96
|
+
description: "GitHub App for Backstage",
|
|
97
|
+
public: false,
|
|
98
|
+
redirect_url: `${baseUrl}/callback`,
|
|
99
|
+
hook_attributes: {
|
|
100
|
+
url: this.webhookUrl,
|
|
101
|
+
active: false
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const manifestJson = JSON.stringify(manifest).replace(/\"/g, """);
|
|
105
|
+
let body = FORM_PAGE;
|
|
106
|
+
body = body.replace("MANIFEST_JSON", manifestJson);
|
|
107
|
+
body = body.replace("ACTION_URL", this.actionUrl);
|
|
108
|
+
res.setHeader("content-type", "text/html");
|
|
109
|
+
res.send(body);
|
|
110
|
+
};
|
|
111
|
+
async listen(app) {
|
|
112
|
+
return new Promise((resolve, reject) => {
|
|
113
|
+
const listener = app.listen(0, () => {
|
|
114
|
+
const info = listener.address();
|
|
115
|
+
if (typeof info !== "object" || info === null) {
|
|
116
|
+
reject(new Error(`Unexpected listener info '${info}'`));
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const { port } = info;
|
|
120
|
+
resolve(`http://localhost:${port}`);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
exports.GithubCreateAppServer = GithubCreateAppServer;
|
|
127
|
+
//# sourceMappingURL=GithubCreateAppServer.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GithubCreateAppServer.cjs.js","sources":["../../../src/commands/create-github-app/GithubCreateAppServer.ts"],"sourcesContent":["/*\n * Copyright 2020 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 crypto from 'node:crypto';\nimport openBrowser from 'react-dev-utils/openBrowser';\nimport { request } from '@octokit/request';\nimport express, { Express, Request, Response } from 'express';\n\nconst FORM_PAGE = `\n<html>\n <body>\n <form id=\"form\" action=\"ACTION_URL\" method=\"post\">\n <input type=\"hidden\" name=\"manifest\" value=\"MANIFEST_JSON\">\n <input type=\"submit\" value=\"Continue\">\n </form>\n <script>\n document.getElementById(\"form\").submit()\n </script>\n </body>\n</html>\n`;\n\ntype GithubAppConfig = {\n appId: number;\n slug?: string;\n name?: string;\n webhookUrl?: string;\n clientId: string;\n clientSecret: string;\n webhookSecret: string;\n privateKey: string;\n};\n\nexport class GithubCreateAppServer {\n private baseUrl?: string;\n private webhookUrl?: string;\n\n static async run(options: {\n org: string;\n permissions: string[];\n }): Promise<GithubAppConfig> {\n const encodedOrg = encodeURIComponent(options.org);\n const actionUrl = `https://github.com/organizations/${encodedOrg}/settings/apps/new`;\n const server = new GithubCreateAppServer(actionUrl, options.permissions);\n return server.start();\n }\n\n private readonly actionUrl: string;\n private readonly permissions: string[];\n\n private constructor(actionUrl: string, permissions: string[]) {\n this.actionUrl = actionUrl;\n this.permissions = permissions;\n const webhookId = crypto\n .randomBytes(15)\n .toString('base64')\n .replace(/[\\+\\/]/g, '');\n\n this.webhookUrl = `https://smee.io/${webhookId}`;\n }\n\n private async start(): Promise<GithubAppConfig> {\n const app = express();\n\n app.get('/', this.formHandler);\n\n const callPromise = new Promise<GithubAppConfig>((resolve, reject) => {\n app.get('/callback', (req, res) => {\n request(\n `POST /app-manifests/${encodeURIComponent(\n req.query.code as string,\n )}/conversions`,\n ).then(({ data }) => {\n resolve({\n name: data.name,\n slug: data.slug,\n appId: data.id,\n webhookUrl: this.webhookUrl,\n clientId: data.client_id,\n clientSecret: data.client_secret,\n webhookSecret: data.webhook_secret,\n privateKey: data.pem,\n });\n res.redirect(302, `${data.html_url}/installations/new`);\n }, reject);\n });\n });\n\n this.baseUrl = await this.listen(app);\n\n openBrowser(this.baseUrl);\n\n return callPromise;\n }\n\n private formHandler = (_req: Request, res: Response) => {\n const baseUrl = this.baseUrl;\n if (!baseUrl) {\n throw new Error('baseUrl is not set');\n }\n\n const manifest = {\n default_events: ['create', 'delete', 'push', 'repository'],\n default_permissions: {\n metadata: 'read',\n ...(this.permissions.includes('members') && {\n members: 'read',\n }),\n ...(this.permissions.includes('read') && {\n contents: 'read',\n checks: 'read',\n }),\n ...(this.permissions.includes('write') && {\n contents: 'write',\n checks: 'read',\n actions: 'write',\n }),\n },\n name: 'Backstage-<changeme>',\n url: 'https://backstage.io',\n description: 'GitHub App for Backstage',\n public: false,\n redirect_url: `${baseUrl}/callback`,\n hook_attributes: {\n url: this.webhookUrl,\n active: false,\n },\n };\n\n const manifestJson = JSON.stringify(manifest).replace(/\\\"/g, '"');\n\n let body = FORM_PAGE;\n body = body.replace('MANIFEST_JSON', manifestJson);\n body = body.replace('ACTION_URL', this.actionUrl);\n\n res.setHeader('content-type', 'text/html');\n res.send(body);\n };\n\n private async listen(app: Express) {\n return new Promise<string>((resolve, reject) => {\n const listener = app.listen(0, () => {\n const info = listener.address();\n if (typeof info !== 'object' || info === null) {\n reject(new Error(`Unexpected listener info '${info}'`));\n return;\n }\n const { port } = info;\n resolve(`http://localhost:${port}`);\n });\n });\n }\n}\n"],"names":["crypto","express","request","openBrowser"],"mappings":"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"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var fs = require('fs-extra');
|
|
6
|
+
var chalk = require('chalk');
|
|
7
|
+
var yaml = require('yaml');
|
|
8
|
+
var inquirer = require('inquirer');
|
|
9
|
+
var cliCommon = require('@backstage/cli-common');
|
|
10
|
+
var cleye = require('cleye');
|
|
11
|
+
var GithubCreateAppServer = require('./GithubCreateAppServer.cjs.js');
|
|
12
|
+
var openBrowser = require('react-dev-utils/openBrowser');
|
|
13
|
+
|
|
14
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
15
|
+
|
|
16
|
+
var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
17
|
+
var chalk__default = /*#__PURE__*/_interopDefaultCompat(chalk);
|
|
18
|
+
var inquirer__default = /*#__PURE__*/_interopDefaultCompat(inquirer);
|
|
19
|
+
var openBrowser__default = /*#__PURE__*/_interopDefaultCompat(openBrowser);
|
|
20
|
+
|
|
21
|
+
var index = async ({ args, info }) => {
|
|
22
|
+
const { _: positionals } = cleye.cli(
|
|
23
|
+
{
|
|
24
|
+
help: { ...info, usage: `${info.usage} <github-org>` },
|
|
25
|
+
booleanFlagNegation: true,
|
|
26
|
+
parameters: ["<github-org>"]
|
|
27
|
+
},
|
|
28
|
+
void 0,
|
|
29
|
+
args
|
|
30
|
+
);
|
|
31
|
+
const org = positionals[0];
|
|
32
|
+
const answers = await inquirer__default.default.prompt({
|
|
33
|
+
name: "appType",
|
|
34
|
+
type: "checkbox",
|
|
35
|
+
message: "Select permissions [required] (these can be changed later but then require approvals in all installations)",
|
|
36
|
+
choices: [
|
|
37
|
+
{
|
|
38
|
+
name: "Read access to content (required by Software Catalog to ingest data from repositories)",
|
|
39
|
+
value: "read",
|
|
40
|
+
checked: true
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "Read access to members (required by Software Catalog to ingest GitHub teams)",
|
|
44
|
+
value: "members",
|
|
45
|
+
checked: true
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: "Read and Write to content and actions (required by Software Templates to create new repositories)",
|
|
49
|
+
value: "write"
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
});
|
|
53
|
+
if (answers.appType.length === 0) {
|
|
54
|
+
console.log(chalk__default.default.red("You must select at least one permission"));
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
await verifyGithubOrg(org);
|
|
58
|
+
const { slug, name, ...config } = await GithubCreateAppServer.GithubCreateAppServer.run({
|
|
59
|
+
org,
|
|
60
|
+
permissions: answers.appType
|
|
61
|
+
});
|
|
62
|
+
const fileName = `github-app-${slug}-credentials.yaml`;
|
|
63
|
+
const content = `# Name: ${name}
|
|
64
|
+
${yaml.stringify(config)}`;
|
|
65
|
+
await fs__default.default.writeFile(cliCommon.targetPaths.resolveRoot(fileName), content);
|
|
66
|
+
console.log(`GitHub App configuration written to ${chalk__default.default.cyan(fileName)}`);
|
|
67
|
+
console.log(
|
|
68
|
+
chalk__default.default.yellow(
|
|
69
|
+
"This file contains sensitive credentials, it should not be committed to version control and handled with care!"
|
|
70
|
+
)
|
|
71
|
+
);
|
|
72
|
+
console.log(
|
|
73
|
+
"Here's an example on how to update the integrations section in app-config.yaml"
|
|
74
|
+
);
|
|
75
|
+
console.log(
|
|
76
|
+
chalk__default.default.green(`
|
|
77
|
+
integrations:
|
|
78
|
+
github:
|
|
79
|
+
- host: github.com
|
|
80
|
+
apps:
|
|
81
|
+
- $include: ${fileName}`)
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
async function verifyGithubOrg(org) {
|
|
85
|
+
let response;
|
|
86
|
+
try {
|
|
87
|
+
response = await fetch(
|
|
88
|
+
`https://api.github.com/orgs/${encodeURIComponent(org)}`
|
|
89
|
+
);
|
|
90
|
+
} catch (e) {
|
|
91
|
+
console.log(
|
|
92
|
+
chalk__default.default.yellow(
|
|
93
|
+
"Warning: Unable to verify existence of GitHub organization. ",
|
|
94
|
+
e
|
|
95
|
+
)
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
if (response?.status === 404) {
|
|
99
|
+
const questions = [
|
|
100
|
+
{
|
|
101
|
+
type: "confirm",
|
|
102
|
+
name: "shouldCreateOrg",
|
|
103
|
+
message: `GitHub organization ${chalk__default.default.cyan(
|
|
104
|
+
org
|
|
105
|
+
)} does not exist. Would you like to create a new Organization instead?`
|
|
106
|
+
}
|
|
107
|
+
];
|
|
108
|
+
const answers = await inquirer__default.default.prompt(questions);
|
|
109
|
+
if (!answers.shouldCreateOrg) {
|
|
110
|
+
console.log(
|
|
111
|
+
chalk__default.default.yellow("GitHub organization must exist to create GitHub app")
|
|
112
|
+
);
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
openBrowser__default.default("https://github.com/account/organizations/new");
|
|
116
|
+
console.log(
|
|
117
|
+
chalk__default.default.yellow(
|
|
118
|
+
"Please re-run this command when you have created your new organization"
|
|
119
|
+
)
|
|
120
|
+
);
|
|
121
|
+
process.exit(0);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
exports.default = index;
|
|
126
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../../../src/commands/create-github-app/index.ts"],"sourcesContent":["/*\n * Copyright 2020 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 fs from 'fs-extra';\nimport chalk from 'chalk';\nimport { stringify as stringifyYaml } from 'yaml';\nimport inquirer, { Question, Answers } from 'inquirer';\nimport { targetPaths } from '@backstage/cli-common';\nimport { cli } from 'cleye';\n\nimport { GithubCreateAppServer } from './GithubCreateAppServer';\nimport openBrowser from 'react-dev-utils/openBrowser';\nimport type { CliCommandContext } from '@backstage/cli-node';\n\n// This is an experimental command that at this point does not support GitHub Enterprise\n// due to lacking support for creating apps from manifests.\n// https://docs.github.com/en/free-pro-team@latest/developers/apps/creating-a-github-app-from-a-manifest\nexport default async ({ args, info }: CliCommandContext) => {\n const { _: positionals } = cli(\n {\n help: { ...info, usage: `${info.usage} <github-org>` },\n booleanFlagNegation: true,\n parameters: ['<github-org>'],\n },\n undefined,\n args,\n );\n\n const org = positionals[0];\n\n const answers: Answers = await inquirer.prompt({\n name: 'appType',\n type: 'checkbox',\n message:\n 'Select permissions [required] (these can be changed later but then require approvals in all installations)',\n choices: [\n {\n name: 'Read access to content (required by Software Catalog to ingest data from repositories)',\n value: 'read',\n checked: true,\n },\n {\n name: 'Read access to members (required by Software Catalog to ingest GitHub teams)',\n value: 'members',\n checked: true,\n },\n {\n name: 'Read and Write to content and actions (required by Software Templates to create new repositories)',\n value: 'write',\n },\n ],\n });\n\n if (answers.appType.length === 0) {\n console.log(chalk.red('You must select at least one permission'));\n process.exit(1);\n }\n\n await verifyGithubOrg(org);\n const { slug, name, ...config } = await GithubCreateAppServer.run({\n org,\n permissions: answers.appType,\n });\n\n const fileName = `github-app-${slug}-credentials.yaml`;\n const content = `# Name: ${name}\\n${stringifyYaml(config)}`;\n await fs.writeFile(targetPaths.resolveRoot(fileName), content);\n console.log(`GitHub App configuration written to ${chalk.cyan(fileName)}`);\n console.log(\n chalk.yellow(\n 'This file contains sensitive credentials, it should not be committed to version control and handled with care!',\n ),\n );\n console.log(\n \"Here's an example on how to update the integrations section in app-config.yaml\",\n );\n console.log(\n chalk.green(`\nintegrations:\n github:\n - host: github.com\n apps:\n - $include: ${fileName}`),\n );\n};\n\nasync function verifyGithubOrg(org: string): Promise<void> {\n let response;\n\n try {\n response = await fetch(\n `https://api.github.com/orgs/${encodeURIComponent(org)}`,\n );\n } catch (e) {\n console.log(\n chalk.yellow(\n 'Warning: Unable to verify existence of GitHub organization. ',\n e,\n ),\n );\n }\n\n if (response?.status === 404) {\n const questions: Question[] = [\n {\n type: 'confirm',\n name: 'shouldCreateOrg',\n message: `GitHub organization ${chalk.cyan(\n org,\n )} does not exist. Would you like to create a new Organization instead?`,\n },\n ];\n\n const answers = await inquirer.prompt(questions);\n\n if (!answers.shouldCreateOrg) {\n console.log(\n chalk.yellow('GitHub organization must exist to create GitHub app'),\n );\n process.exit(1);\n }\n\n openBrowser('https://github.com/account/organizations/new');\n\n console.log(\n chalk.yellow(\n 'Please re-run this command when you have created your new organization',\n ),\n );\n\n process.exit(0);\n }\n}\n"],"names":["cli","inquirer","chalk","GithubCreateAppServer","stringifyYaml","fs","targetPaths","openBrowser"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var cliNode = require('@backstage/cli-node');
|
|
6
|
+
var _package = require('./package.json.cjs.js');
|
|
7
|
+
|
|
8
|
+
var index = cliNode.createCliModule({
|
|
9
|
+
packageJson: _package.default,
|
|
10
|
+
init: async (reg) => {
|
|
11
|
+
reg.addCommand({
|
|
12
|
+
path: ["create-github-app"],
|
|
13
|
+
description: "Create new GitHub App in your organization.",
|
|
14
|
+
execute: { loader: () => import('./commands/create-github-app/index.cjs.js') }
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
exports.default = index;
|
|
20
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/index.ts"],"sourcesContent":["/*\n * Copyright 2025 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 */\nimport { createCliModule } from '@backstage/cli-node';\nimport packageJson from '../package.json';\n\nexport default createCliModule({\n packageJson,\n init: async reg => {\n reg.addCommand({\n path: ['create-github-app'],\n description: 'Create new GitHub App in your organization.',\n execute: { loader: () => import('./commands/create-github-app') },\n });\n },\n});\n"],"names":["createCliModule","packageJson"],"mappings":";;;;;;;AAkBA,YAAeA,uBAAA,CAAgB;AAAA,eAC7BC,gBAAA;AAAA,EACA,IAAA,EAAM,OAAM,GAAA,KAAO;AACjB,IAAA,GAAA,CAAI,UAAA,CAAW;AAAA,MACb,IAAA,EAAM,CAAC,mBAAmB,CAAA;AAAA,MAC1B,WAAA,EAAa,6CAAA;AAAA,MACb,SAAS,EAAE,MAAA,EAAQ,MAAM,OAAO,2CAA8B,CAAA;AAAE,KACjE,CAAA;AAAA,EACH;AACF,CAAC,CAAA;;;;"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var name = "@backstage/cli-module-github";
|
|
6
|
+
var version = "0.0.0-nightly-20260317031259";
|
|
7
|
+
var description = "CLI module for Backstage CLI";
|
|
8
|
+
var backstage = {
|
|
9
|
+
role: "cli-module"
|
|
10
|
+
};
|
|
11
|
+
var publishConfig = {
|
|
12
|
+
access: "public",
|
|
13
|
+
main: "dist/index.cjs.js",
|
|
14
|
+
types: "dist/index.d.ts"
|
|
15
|
+
};
|
|
16
|
+
var homepage = "https://backstage.io";
|
|
17
|
+
var repository = {
|
|
18
|
+
type: "git",
|
|
19
|
+
url: "https://github.com/backstage/backstage",
|
|
20
|
+
directory: "packages/cli-module-github"
|
|
21
|
+
};
|
|
22
|
+
var license = "Apache-2.0";
|
|
23
|
+
var main = "src/index.ts";
|
|
24
|
+
var types = "src/index.ts";
|
|
25
|
+
var files = [
|
|
26
|
+
"dist",
|
|
27
|
+
"bin"
|
|
28
|
+
];
|
|
29
|
+
var scripts = {
|
|
30
|
+
build: "backstage-cli package build",
|
|
31
|
+
clean: "backstage-cli package clean",
|
|
32
|
+
lint: "backstage-cli package lint",
|
|
33
|
+
prepack: "backstage-cli package prepack",
|
|
34
|
+
postpack: "backstage-cli package postpack",
|
|
35
|
+
test: "backstage-cli package test"
|
|
36
|
+
};
|
|
37
|
+
var dependencies = {
|
|
38
|
+
"@backstage/cli-common": "workspace:*",
|
|
39
|
+
"@backstage/cli-node": "workspace:*",
|
|
40
|
+
"@octokit/request": "^8.0.0",
|
|
41
|
+
chalk: "^4.0.0",
|
|
42
|
+
cleye: "^2.3.0",
|
|
43
|
+
express: "^4.22.0",
|
|
44
|
+
"fs-extra": "^11.2.0",
|
|
45
|
+
inquirer: "^8.2.0",
|
|
46
|
+
"react-dev-utils": "^12.0.0-next.60",
|
|
47
|
+
yaml: "^2.0.0"
|
|
48
|
+
};
|
|
49
|
+
var devDependencies = {
|
|
50
|
+
"@backstage/cli": "workspace:*",
|
|
51
|
+
"@types/express": "^4.17.6",
|
|
52
|
+
"@types/fs-extra": "^11.0.0"
|
|
53
|
+
};
|
|
54
|
+
var bin = "bin/backstage-cli-module-github";
|
|
55
|
+
var packageJson = {
|
|
56
|
+
name: name,
|
|
57
|
+
version: version,
|
|
58
|
+
description: description,
|
|
59
|
+
backstage: backstage,
|
|
60
|
+
publishConfig: publishConfig,
|
|
61
|
+
homepage: homepage,
|
|
62
|
+
repository: repository,
|
|
63
|
+
license: license,
|
|
64
|
+
main: main,
|
|
65
|
+
types: types,
|
|
66
|
+
files: files,
|
|
67
|
+
scripts: scripts,
|
|
68
|
+
dependencies: dependencies,
|
|
69
|
+
devDependencies: devDependencies,
|
|
70
|
+
bin: bin
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
exports.backstage = backstage;
|
|
74
|
+
exports.bin = bin;
|
|
75
|
+
exports.default = packageJson;
|
|
76
|
+
exports.dependencies = dependencies;
|
|
77
|
+
exports.description = description;
|
|
78
|
+
exports.devDependencies = devDependencies;
|
|
79
|
+
exports.files = files;
|
|
80
|
+
exports.homepage = homepage;
|
|
81
|
+
exports.license = license;
|
|
82
|
+
exports.main = main;
|
|
83
|
+
exports.name = name;
|
|
84
|
+
exports.publishConfig = publishConfig;
|
|
85
|
+
exports.repository = repository;
|
|
86
|
+
exports.scripts = scripts;
|
|
87
|
+
exports.types = types;
|
|
88
|
+
exports.version = version;
|
|
89
|
+
//# sourceMappingURL=package.json.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package.json.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@backstage/cli-module-github",
|
|
3
|
+
"version": "0.0.0-nightly-20260317031259",
|
|
4
|
+
"description": "CLI module for Backstage CLI",
|
|
5
|
+
"backstage": {
|
|
6
|
+
"role": "cli-module"
|
|
7
|
+
},
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public",
|
|
10
|
+
"main": "dist/index.cjs.js",
|
|
11
|
+
"types": "dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://backstage.io",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/backstage/backstage",
|
|
17
|
+
"directory": "packages/cli-module-github"
|
|
18
|
+
},
|
|
19
|
+
"license": "Apache-2.0",
|
|
20
|
+
"main": "dist/index.cjs.js",
|
|
21
|
+
"types": "dist/index.d.ts",
|
|
22
|
+
"files": [
|
|
23
|
+
"dist",
|
|
24
|
+
"bin"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "backstage-cli package build",
|
|
28
|
+
"clean": "backstage-cli package clean",
|
|
29
|
+
"lint": "backstage-cli package lint",
|
|
30
|
+
"prepack": "backstage-cli package prepack",
|
|
31
|
+
"postpack": "backstage-cli package postpack",
|
|
32
|
+
"test": "backstage-cli package test"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@backstage/cli-common": "0.0.0-nightly-20260317031259",
|
|
36
|
+
"@backstage/cli-node": "0.0.0-nightly-20260317031259",
|
|
37
|
+
"@octokit/request": "^8.0.0",
|
|
38
|
+
"chalk": "^4.0.0",
|
|
39
|
+
"cleye": "^2.3.0",
|
|
40
|
+
"express": "^4.22.0",
|
|
41
|
+
"fs-extra": "^11.2.0",
|
|
42
|
+
"inquirer": "^8.2.0",
|
|
43
|
+
"react-dev-utils": "^12.0.0-next.60",
|
|
44
|
+
"yaml": "^2.0.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@backstage/cli": "0.0.0-nightly-20260317031259",
|
|
48
|
+
"@types/express": "^4.17.6",
|
|
49
|
+
"@types/fs-extra": "^11.0.0"
|
|
50
|
+
},
|
|
51
|
+
"bin": "bin/backstage-cli-module-github",
|
|
52
|
+
"typesVersions": {
|
|
53
|
+
"*": {
|
|
54
|
+
"package.json": [
|
|
55
|
+
"package.json"
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|