repo-branch 0.0.7 → 0.0.8
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/dist/index.js +91 -113
- package/package.json +1 -2
package/dist/index.js
CHANGED
|
@@ -1,134 +1,95 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
-
if (k2 === undefined) k2 = k;
|
|
5
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
-
}
|
|
9
|
-
Object.defineProperty(o, k2, desc);
|
|
10
|
-
}) : (function(o, m, k, k2) {
|
|
11
|
-
if (k2 === undefined) k2 = k;
|
|
12
|
-
o[k2] = m[k];
|
|
13
|
-
}));
|
|
14
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
-
}) : function(o, v) {
|
|
17
|
-
o["default"] = v;
|
|
18
|
-
});
|
|
19
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
-
var ownKeys = function(o) {
|
|
21
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
-
var ar = [];
|
|
23
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
-
return ar;
|
|
25
|
-
};
|
|
26
|
-
return ownKeys(o);
|
|
27
|
-
};
|
|
28
|
-
return function (mod) {
|
|
29
|
-
if (mod && mod.__esModule) return mod;
|
|
30
|
-
var result = {};
|
|
31
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
-
__setModuleDefault(result, mod);
|
|
33
|
-
return result;
|
|
34
|
-
};
|
|
35
|
-
})();
|
|
36
3
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
5
|
};
|
|
39
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
7
|
const commander_1 = require("commander");
|
|
41
|
-
const rest_1 = require("@octokit/rest");
|
|
42
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
43
9
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
44
10
|
const listr_1 = __importDefault(require("listr"));
|
|
45
11
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
46
|
-
const
|
|
47
|
-
const
|
|
12
|
+
const util_1 = require("util");
|
|
13
|
+
const exec = (0, util_1.promisify)(require("child_process").exec);
|
|
48
14
|
// Load environment variables from .env file
|
|
49
15
|
dotenv_1.default.config({ quiet: true });
|
|
50
16
|
const program = new commander_1.Command();
|
|
51
17
|
// Configuration - load from environment variables
|
|
52
18
|
const GITHUB_ORG = process.env.BRANCH_SYNC_GITHUB_ORG || "";
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const envPath = path.resolve(process.cwd(), ".env");
|
|
59
|
-
return fs.existsSync(envPath);
|
|
60
|
-
}
|
|
61
|
-
// Function to validate environment variables
|
|
62
|
-
function validateEnv() {
|
|
63
|
-
if (!OWNER) {
|
|
64
|
-
console.error(chalk_1.default.red("❌ Neither BRANCH_SYNC_GITHUB_ORG nor BRANCH_SYNC_GITHUB_OWNER found in environment variables"));
|
|
65
|
-
console.error(chalk_1.default.yellow("Please set either BRANCH_SYNC_GITHUB_ORG or BRANCH_SYNC_GITHUB_OWNER in your .env file or as environment variable"));
|
|
66
|
-
return false;
|
|
19
|
+
// Get current GitHub user (from gh auth status)
|
|
20
|
+
const getCurrentUser = async () => {
|
|
21
|
+
try {
|
|
22
|
+
const { stdout } = await exec("gh api user --jq .login");
|
|
23
|
+
return stdout.trim();
|
|
67
24
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
25
|
+
catch (error) {
|
|
26
|
+
throw new Error("Failed to get GitHub user. Please run 'gh auth login'");
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
// Function to validate environment and get owner
|
|
30
|
+
const validateAndGetOwner = async () => {
|
|
31
|
+
if (GITHUB_ORG) {
|
|
32
|
+
return GITHUB_ORG;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const currentUser = await getCurrentUser();
|
|
36
|
+
return currentUser;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
console.error(chalk_1.default.red("❌ Unable to determine GitHub owner"));
|
|
40
|
+
console.error(chalk_1.default.yellow("Please either:"));
|
|
41
|
+
console.error(chalk_1.default.yellow("1. Set BRANCH_SYNC_GITHUB_ORG in your .env file"));
|
|
42
|
+
console.error(chalk_1.default.yellow("2. Run 'gh auth login' to authenticate with GitHub CLI"));
|
|
43
|
+
throw error;
|
|
72
44
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
console.error(chalk_1.default.yellow("BRANCH_SYNC_GITHUB_TOKEN=your_token_here"));
|
|
80
|
-
console.error(chalk_1.default.yellow("BRANCH_SYNC_GITHUB_OWNER=your_username"));
|
|
45
|
+
};
|
|
46
|
+
// Check if GitHub CLI is installed
|
|
47
|
+
const checkGitHubCLI = async () => {
|
|
48
|
+
try {
|
|
49
|
+
await exec("gh --version");
|
|
50
|
+
return true;
|
|
81
51
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
52
|
+
catch (error) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const getRepositories = async (owner) => {
|
|
86
57
|
try {
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
sort: "full_name",
|
|
93
|
-
})
|
|
94
|
-
: await octokit.paginate(octokit.rest.repos.listForAuthenticatedUser, {
|
|
95
|
-
username: OWNER,
|
|
96
|
-
per_page: 100,
|
|
97
|
-
sort: "full_name",
|
|
98
|
-
});
|
|
99
|
-
return repos.map((repo) => ({
|
|
58
|
+
const command = `gh repo list ${owner} --limit 1000 --json name,defaultBranchRef,nameWithOwner`;
|
|
59
|
+
const { stdout } = await exec(command);
|
|
60
|
+
const repos = JSON.parse(stdout);
|
|
61
|
+
return repos
|
|
62
|
+
.map((repo) => ({
|
|
100
63
|
name: repo.name,
|
|
101
|
-
defaultBranch: repo.
|
|
102
|
-
full_name: repo.
|
|
103
|
-
}))
|
|
64
|
+
defaultBranch: repo.defaultBranchRef?.name || "main",
|
|
65
|
+
full_name: repo.nameWithOwner,
|
|
66
|
+
}))
|
|
67
|
+
.sort((a, b) => a.full_name.localeCompare(b.full_name));
|
|
104
68
|
}
|
|
105
69
|
catch (error) {
|
|
106
70
|
console.error(chalk_1.default.red("Failed to fetch repositories:"), error);
|
|
107
71
|
throw error;
|
|
108
72
|
}
|
|
109
|
-
}
|
|
110
|
-
async
|
|
73
|
+
};
|
|
74
|
+
const createBranch = async (owner, repoName, branchName) => {
|
|
111
75
|
try {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
ref: `refs/heads/${branchName}`,
|
|
121
|
-
sha: refData.object.sha,
|
|
122
|
-
});
|
|
76
|
+
// Get default branch
|
|
77
|
+
const { stdout: defaultBranchStdout } = await exec(`gh repo view ${owner}/${repoName} --json defaultBranchRef --jq .defaultBranchRef.name`);
|
|
78
|
+
const defaultBranch = defaultBranchStdout.trim() || "main";
|
|
79
|
+
// Get SHA of default branch
|
|
80
|
+
const { stdout: shaStdout } = await exec(`gh api repos/${owner}/${repoName}/git/refs/heads/${defaultBranch} --jq .object.sha`);
|
|
81
|
+
const sha = shaStdout.trim();
|
|
82
|
+
// Create new branch
|
|
83
|
+
await exec(`gh api repos/${owner}/${repoName}/git/refs -f ref=refs/heads/${branchName} -f sha=${sha}`);
|
|
123
84
|
}
|
|
124
85
|
catch (error) {
|
|
125
|
-
if (error.
|
|
86
|
+
if (error.stderr && error.stderr.includes("Reference already exists")) {
|
|
126
87
|
throw new Error(`Branch already exists`);
|
|
127
88
|
}
|
|
128
89
|
throw error;
|
|
129
90
|
}
|
|
130
|
-
}
|
|
131
|
-
async
|
|
91
|
+
};
|
|
92
|
+
const selectRepositories = async (repos) => {
|
|
132
93
|
const answers = await inquirer_1.default.prompt([
|
|
133
94
|
{
|
|
134
95
|
type: "checkbox",
|
|
@@ -142,11 +103,13 @@ async function selectRepositories(repos) {
|
|
|
142
103
|
},
|
|
143
104
|
]);
|
|
144
105
|
return answers.selectedRepos;
|
|
145
|
-
}
|
|
146
|
-
async
|
|
106
|
+
};
|
|
107
|
+
const run = async (branchName, repoNames) => {
|
|
147
108
|
try {
|
|
148
|
-
|
|
149
|
-
const
|
|
109
|
+
// Get owner (org or current user)
|
|
110
|
+
const owner = await validateAndGetOwner();
|
|
111
|
+
console.log(chalk_1.default.blue(`🔍 Fetching repositories for ${owner}...`));
|
|
112
|
+
const allRepos = await getRepositories(owner);
|
|
150
113
|
let selectedRepos;
|
|
151
114
|
if (repoNames && repoNames.length > 0) {
|
|
152
115
|
selectedRepos = allRepos.filter((repo) => repoNames.includes(repo.name));
|
|
@@ -168,7 +131,7 @@ async function run(branchName, repoNames) {
|
|
|
168
131
|
title: `Creating branch in ${chalk_1.default.cyan(repo.name)}`,
|
|
169
132
|
task: async () => {
|
|
170
133
|
try {
|
|
171
|
-
await createBranch(repo.name, branchName);
|
|
134
|
+
await createBranch(owner, repo.name, branchName);
|
|
172
135
|
}
|
|
173
136
|
catch (error) {
|
|
174
137
|
if (error.message.includes("already exists")) {
|
|
@@ -189,13 +152,28 @@ async function run(branchName, repoNames) {
|
|
|
189
152
|
console.error(chalk_1.default.red("Error:"), error);
|
|
190
153
|
process.exit(1);
|
|
191
154
|
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
program
|
|
155
|
+
};
|
|
156
|
+
// Main execution wrapper to avoid top-level await
|
|
157
|
+
(async () => {
|
|
158
|
+
// Check if GitHub CLI is available
|
|
159
|
+
if (!(await checkGitHubCLI())) {
|
|
160
|
+
console.error(chalk_1.default.red("❌ GitHub CLI not found"));
|
|
161
|
+
console.error(chalk_1.default.yellow("Please install GitHub CLI: https://cli.github.com/"));
|
|
162
|
+
process.exit(1);
|
|
163
|
+
}
|
|
164
|
+
program
|
|
165
|
+
.name("repo-branch")
|
|
166
|
+
.description("Create a branch across multiple GitHub repositories")
|
|
167
|
+
.argument("<branch-name>", "name of the branch to create")
|
|
168
|
+
.argument("[repositories...]", "repositories to create branch in")
|
|
169
|
+
.helpOption("-h, --help", "Display help for command")
|
|
170
|
+
.addHelpText("after", `
|
|
171
|
+
Examples:
|
|
172
|
+
$ repo-branch feature/new-ui
|
|
173
|
+
$ repo-branch feature/new-ui repo1 repo2
|
|
174
|
+
`)
|
|
175
|
+
.action((branchName, repositories) => {
|
|
176
|
+
run(branchName, repositories);
|
|
177
|
+
});
|
|
178
|
+
program.parse();
|
|
179
|
+
})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "repo-branch",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "Create branches across multiple GitHub repositories simultaneously",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -30,7 +30,6 @@
|
|
|
30
30
|
"start": "node dist/index.js"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@octokit/rest": "^22.0.1",
|
|
34
33
|
"chalk": "^5.6.2",
|
|
35
34
|
"commander": "^14.0.2",
|
|
36
35
|
"dotenv": "^17.2.3",
|