repo-branch 0.0.3

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.
Files changed (2) hide show
  1. package/dist/index.js +191 -0
  2. package/package.json +49 -0
package/dist/index.js ADDED
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env node
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ const commander_1 = require("commander");
41
+ const rest_1 = require("@octokit/rest");
42
+ const chalk_1 = __importDefault(require("chalk"));
43
+ const inquirer_1 = __importDefault(require("inquirer"));
44
+ const listr_1 = __importDefault(require("listr"));
45
+ const dotenv_1 = __importDefault(require("dotenv"));
46
+ const path = __importStar(require("path"));
47
+ const fs = __importStar(require("fs"));
48
+ // Load environment variables from .env file
49
+ dotenv_1.default.config();
50
+ const program = new commander_1.Command();
51
+ // Configuration - load from environment variables
52
+ const GITHUB_OWNER = process.env.BRANCH_SYNC_GITHUB_OWNER || "";
53
+ const GITHUB_TOKEN = process.env.BRANCH_SYNC_GITHUB_TOKEN || "";
54
+ // Function to check if .env file exists
55
+ function checkEnvFile() {
56
+ const envPath = path.resolve(process.cwd(), ".env");
57
+ return fs.existsSync(envPath);
58
+ }
59
+ // Function to validate environment variables
60
+ function validateEnv() {
61
+ if (!GITHUB_OWNER) {
62
+ console.error(chalk_1.default.red("āŒ BRANCH_SYNC_GITHUB_OWNER not found in environment variables"));
63
+ console.error(chalk_1.default.yellow("Please set BRANCH_SYNC_GITHUB_OWNER in your .env file or as environment variable"));
64
+ return false;
65
+ }
66
+ if (!GITHUB_TOKEN) {
67
+ console.error(chalk_1.default.red("āŒ BRANCH_SYNC_GITHUB_TOKEN not found in environment variables"));
68
+ console.error(chalk_1.default.yellow("Please set BRANCH_SYNC_GITHUB_TOKEN in your .env file or as environment variable"));
69
+ return false;
70
+ }
71
+ return true;
72
+ }
73
+ if (!validateEnv()) {
74
+ if (!checkEnvFile()) {
75
+ console.error(chalk_1.default.red("\nNo .env file found!"));
76
+ console.error(chalk_1.default.yellow("Create a .env file with:"));
77
+ console.error(chalk_1.default.yellow("BRANCH_SYNC_GITHUB_TOKEN=your_token_here"));
78
+ console.error(chalk_1.default.yellow("BRANCH_SYNC_GITHUB_OWNER=your_username"));
79
+ }
80
+ process.exit(1);
81
+ }
82
+ const octokit = new rest_1.Octokit({ auth: GITHUB_TOKEN });
83
+ async function getRepositories() {
84
+ try {
85
+ const repos = await octokit.paginate(octokit.rest.repos.listForUser, {
86
+ username: GITHUB_OWNER,
87
+ per_page: 100,
88
+ sort: "updated",
89
+ });
90
+ return repos.map((repo) => ({
91
+ name: repo.name,
92
+ defaultBranch: repo.default_branch ?? "main",
93
+ }));
94
+ }
95
+ catch (error) {
96
+ console.error(chalk_1.default.red("Failed to fetch repositories:"), error);
97
+ throw error;
98
+ }
99
+ }
100
+ async function createBranch(repoName, branchName) {
101
+ try {
102
+ const { data: refData } = await octokit.rest.git.getRef({
103
+ owner: GITHUB_OWNER,
104
+ repo: repoName,
105
+ ref: `heads/${(await octokit.rest.repos.get({ owner: GITHUB_OWNER, repo: repoName })).data.default_branch}`,
106
+ });
107
+ await octokit.rest.git.createRef({
108
+ owner: GITHUB_OWNER,
109
+ repo: repoName,
110
+ ref: `refs/heads/${branchName}`,
111
+ sha: refData.object.sha,
112
+ });
113
+ }
114
+ catch (error) {
115
+ if (error.status === 422) {
116
+ throw new Error(`Branch already exists`);
117
+ }
118
+ throw error;
119
+ }
120
+ }
121
+ async function selectRepositories(repos) {
122
+ const answers = await inquirer_1.default.prompt([
123
+ {
124
+ type: "checkbox",
125
+ name: "selectedRepos",
126
+ message: "Select repositories:",
127
+ choices: repos.map((repo) => ({
128
+ name: `${repo.name} (${repo.defaultBranch})`,
129
+ value: repo,
130
+ })),
131
+ pageSize: 15,
132
+ },
133
+ ]);
134
+ return answers.selectedRepos;
135
+ }
136
+ async function run(branchName, repoNames) {
137
+ try {
138
+ console.log(chalk_1.default.blue("šŸ” Fetching repositories..."));
139
+ const allRepos = await getRepositories();
140
+ let selectedRepos;
141
+ if (repoNames && repoNames.length > 0) {
142
+ selectedRepos = allRepos.filter((repo) => repoNames.includes(repo.name));
143
+ const notFound = repoNames.filter((name) => !allRepos.some((repo) => repo.name === name));
144
+ if (notFound.length > 0) {
145
+ console.warn(chalk_1.default.yellow(`āš ļø Repositories not found: ${notFound.join(", ")}`));
146
+ }
147
+ }
148
+ else {
149
+ selectedRepos = await selectRepositories(allRepos);
150
+ }
151
+ if (selectedRepos.length === 0) {
152
+ console.log(chalk_1.default.yellow("No repositories selected"));
153
+ return;
154
+ }
155
+ console.log(chalk_1.default.blue(`\nšŸš€ Creating branch '${branchName}' in ${selectedRepos.length} repositories...\n`));
156
+ // Create tasks for Listr
157
+ const tasks = new listr_1.default(selectedRepos.map((repo) => ({
158
+ title: `Creating branch in ${chalk_1.default.cyan(repo.name)}`,
159
+ task: async () => {
160
+ try {
161
+ await createBranch(repo.name, branchName);
162
+ }
163
+ catch (error) {
164
+ if (error.message.includes("already exists")) {
165
+ throw new Error(chalk_1.default.yellow("Branch already exists"));
166
+ }
167
+ throw error;
168
+ }
169
+ },
170
+ })));
171
+ await tasks.run();
172
+ console.log(chalk_1.default.green("\n✨ All done!"));
173
+ }
174
+ catch (error) {
175
+ if (error.message === "Prompt was cancelled") {
176
+ console.log(chalk_1.default.yellow("\nOperation cancelled"));
177
+ process.exit(0);
178
+ }
179
+ console.error(chalk_1.default.red("Error:"), error);
180
+ process.exit(1);
181
+ }
182
+ }
183
+ program
184
+ .name("repo-branch")
185
+ .description("Create a branch across multiple GitHub repositories")
186
+ .argument("<branch-name>", "name of the branch to create")
187
+ .argument("[repositories...]", "repositories to create branch in")
188
+ .action((branchName, repositories) => {
189
+ run(branchName, repositories);
190
+ });
191
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "repo-branch",
3
+ "version": "0.0.3",
4
+ "description": "Create branches across multiple GitHub repositories simultaneously",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "repo-branch": "dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist/**/*"
11
+ ],
12
+ "keywords": [
13
+ "github",
14
+ "branch",
15
+ "repository",
16
+ "sync",
17
+ "multiple",
18
+ "cli"
19
+ ],
20
+ "author": "Your Name",
21
+ "license": "MIT",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/sergiubutnarasu/repo-branch.git"
25
+ },
26
+ "scripts": {
27
+ "build": "tsc",
28
+ "prepublishOnly": "npm run build",
29
+ "dev": "ts-node src/index.ts",
30
+ "start": "node dist/index.js"
31
+ },
32
+ "dependencies": {
33
+ "@octokit/rest": "^22.0.1",
34
+ "chalk": "^5.6.2",
35
+ "commander": "^14.0.2",
36
+ "dotenv": "^17.2.3",
37
+ "inquirer": "^13.1.0",
38
+ "listr": "^0.14.3"
39
+ },
40
+ "devDependencies": {
41
+ "@types/listr": "^0.14.10",
42
+ "@types/node": "^25.0.3",
43
+ "ts-node": "^10.9.2",
44
+ "typescript": "^5.9.3"
45
+ },
46
+ "engines": {
47
+ "node": ">=22"
48
+ }
49
+ }