notion-github 0.1.6 → 0.1.7
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/README.md +62 -1
- package/dist/cli.js +111 -38
- package/package.json +5 -4
package/README.md
CHANGED
@@ -1 +1,62 @@
|
|
1
|
-
|
1
|
+
# notion-github CLI
|
2
|
+
|
3
|
+
GitHub PR 생성을 자동화하는 CLI 도구입니다.
|
4
|
+
|
5
|
+
## 설치
|
6
|
+
|
7
|
+
```bash
|
8
|
+
npm install -g notion-github
|
9
|
+
```
|
10
|
+
|
11
|
+
## 사전 준비사항
|
12
|
+
|
13
|
+
1. GitHub Personal Access Token 발급
|
14
|
+
|
15
|
+
- [GitHub Token 발급 가이드](./docs/GITHUB_TOKEN.md)를 참고하여 토큰을 발급받으세요.
|
16
|
+
- 발급받은 토큰을 환경변수로 설정:
|
17
|
+
```bash
|
18
|
+
export GITHUB_TOKEN=your_token_here
|
19
|
+
```
|
20
|
+
|
21
|
+
2. Repository 접근 권한 확인
|
22
|
+
- PR을 생성하려는 repository에 대한 write 권한이 있어야 합니다.
|
23
|
+
|
24
|
+
## 사용법
|
25
|
+
|
26
|
+
### PR 생성
|
27
|
+
|
28
|
+
```bash
|
29
|
+
pr-cli create --title "PR 제목" --description "PR 설명" --head feature/branch --repo owner/repo
|
30
|
+
```
|
31
|
+
|
32
|
+
### 필수 옵션
|
33
|
+
|
34
|
+
- `--title`: PR 제목
|
35
|
+
- `--head`: PR을 생성할 소스 브랜치
|
36
|
+
- `--repo`: 대상 레포지토리 (예: owner/repo)
|
37
|
+
|
38
|
+
### 선택 옵션
|
39
|
+
|
40
|
+
- `--description`: PR 설명
|
41
|
+
- `--base`: PR을 병합할 대상 브랜치 (기본값: main)
|
42
|
+
|
43
|
+
### 도움말
|
44
|
+
|
45
|
+
```bash
|
46
|
+
pr-cli --help # 전체 도움말
|
47
|
+
pr-cli create --help # create 명령어 도움말
|
48
|
+
```
|
49
|
+
|
50
|
+
## 라이선스
|
51
|
+
|
52
|
+
MIT
|
53
|
+
|
54
|
+
## 설정
|
55
|
+
|
56
|
+
1. 홈 디렉토리에 `notion_github_config.json` 파일을 생성합니다:
|
57
|
+
|
58
|
+
```json
|
59
|
+
{
|
60
|
+
"githubToken": "your_github_token_here"
|
61
|
+
}
|
62
|
+
```
|
package/dist/cli.js
CHANGED
@@ -927,9 +927,9 @@ var require_command = __commonJS({
|
|
927
927
|
"use strict";
|
928
928
|
var EventEmitter = require("events").EventEmitter;
|
929
929
|
var childProcess = require("child_process");
|
930
|
-
var
|
931
|
-
var
|
932
|
-
var
|
930
|
+
var path2 = require("path");
|
931
|
+
var fs2 = require("fs");
|
932
|
+
var process2 = require("process");
|
933
933
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
934
934
|
var { CommanderError: CommanderError2 } = require_error();
|
935
935
|
var { Help: Help2 } = require_help();
|
@@ -975,10 +975,10 @@ var require_command = __commonJS({
|
|
975
975
|
this._showHelpAfterError = false;
|
976
976
|
this._showSuggestionAfterError = true;
|
977
977
|
this._outputConfiguration = {
|
978
|
-
writeOut: (str) =>
|
979
|
-
writeErr: (str) =>
|
980
|
-
getOutHelpWidth: () =>
|
981
|
-
getErrHelpWidth: () =>
|
978
|
+
writeOut: (str) => process2.stdout.write(str),
|
979
|
+
writeErr: (str) => process2.stderr.write(str),
|
980
|
+
getOutHelpWidth: () => process2.stdout.isTTY ? process2.stdout.columns : void 0,
|
981
|
+
getErrHelpWidth: () => process2.stderr.isTTY ? process2.stderr.columns : void 0,
|
982
982
|
outputError: (str, write) => write(str)
|
983
983
|
};
|
984
984
|
this._hidden = false;
|
@@ -1335,7 +1335,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
1335
1335
|
if (this._exitCallback) {
|
1336
1336
|
this._exitCallback(new CommanderError2(exitCode, code, message));
|
1337
1337
|
}
|
1338
|
-
|
1338
|
+
process2.exit(exitCode);
|
1339
1339
|
}
|
1340
1340
|
/**
|
1341
1341
|
* Register callback `fn` for the command.
|
@@ -1666,8 +1666,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
1666
1666
|
}
|
1667
1667
|
parseOptions = parseOptions || {};
|
1668
1668
|
if (argv === void 0) {
|
1669
|
-
argv =
|
1670
|
-
if (
|
1669
|
+
argv = process2.argv;
|
1670
|
+
if (process2.versions && process2.versions.electron) {
|
1671
1671
|
parseOptions.from = "electron";
|
1672
1672
|
}
|
1673
1673
|
}
|
@@ -1680,7 +1680,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
1680
1680
|
userArgs = argv.slice(2);
|
1681
1681
|
break;
|
1682
1682
|
case "electron":
|
1683
|
-
if (
|
1683
|
+
if (process2.defaultApp) {
|
1684
1684
|
this._scriptPath = argv[1];
|
1685
1685
|
userArgs = argv.slice(2);
|
1686
1686
|
} else {
|
@@ -1751,10 +1751,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
1751
1751
|
let launchWithNode = false;
|
1752
1752
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
1753
1753
|
function findFile(baseDir, baseName) {
|
1754
|
-
const localBin =
|
1755
|
-
if (
|
1756
|
-
if (sourceExt.includes(
|
1757
|
-
const foundExt = sourceExt.find((ext) =>
|
1754
|
+
const localBin = path2.resolve(baseDir, baseName);
|
1755
|
+
if (fs2.existsSync(localBin)) return localBin;
|
1756
|
+
if (sourceExt.includes(path2.extname(baseName))) return void 0;
|
1757
|
+
const foundExt = sourceExt.find((ext) => fs2.existsSync(`${localBin}${ext}`));
|
1758
1758
|
if (foundExt) return `${localBin}${foundExt}`;
|
1759
1759
|
return void 0;
|
1760
1760
|
}
|
@@ -1765,41 +1765,41 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
1765
1765
|
if (this._scriptPath) {
|
1766
1766
|
let resolvedScriptPath;
|
1767
1767
|
try {
|
1768
|
-
resolvedScriptPath =
|
1768
|
+
resolvedScriptPath = fs2.realpathSync(this._scriptPath);
|
1769
1769
|
} catch (err) {
|
1770
1770
|
resolvedScriptPath = this._scriptPath;
|
1771
1771
|
}
|
1772
|
-
executableDir =
|
1772
|
+
executableDir = path2.resolve(path2.dirname(resolvedScriptPath), executableDir);
|
1773
1773
|
}
|
1774
1774
|
if (executableDir) {
|
1775
1775
|
let localFile = findFile(executableDir, executableFile);
|
1776
1776
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
1777
|
-
const legacyName =
|
1777
|
+
const legacyName = path2.basename(this._scriptPath, path2.extname(this._scriptPath));
|
1778
1778
|
if (legacyName !== this._name) {
|
1779
1779
|
localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
|
1780
1780
|
}
|
1781
1781
|
}
|
1782
1782
|
executableFile = localFile || executableFile;
|
1783
1783
|
}
|
1784
|
-
launchWithNode = sourceExt.includes(
|
1784
|
+
launchWithNode = sourceExt.includes(path2.extname(executableFile));
|
1785
1785
|
let proc;
|
1786
|
-
if (
|
1786
|
+
if (process2.platform !== "win32") {
|
1787
1787
|
if (launchWithNode) {
|
1788
1788
|
args.unshift(executableFile);
|
1789
|
-
args = incrementNodeInspectorPort(
|
1790
|
-
proc = childProcess.spawn(
|
1789
|
+
args = incrementNodeInspectorPort(process2.execArgv).concat(args);
|
1790
|
+
proc = childProcess.spawn(process2.argv[0], args, { stdio: "inherit" });
|
1791
1791
|
} else {
|
1792
1792
|
proc = childProcess.spawn(executableFile, args, { stdio: "inherit" });
|
1793
1793
|
}
|
1794
1794
|
} else {
|
1795
1795
|
args.unshift(executableFile);
|
1796
|
-
args = incrementNodeInspectorPort(
|
1797
|
-
proc = childProcess.spawn(
|
1796
|
+
args = incrementNodeInspectorPort(process2.execArgv).concat(args);
|
1797
|
+
proc = childProcess.spawn(process2.execPath, args, { stdio: "inherit" });
|
1798
1798
|
}
|
1799
1799
|
if (!proc.killed) {
|
1800
1800
|
const signals = ["SIGUSR1", "SIGUSR2", "SIGTERM", "SIGINT", "SIGHUP"];
|
1801
1801
|
signals.forEach((signal) => {
|
1802
|
-
|
1802
|
+
process2.on(signal, () => {
|
1803
1803
|
if (proc.killed === false && proc.exitCode === null) {
|
1804
1804
|
proc.kill(signal);
|
1805
1805
|
}
|
@@ -1808,10 +1808,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
1808
1808
|
}
|
1809
1809
|
const exitCallback = this._exitCallback;
|
1810
1810
|
if (!exitCallback) {
|
1811
|
-
proc.on("close",
|
1811
|
+
proc.on("close", process2.exit.bind(process2));
|
1812
1812
|
} else {
|
1813
1813
|
proc.on("close", () => {
|
1814
|
-
exitCallback(new CommanderError2(
|
1814
|
+
exitCallback(new CommanderError2(process2.exitCode || 0, "commander.executeSubCommandAsync", "(close)"));
|
1815
1815
|
});
|
1816
1816
|
}
|
1817
1817
|
proc.on("error", (err) => {
|
@@ -1826,7 +1826,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
1826
1826
|
throw new Error(`'${executableFile}' not executable`);
|
1827
1827
|
}
|
1828
1828
|
if (!exitCallback) {
|
1829
|
-
|
1829
|
+
process2.exit(1);
|
1830
1830
|
} else {
|
1831
1831
|
const wrappedError = new CommanderError2(1, "commander.executeSubCommandAsync", "(error)");
|
1832
1832
|
wrappedError.nestedError = err;
|
@@ -2292,11 +2292,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
2292
2292
|
*/
|
2293
2293
|
_parseOptionsEnv() {
|
2294
2294
|
this.options.forEach((option) => {
|
2295
|
-
if (option.envVar && option.envVar in
|
2295
|
+
if (option.envVar && option.envVar in process2.env) {
|
2296
2296
|
const optionKey = option.attributeName();
|
2297
2297
|
if (this.getOptionValue(optionKey) === void 0 || ["default", "config", "env"].includes(this.getOptionValueSource(optionKey))) {
|
2298
2298
|
if (option.required || option.optional) {
|
2299
|
-
this.emit(`optionEnv:${option.name()}`,
|
2299
|
+
this.emit(`optionEnv:${option.name()}`, process2.env[option.envVar]);
|
2300
2300
|
} else {
|
2301
2301
|
this.emit(`optionEnv:${option.name()}`);
|
2302
2302
|
}
|
@@ -2564,7 +2564,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
2564
2564
|
* @return {Command}
|
2565
2565
|
*/
|
2566
2566
|
nameFromFilename(filename) {
|
2567
|
-
this._name =
|
2567
|
+
this._name = path2.basename(filename, path2.extname(filename));
|
2568
2568
|
return this;
|
2569
2569
|
}
|
2570
2570
|
/**
|
@@ -2578,9 +2578,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
2578
2578
|
* @param {string} [path]
|
2579
2579
|
* @return {string|null|Command}
|
2580
2580
|
*/
|
2581
|
-
executableDir(
|
2582
|
-
if (
|
2583
|
-
this._executableDir =
|
2581
|
+
executableDir(path3) {
|
2582
|
+
if (path3 === void 0) return this._executableDir;
|
2583
|
+
this._executableDir = path3;
|
2584
2584
|
return this;
|
2585
2585
|
}
|
2586
2586
|
/**
|
@@ -2672,7 +2672,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
2672
2672
|
*/
|
2673
2673
|
help(contextOptions) {
|
2674
2674
|
this.outputHelp(contextOptions);
|
2675
|
-
let exitCode =
|
2675
|
+
let exitCode = process2.exitCode || 0;
|
2676
2676
|
if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
|
2677
2677
|
exitCode = 1;
|
2678
2678
|
}
|
@@ -2789,21 +2789,94 @@ var {
|
|
2789
2789
|
} = import_index.default;
|
2790
2790
|
|
2791
2791
|
// package.json
|
2792
|
-
var version = "0.1.
|
2792
|
+
var version = "0.1.7";
|
2793
|
+
|
2794
|
+
// src/commands/create/action.ts
|
2795
|
+
var import_rest = require("@octokit/rest");
|
2796
|
+
|
2797
|
+
// src/utils/config.ts
|
2798
|
+
var import_fs = __toESM(require("fs"));
|
2799
|
+
var import_path = __toESM(require("path"));
|
2800
|
+
var import_os = __toESM(require("os"));
|
2801
|
+
var CONFIG_FILE = "notion_github_config.json";
|
2802
|
+
var CONFIG_PATH = import_path.default.join(import_os.default.homedir(), CONFIG_FILE);
|
2803
|
+
function readConfig() {
|
2804
|
+
try {
|
2805
|
+
if (!import_fs.default.existsSync(CONFIG_PATH)) {
|
2806
|
+
throw new Error(`Config file not found. Please create ${CONFIG_FILE} in your home directory.`);
|
2807
|
+
}
|
2808
|
+
const config = JSON.parse(import_fs.default.readFileSync(CONFIG_PATH, "utf8"));
|
2809
|
+
if (!config.githubToken) {
|
2810
|
+
throw new Error("GitHub token not found in config file.");
|
2811
|
+
}
|
2812
|
+
return config;
|
2813
|
+
} catch (error) {
|
2814
|
+
if (error instanceof Error) {
|
2815
|
+
throw new Error(`Failed to read config: ${error.message}`);
|
2816
|
+
}
|
2817
|
+
throw error;
|
2818
|
+
}
|
2819
|
+
}
|
2793
2820
|
|
2794
2821
|
// src/commands/create/action.ts
|
2795
2822
|
async function action(options) {
|
2796
|
-
|
2823
|
+
try {
|
2824
|
+
const config = readConfig();
|
2825
|
+
const octokit = new import_rest.Octokit({ auth: config.githubToken });
|
2826
|
+
const [owner, repo] = options.repo.split("/");
|
2827
|
+
if (!owner || !repo) {
|
2828
|
+
throw new Error("Invalid repository format. Use 'owner/repo' format.");
|
2829
|
+
}
|
2830
|
+
console.log("Creating PR...");
|
2831
|
+
const response = await octokit.pulls.create({
|
2832
|
+
owner,
|
2833
|
+
repo,
|
2834
|
+
title: options.title,
|
2835
|
+
head: options.head,
|
2836
|
+
base: options.base || "main",
|
2837
|
+
body: options.description
|
2838
|
+
});
|
2839
|
+
console.log(`PR created successfully: ${response.data.html_url}`);
|
2840
|
+
} catch (error) {
|
2841
|
+
if (error instanceof Error) {
|
2842
|
+
console.error("Failed to create PR:", error.message);
|
2843
|
+
} else {
|
2844
|
+
console.error("An unknown error occurred");
|
2845
|
+
}
|
2846
|
+
process.exit(1);
|
2847
|
+
}
|
2797
2848
|
}
|
2798
2849
|
|
2799
2850
|
// src/commands/create/index.ts
|
2800
2851
|
function createCommand2(program3) {
|
2801
|
-
program3.command("create").description("Create a new PR").requiredOption("--title <title>", "PR title").option("--description <description>", "PR description").option("--
|
2852
|
+
program3.command("create").description("Create a new PR").requiredOption("--title <title>", "PR title").requiredOption("--head <head>", "Head branch").requiredOption("--repo <repo>", "Repository (owner/repo)").option("--description <description>", "PR description").option("--base <base>", "Base branch", "main").action(action);
|
2853
|
+
}
|
2854
|
+
|
2855
|
+
// src/commands/debug/action.ts
|
2856
|
+
async function action2(options) {
|
2857
|
+
try {
|
2858
|
+
const config = readConfig();
|
2859
|
+
console.log("Current Configuration:");
|
2860
|
+
console.log(JSON.stringify(config, null, 2));
|
2861
|
+
} catch (error) {
|
2862
|
+
if (error instanceof Error) {
|
2863
|
+
console.error("Debug failed:", error.message);
|
2864
|
+
} else {
|
2865
|
+
console.error("An unknown error occurred");
|
2866
|
+
}
|
2867
|
+
process.exit(1);
|
2868
|
+
}
|
2869
|
+
}
|
2870
|
+
|
2871
|
+
// src/commands/debug/index.ts
|
2872
|
+
function debugCommand(program3) {
|
2873
|
+
program3.command("debug").description("Show debug information").option("--config", "Show configuration").action(action2);
|
2802
2874
|
}
|
2803
2875
|
|
2804
2876
|
// src/commands/index.ts
|
2805
2877
|
function registerCommands(program3) {
|
2806
2878
|
createCommand2(program3);
|
2879
|
+
debugCommand(program3);
|
2807
2880
|
}
|
2808
2881
|
|
2809
2882
|
// src/cli.ts
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "notion-github",
|
3
|
-
"version": "0.1.
|
3
|
+
"version": "0.1.7",
|
4
4
|
"description": "GitHub and Notion integration for PR automation",
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"module": "dist/index.mjs",
|
@@ -18,15 +18,16 @@
|
|
18
18
|
},
|
19
19
|
"license": "MIT",
|
20
20
|
"devDependencies": {
|
21
|
-
"@types/node": "^16.
|
21
|
+
"@types/node": "^16.18.124",
|
22
22
|
"tsup": "^8.0.0",
|
23
23
|
"typescript": "^5.0.0"
|
24
24
|
},
|
25
25
|
"dependencies": {
|
26
26
|
"@changesets/cli": "^2.27.11",
|
27
27
|
"@notionhq/client": "^2.0.0",
|
28
|
-
"@octokit/rest": "^19.0.
|
29
|
-
"commander": "^11.0.0"
|
28
|
+
"@octokit/rest": "^19.0.13",
|
29
|
+
"commander": "^11.0.0",
|
30
|
+
"dotenv": "^16.4.7"
|
30
31
|
},
|
31
32
|
"bin": {
|
32
33
|
"pr-cli": "dist/cli.js"
|