Skip to content

Commit 5e3b605

Browse files
committed
Wip release automation
1 parent 5804c72 commit 5e3b605

File tree

7 files changed

+124
-15
lines changed

7 files changed

+124
-15
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@ yarn-error.log*
1515
*.njsproj
1616
*.sln
1717
*.sw?
18+
19+
# Releases
20+
*.tar.gz

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ npm run dev
9898

9999
## License
100100

101-
ISC
101+
MIT
102102

103103
## Contributing
104104

RELEASE_NOTES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Version 0.0.2
2+
Tarball: explainshell-cli-v0.0.2.tar.gz
3+
SHA256: 96296843b92fc94f13815464429dbe08009854f6b763965a2493f8f0af3f8ac0

explainshell-cli.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# explainshell-cli.rb
22
class ExplainshellCli < Formula
33
desc "Explain shell commands using explainshell.com"
4-
homepage "https://github.com/mjsarfatti/explainshell-cli" # Replace with your repo URL
5-
url "https://github.com/mjsarfatti/explainshell-cli/archive/v0.1.0.tar.gz" # URL to the release tarball
6-
sha256 "CHECKSUM_OF_THE_TARBALL" # Will be calculated after you create a release
7-
license "ISC" # Or your chosen license
4+
homepage "https://github.com/mjsarfatti/explainshell-cli"
5+
url "https://github.com/mjsarfatti/explainshell-cli/archive/v0.1.0.tar.gz"
6+
sha256 "CHECKSUM_OF_THE_TARBALL"
7+
license "MIT"
88

