deadbranch 0.0.1 → 0.1.1

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 CHANGED
@@ -1,45 +1,56 @@
1
- # deadbranch
1
+ # deadbranch npm package
2
2
 
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
3
+ This is the npm distribution package for [deadbranch](https://github.com/armgabrielyan/deadbranch), a CLI tool to clean up stale git branches safely.
4
4
 
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
5
+ ## Installation
6
6
 
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
7
+ ```bash
8
+ npm install -g deadbranch
9
+ ```
8
10
 
9
- ## Purpose
11
+ Or run directly with npx:
10
12
 
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `deadbranch`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
13
+ ```bash
14
+ npx deadbranch list
15
+ ```
15
16
 
16
- ## What is OIDC Trusted Publishing?
17
+ ## What this package does
17
18
 
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
19
+ When you install this package, it automatically downloads the appropriate pre-built binary for your platform from GitHub Releases. Supported platforms:
19
20
 
20
- ## Setup Instructions
21
+ - macOS (Intel & Apple Silicon)
22
+ - Linux (x64 & ARM64)
23
+ - Windows (x64)
21
24
 
22
- To properly configure OIDC trusted publishing for this package:
25
+ ## Alternative installation methods
23
26
 
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
27
+ If npm installation fails, you can install deadbranch using other methods:
28
28
 
29
- ## DO NOT USE THIS PACKAGE
29
+ ### Shell installer (Linux/macOS)
30
+ ```bash
31
+ curl -sSf https://raw.githubusercontent.com/armgabrielyan/deadbranch/main/install.sh | sh
32
+ ```
30
33
 
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
34
+ ### Cargo (from source)
35
+ ```bash
36
+ cargo install deadbranch
37
+ ```
36
38
 
37
- ## More Information
39
+ ### Homebrew (macOS/Linux)
40
+ ```bash
41
+ brew install armgabrielyan/deadbranch/deadbranch
42
+ ```
38
43
 
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
44
+ ## Usage
42
45
 
43
- ---
46
+ ```bash
47
+ deadbranch list # List stale branches
48
+ deadbranch clean # Delete merged stale branches
49
+ deadbranch clean --dry-run # Preview what would be deleted
50
+ ```
44
51
 
45
- **Maintained for OIDC setup purposes only**
52
+ For more information, see the [full documentation](https://github.com/armgabrielyan/deadbranch).
53
+
54
+ ## License
55
+
56
+ MIT
package/bin/deadbranch ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Binary wrapper for deadbranch
5
+ * This script runs the actual binary with all passed arguments
6
+ */
7
+
8
+ const { spawn } = require('child_process');
9
+ const path = require('path');
10
+ const os = require('os');
11
+
12
+ const binaryExt = os.platform() === 'win32' ? '.exe' : '';
13
+ const binaryPath = path.join(__dirname, 'deadbranch' + binaryExt);
14
+
15
+ const child = spawn(binaryPath, process.argv.slice(2), {
16
+ stdio: 'inherit',
17
+ env: process.env,
18
+ });
19
+
20
+ child.on('exit', (code) => {
21
+ process.exit(code || 0);
22
+ });
package/package.json CHANGED
@@ -1,10 +1,40 @@
1
1
  {
2
2
  "name": "deadbranch",
3
- "version": "0.0.1",
4
- "description": "OIDC trusted publishing setup package for deadbranch",
3
+ "version": "0.1.1",
4
+ "description": "Clean up stale git branches safely",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/armgabrielyan/deadbranch.git"
8
+ },
9
+ "author": "Armen Gabrielyan",
10
+ "license": "MIT",
5
11
  "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
12
+ "git",
13
+ "cli",
14
+ "branches",
15
+ "cleanup",
16
+ "devtools"
17
+ ],
18
+ "bin": {
19
+ "deadbranch": "bin/deadbranch"
20
+ },
21
+ "scripts": {
22
+ "postinstall": "node scripts/install.js"
23
+ },
24
+ "files": [
25
+ "bin/",
26
+ "scripts/"
27
+ ],
28
+ "engines": {
29
+ "node": ">=14"
30
+ },
31
+ "os": [
32
+ "darwin",
33
+ "linux",
34
+ "win32"
35
+ ],
36
+ "cpu": [
37
+ "x64",
38
+ "arm64"
9
39
  ]
10
40
  }
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * npm postinstall script for deadbranch
5
+ * Downloads the appropriate pre-built binary for the current platform
6
+ */
7
+
8
+ const { execSync, spawn } = require('child_process');
9
+ const fs = require('fs');
10
+ const https = require('https');
11
+ const path = require('path');
12
+ const os = require('os');
13
+ const zlib = require('zlib');
14
+
15
+ const REPO = 'armgabrielyan/deadbranch';
16
+ const BINARY_NAME = 'deadbranch';
17
+ const VERSION = require('../package.json').version;
18
+
19
+ /**
20
+ * Get the target triple for the current platform
21
+ */
22
+ function getTarget() {
23
+ const platform = os.platform();
24
+ const arch = os.arch();
25
+
26
+ const targets = {
27
+ 'darwin-x64': 'x86_64-apple-darwin',
28
+ 'darwin-arm64': 'aarch64-apple-darwin',
29
+ 'linux-x64': 'x86_64-unknown-linux-gnu',
30
+ 'linux-arm64': 'aarch64-unknown-linux-gnu',
31
+ 'win32-x64': 'x86_64-pc-windows-msvc',
32
+ };
33
+
34
+ const key = `${platform}-${arch}`;
35
+ const target = targets[key];
36
+
37
+ if (!target) {
38
+ throw new Error(`Unsupported platform: ${key}`);
39
+ }
40
+
41
+ return target;
42
+ }
43
+
44
+ /**
45
+ * Get the archive extension for the current platform
46
+ */
47
+ function getArchiveExt() {
48
+ return os.platform() === 'win32' ? 'zip' : 'tar.gz';
49
+ }
50
+
51
+ /**
52
+ * Download a file from a URL
53
+ */
54
+ function download(url) {
55
+ return new Promise((resolve, reject) => {
56
+ const handleResponse = (response) => {
57
+ if (response.statusCode === 302 || response.statusCode === 301) {
58
+ // Follow redirect
59
+ https.get(response.headers.location, handleResponse).on('error', reject);
60
+ return;
61
+ }
62
+
63
+ if (response.statusCode !== 200) {
64
+ reject(new Error(`Failed to download: ${response.statusCode}`));
65
+ return;
66
+ }
67
+
68
+ const chunks = [];
69
+ response.on('data', (chunk) => chunks.push(chunk));
70
+ response.on('end', () => resolve(Buffer.concat(chunks)));
71
+ response.on('error', reject);
72
+ };
73
+
74
+ https.get(url, handleResponse).on('error', reject);
75
+ });
76
+ }
77
+
78
+ /**
79
+ * Extract tar.gz archive
80
+ */
81
+ function extractTarGz(buffer, destDir) {
82
+ const tarPath = path.join(os.tmpdir(), 'deadbranch.tar');
83
+
84
+ // Decompress gzip
85
+ const decompressed = zlib.gunzipSync(buffer);
86
+ fs.writeFileSync(tarPath, decompressed);
87
+
88
+ // Extract tar
89
+ execSync(`tar -xf "${tarPath}" -C "${destDir}"`, { stdio: 'inherit' });
90
+ fs.unlinkSync(tarPath);
91
+ }
92
+
93
+ /**
94
+ * Extract zip archive (Windows)
95
+ */
96
+ function extractZip(buffer, destDir) {
97
+ const zipPath = path.join(os.tmpdir(), 'deadbranch.zip');
98
+ fs.writeFileSync(zipPath, buffer);
99
+
100
+ // Use PowerShell to extract
101
+ execSync(`powershell -Command "Expand-Archive -Path '${zipPath}' -DestinationPath '${destDir}' -Force"`, { stdio: 'inherit' });
102
+ fs.unlinkSync(zipPath);
103
+ }
104
+
105
+ async function install() {
106
+ console.log('Installing deadbranch...');
107
+
108
+ try {
109
+ const target = getTarget();
110
+ const ext = getArchiveExt();
111
+ const archiveName = `deadbranch-${VERSION}-${target}.${ext}`;
112
+ const url = `https://github.com/${REPO}/releases/download/v${VERSION}/${archiveName}`;
113
+
114
+ console.log(`Downloading ${archiveName}...`);
115
+ const buffer = await download(url);
116
+
117
+ const binDir = path.join(__dirname, '..', 'bin');
118
+ if (!fs.existsSync(binDir)) {
119
+ fs.mkdirSync(binDir, { recursive: true });
120
+ }
121
+
122
+ // Create temp dir for extraction
123
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'deadbranch-'));
124
+
125
+ console.log('Extracting...');
126
+ if (ext === 'zip') {
127
+ extractZip(buffer, tmpDir);
128
+ } else {
129
+ extractTarGz(buffer, tmpDir);
130
+ }
131
+
132
+ // Copy binary to bin directory
133
+ const binaryExt = os.platform() === 'win32' ? '.exe' : '';
134
+ const srcBinary = path.join(tmpDir, BINARY_NAME + binaryExt);
135
+ const destBinary = path.join(binDir, BINARY_NAME + binaryExt);
136
+
137
+ fs.copyFileSync(srcBinary, destBinary);
138
+
139
+ // Make executable on Unix
140
+ if (os.platform() !== 'win32') {
141
+ fs.chmodSync(destBinary, 0o755);
142
+ }
143
+
144
+ // Cleanup temp dir
145
+ fs.rmSync(tmpDir, { recursive: true, force: true });
146
+
147
+ console.log('deadbranch installed successfully!');
148
+ } catch (error) {
149
+ console.error('Failed to install deadbranch:', error.message);
150
+ console.error('');
151
+ console.error('You can install from source instead:');
152
+ console.error(' cargo install deadbranch');
153
+ process.exit(1);
154
+ }
155
+ }
156
+
157
+ install();