99
depends_on "node"
1010

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,12 @@
1414
"test": "tsx --test tests/main.test.ts",
1515
"prestart": "npm run build",
1616
"prepublishOnly": "npm run build",
17-
"release:patch": "npm version patch && npm run release:build",
18-
"release:minor": "npm version minor && npm run release:build",
19-
"release:major": "npm version major && npm run release:build",
20-
"release:build": "npm run build && npm run release:tarball && npm run release:sha",
21-
"release:tarball": "tar -czf explainshell-cli-v$(node -p 'require(\"./package.json\").version').tar.gz --exclude=node_modules --exclude=dist/.* --exclude=.git --exclude=tests .",
22-
"release:sha": "node -e \"const fs=require('fs'); const v=require('./package.json').version; const file='explainshell-cli-v'+v+'.tar.gz'; const hash=require('crypto').createHash('sha256').update(fs.readFileSync(file)).digest('hex'); console.log('SHA256: ' + hash); fs.appendFileSync('RELEASE_NOTES.md', '\\n\\nVersion ' + v + '\\nTarball: ' + file + '\\nSHA256: ' + hash + '\\n');\"",
23-
"release:info": "node -e \"const v=require('./package.json').version; const file='explainshell-cli-v'+v+'.tar.gz'; console.log('\\nRelease Info:'); console.log('Version:', v); console.log('Tarball:', file); console.log('\\nUpdate explainshell-cli.rb:'); console.log('url \\\"https://github.com/mjsarfatti/explainshell-cli/releases/download/v' + v + '/' + file + '\\\"'); const fs=require('fs'); if(fs.existsSync(file)){const hash=require('crypto').createHash('sha256').update(fs.readFileSync(file)).digest('hex'); console.log('sha256 \\\"' + hash + '\\\"');}\"",
17+
"version:patch": "npm version patch --no-git-tag-version",
18+
"version:minor": "npm version minor --no-git-tag-version",
19+
"version:major": "npm version major --no-git-tag-version",
20+
"release:patch": "npm run version:patch && node scripts/release.js",
21+
"release:minor": "npm run version:minor && node scripts/release.js",
22+
"release:major": "npm run version:major && node scripts/release.js",
2423
"release": "npm run release:patch"
2524
},
2625
"keywords": [
@@ -30,7 +29,7 @@
3029
"typescript"
3130
],
3231
"author": "Manuele J Sarfatti",
33-
"license": "ISC",
32+
"license": "MIT",
3433
"dependencies": {
3534
"axios": "^1.9.0",
3635
"chalk": "^5.4.1",

scripts/release.js

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#!/usr/bin/env node
2+
3+
const fs = require("fs");
4+
const { execSync } = require("child_process");
5+
const crypto = require("crypto");
6+
7+
function exec(command, options = {}) {
8+
console.log(`\n→ ${command}`);
9+
return execSync(command, { stdio: "inherit", ...options });
10+
}
11+
12+
function getOutput(command) {
13+
return execSync(command, { encoding: "utf-8" }).trim();
14+
}
15+
16+
async function release() {
17+
try {
18+
// Get current version
19+
const pkg = JSON.parse(fs.readFileSync("./package.json", "utf-8"));
20+
const version = pkg.version;
21+
const tarballName = `explainshell-cli-v${version}.tar.gz`;
22+
const githubRepo = "mjsarfatti/explainshell-cli";
23+
24+
console.log(`\n📦 Releasing version ${version}`);
25+
26+
// 1. Run tests
27+
console.log("\n1️⃣ Running tests...");
28+
exec("npm test");
29+
30+
// 2. Build
31+
console.log("\n2️⃣ Building...");
32+
exec("npm run build");
33+
34+
// 3. Create tarball
35+
console.log("\n3️⃣ Creating tarball...");
36+
exec(
37+
`tar -czf ${tarballName} --exclude=node_modules --exclude=.git --exclude=tests --exclude='*.tar.gz' --exclude='.DS_Store' .`
38+
);
39+
40+
// 4. Calculate SHA256
41+
console.log("\n4️⃣ Calculating SHA256...");
42+
const fileBuffer = fs.readFileSync(tarballName);
43+
const sha256 = crypto.createHash("sha256").update(fileBuffer).digest("hex");
44+
console.log(` SHA256: ${sha256}`);
45+
46+
// 5. Update Homebrew formula
47+
console.log("\n5️⃣ Updating Homebrew formula...");
48+
let formula = fs.readFileSync("explainshell-cli.rb", "utf-8");
49+
formula = formula.replace(
50+
/url\s+"[^"]+"/,
51+
`url "https://github.com/${githubRepo}/releases/download/v${version}/${tarballName}"`
52+
);
53+
formula = formula.replace(/sha256\s+"[^"]+"/, `sha256 "${sha256}"`);
54+
fs.writeFileSync("explainshell-cli.rb", formula);
55+
console.log(" ✓ Updated explainshell-cli.rb");
56+
57+
// 6. Commit changes
58+
console.log("\n6️⃣ Committing changes...");
59+
exec("git add package.json package-lock.json explainshell-cli.rb");
60+
exec(`git commit -m "Release v${version}"`);
61+
62+
// 7. Create git tag
63+
console.log("\n7️⃣ Creating git tag...");
64+
exec(`git tag -a v${version} -m "Release v${version}"`);
65+
66+
// 8. Push to GitHub
67+
console.log("\n8️⃣ Pushing to GitHub...");
68+
exec("git push origin main");
69+
exec("git push origin --tags");
70+
71+
// 9. Create GitHub release
72+
console.log("\n9️⃣ Creating GitHub release...");
73+
74+
// Check if gh CLI is available
75+
try {
76+
getOutput("which gh");
77+
exec(
78+
`gh release create v${version} ${tarballName} --title "v${version}" --notes "Release v${version}"`
79+
);
80+
console.log(" ✓ GitHub release created");
81+
} catch (error) {
82+
console.log(
83+
"\n⚠️ GitHub CLI (gh) not found. Please create the release manually:"
84+
);
85+
console.log(` 1. Go to https://github.com/${githubRepo}/releases/new`);
86+
console.log(` 2. Tag: v${version}`);
87+
console.log(` 3. Upload ${tarballName}`);
88+
console.log(` 4. Publish release`);
89+
console.log(
90+
"\nℹ️ For next time, you can install the GitHub CLI with `brew install gh`"
91+
);
92+
}
93+
94+
console.log("\n✅ Release complete!");
95+
console.log(`\nVersion: ${version}`);
96+
console.log(`Tarball: ${tarballName}`);
97+
console.log(`SHA256: ${sha256}`);
98+
} catch (error) {
99+
console.error("\n❌ Release failed:", error.message);
100+
process.exit(1);
101+
}
102+
}
103+
104+
release();

0 commit comments

Comments
 (0)