Skip to content

Commit f62a2f7

Browse files
Refactor GitHub Actions workflow to follow best practices and fix critical issues
- Fixed version format handling (package.json contains "v1.2.0", Windows binaries have .exe extension) - Added comprehensive error handling and validation throughout the workflow - Implemented dependency caching to improve build performance - Enhanced binary verification with detailed logging and file size reporting - Added path-based filtering to avoid unnecessary builds on documentation changes - Improved release notes with better formatting and comprehensive metadata - Added proper input validation and sanitization for security - Created separate validation workflow for PR testing and quality assurance - Updated README with detailed build instructions and comprehensive binary information - Fixed DRY violations by centralizing version extraction - Simplified binary verification logic following KISS principles - Enhanced maintainability with better error messages and structured validation Co-authored-by: Explosion-Scratch <61319150+Explosion-Scratch@users.noreply.github.com>
1 parent 46f5e80 commit f62a2f7

3 files changed

Lines changed: 238 additions & 45 deletions

File tree

Lines changed: 110 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,29 @@
11
name: Build and Release
22

3+
# Only trigger on pushes to main branch that modify code files
4+
# Manual workflow dispatch is also supported for testing
35
on:
46
push:
57
branches: [ main ]
8+
paths-ignore:
9+
- '**.md'
10+
- 'docs/**'
611
workflow_dispatch:
712

13+
env:
14+
# Cache key version - increment to invalidate caches
15+
CACHE_VERSION: v1
16+
817
jobs:
918
build:
1019
runs-on: ubuntu-latest
1120

1221
permissions:
13-
contents: write
22+
contents: write # Required for creating releases and uploading assets
23+
24+
outputs:
25+
version: ${{ steps.version.outputs.version }}
26+
tag: ${{ steps.tag.outputs.tag }}
1427

1528
steps:
1629
- name: Checkout code
@@ -21,68 +34,127 @@ jobs:
2134
with:
2235
bun-version: latest
2336

37+
- name: Cache dependencies
38+
uses: actions/cache@v4
39+
with:
40+
path: ~/.bun/install/cache
41+
key: bun-${{ env.CACHE_VERSION }}-${{ hashFiles('**/bun.lockb', '**/package.json') }}
42+
restore-keys: |
43+
bun-${{ env.CACHE_VERSION }}-
44+
2445
- name: Install dependencies
25-
run: bun install
46+
run: bun install --frozen-lockfile
2647

27-
- name: Make build script executable
28-
run: chmod +x build.sh
48+
- name: Extract version
49+
id: version
50+
run: |
51+
VERSION=$(cat package.json | jq -r '.version')
52+
if [[ -z "$VERSION" || "$VERSION" == "null" ]]; then
53+
echo "❌ Failed to extract version from package.json"
54+
exit 1
55+
fi
56+
echo "version=$VERSION" >> $GITHUB_OUTPUT
57+
echo "✅ Extracted version: $VERSION"
2958
59+
- name: Validate build script
60+
run: |
61+
if [[ ! -x "build.sh" ]]; then
62+
echo "❌ build.sh is not executable"
63+
exit 1
64+
fi
65+
3066
- name: Build binaries
31-
run: ./build.sh
32-
33-
- name: List build artifacts
34-
run: ls -la build/
35-
36-
- name: Verify all binaries were created
3767
run: |
38-
VERSION=$(cat package.json | jq -r '.version')
39-
EXPECTED_FILES=(
40-
"justinstall-$VERSION-linux-x64"
41-
"justinstall-$VERSION-linux-arm64"
42-
"justinstall-$VERSION-windows-x64"
43-
"justinstall-$VERSION-darwin-x64"
44-
"justinstall-$VERSION-darwin-arm64"
68+
echo "🔨 Building binaries for version ${{ steps.version.outputs.version }}"
69+
./build.sh
70+
71+
- name: Verify build artifacts
72+
run: |
73+
VERSION="${{ steps.version.outputs.version }}"
74+
BUILD_DIR="build"
75+
76+
# Expected binaries based on current build script behavior
77+
declare -A EXPECTED_BINARIES=(
78+
["linux-x64"]="justinstall-$VERSION-linux-x64"
79+
["linux-arm64"]="justinstall-$VERSION-linux-arm64"
80+
["windows-x64"]="justinstall-$VERSION-windows-x64.exe"
81+
["darwin-x64"]="justinstall-$VERSION-darwin-x64"
82+
["darwin-arm64"]="justinstall-$VERSION-darwin-arm64"
4583
)
4684
47-
for file in "${EXPECTED_FILES[@]}"; do
48-
if [[ ! -f "build/$file" ]]; then
49-
echo "❌ Missing binary: build/$file"
50-
exit 1
85+
echo "📋 Verifying build artifacts..."
86+
ALL_FOUND=true
87+
88+
for platform in "${!EXPECTED_BINARIES[@]}"; do
89+
binary="${EXPECTED_BINARIES[$platform]}"
90+
if [[ -f "$BUILD_DIR/$binary" ]]; then
91+
size=$(stat -f%z "$BUILD_DIR/$binary" 2>/dev/null || stat -c%s "$BUILD_DIR/$binary" 2>/dev/null)
92+
echo "✅ $platform: $binary (${size} bytes)"
5193
else
52-
echo "✅ Found binary: build/$file"
94+
echo "❌ Missing $platform binary: $binary"
95+
ALL_FOUND=false
5396
fi
5497
done
98+
99+
if [[ "$ALL_FOUND" == "false" ]]; then
100+
echo "❌ Build verification failed - some binaries are missing"
101+
echo "📁 Contents of build directory:"
102+
ls -la "$BUILD_DIR/" || echo "Build directory not found"
103+
exit 1
104+
fi
105+
106+
echo "✅ All expected binaries verified successfully"
55107
56108
- name: Generate release tag
57109
id: tag
58110
run: |
59-
VERSION=$(cat package.json | jq -r '.version')
60-
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
111+
VERSION="${{ steps.version.outputs.version }}"
112+
TIMESTAMP=$(date -u +%Y%m%d-%H%M%S)
61113
TAG="$VERSION-$TIMESTAMP"
114+
115+
# Validate tag format
116+
if [[ ! "$TAG" =~ ^[a-zA-Z0-9v][a-zA-Z0-9v._-]*$ ]]; then
117+
echo "❌ Invalid tag format: $TAG"
118+
exit 1
119+
fi
120+
62121
echo "tag=$TAG" >> $GITHUB_OUTPUT
63-
echo "version=$VERSION" >> $GITHUB_OUTPUT
122+
echo "✅ Generated release tag: $TAG"
64123
65124
- name: Create Pre-Release
66-
uses: softprops/action-gh-release@v1
125+
uses: softprops/action-gh-release@v2
67126
with:
68127
tag_name: ${{ steps.tag.outputs.tag }}
69128
name: "Pre-release ${{ steps.tag.outputs.tag }}"
70129
body: |
71-
Automated pre-release build from commit ${{ github.sha }}
130+
🤖 **Automated pre-release build**
131+
132+
**Version:** `${{ steps.version.outputs.version }}`
133+
**Commit:** [`${{ github.sha }}`](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }})
134+
**Build:** [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
135+
**Built:** ${{ steps.tag.outputs.tag }}
136+
137+
## 📦 Available Binaries
138+
139+
| Platform | Binary | Architecture |
140+
|----------|--------|--------------|
141+
| Linux | `justinstall-${{ steps.version.outputs.version }}-linux-x64` | x86_64 |
142+
| Linux | `justinstall-${{ steps.version.outputs.version }}-linux-arm64` | ARM64 |
143+
| Windows | `justinstall-${{ steps.version.outputs.version }}-windows-x64.exe` | x86_64 |
144+
| macOS | `justinstall-${{ steps.version.outputs.version }}-darwin-x64` | x86_64 |
145+
| macOS | `justinstall-${{ steps.version.outputs.version }}-darwin-arm64` | ARM64 (Apple Silicon) |
146+
147+
## 📥 Installation
148+
149+
Download the appropriate binary for your platform and add it to your PATH.
72150
73-
**Version:** ${{ steps.tag.outputs.version }}
74-
**Built on:** ${{ github.run_id }}
75-
**Commit:** ${{ github.sha }}
151+
---
76152
77-
## Binaries
78-
- `justinstall-${{ steps.tag.outputs.version }}-linux-x64` - Linux x64
79-
- `justinstall-${{ steps.tag.outputs.version }}-linux-arm64` - Linux ARM64
80-
- `justinstall-${{ steps.tag.outputs.version }}-windows-x64` - Windows x64
81-
- `justinstall-${{ steps.tag.outputs.version }}-darwin-x64` - macOS x64
82-
- `justinstall-${{ steps.tag.outputs.version }}-darwin-arm64` - macOS ARM64 (Apple Silicon)
83-
files: |
84-
build/*
153+
> This is an automated pre-release. For stable releases, see the main releases.
154+
files: build/*
85155
prerelease: true
86156
draft: false
157+
fail_on_unmatched_files: true
158+
generate_release_notes: false
87159
env:
88160
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/validate.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: Validate
2+
3+
# Run on PRs and pushes to validate the codebase
4+
on:
5+
push:
6+
branches: [ main ]
7+
pull_request:
8+
branches: [ main ]
9+
10+
jobs:
11+
validate:
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
18+
- name: Setup Bun
19+
uses: oven-sh/setup-bun@v1
20+
with:
21+
bun-version: latest
22+
23+
- name: Install dependencies
24+
run: bun install --frozen-lockfile
25+
26+
- name: Validate package.json
27+
run: |
28+
VERSION=$(cat package.json | jq -r '.version')
29+
if [[ -z "$VERSION" || "$VERSION" == "null" ]]; then
30+
echo "❌ Invalid or missing version in package.json"
31+
exit 1
32+
fi
33+
echo "✅ Version: $VERSION"
34+
35+
- name: Check build script
36+
run: |
37+
if [[ ! -x "build.sh" ]]; then
38+
echo "❌ build.sh is not executable"
39+
exit 1
40+
fi
41+
echo "✅ build.sh is executable"
42+
43+
- name: Test build process
44+
run: |
45+
echo "🔨 Testing build process..."
46+
timeout 300 ./build.sh || {
47+
echo "❌ Build failed or timed out"
48+
exit 1
49+
}
50+
51+
# Quick verification that some binaries were created
52+
if [[ ! -d "build" ]] || [[ -z "$(ls -A build/)" ]]; then
53+
echo "❌ No build artifacts created"
54+
exit 1
55+
fi
56+
57+
echo "✅ Build test completed successfully"
58+
echo "📦 Created artifacts:"
59+
ls -la build/

README.md

Lines changed: 69 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,35 @@ https://github.com/Explosion-Scratch/justinstall/assets/61319150/4a05e6e0-065a-4
1111
Grab the binary from the github releases (ironically you can use this tool to install itself)
1212

1313
### Automated Builds
14-
This project uses GitHub Actions to automatically build binaries for all supported platforms on every push to the main branch. Pre-releases are created with binaries for:
15-
- Linux x64
16-
- Linux ARM64
17-
- Windows x64
18-
- macOS x64
19-
- macOS ARM64 (Apple Silicon)
2014

21-
You can find the latest pre-releases in the [releases page](https://github.com/Explosion-Scratch/justinstall/releases).
15+
This project uses GitHub Actions to automatically build cross-platform binaries whenever code changes are pushed to the main branch. The build system creates pre-releases with binaries for all supported platforms:
16+
17+
| Platform | Architecture | Binary Name |
18+
|----------|--------------|-------------|
19+
| Linux | x86_64 | `justinstall-{version}-linux-x64` |
20+
| Linux | ARM64 | `justinstall-{version}-linux-arm64` |
21+
| Windows | x86_64 | `justinstall-{version}-windows-x64.exe` |
22+
| macOS | x86_64 | `justinstall-{version}-darwin-x64` |
23+
| macOS | ARM64 (Apple Silicon) | `justinstall-{version}-darwin-arm64` |
24+
25+
#### Getting Pre-built Binaries
26+
27+
1. Visit the [releases page](https://github.com/Explosion-Scratch/justinstall/releases)
28+
2. Look for the latest pre-release (marked with "Pre-release" tag)
29+
3. Download the appropriate binary for your platform
30+
4. Make the binary executable: `chmod +x justinstall-*` (Unix/macOS)
31+
5. Add it to your PATH or run directly
32+
33+
#### Build Process
34+
35+
The automated build process:
36+
- Triggers only on code changes (ignoring documentation updates)
37+
- Uses Bun's native compilation for optimal performance
38+
- Verifies all binaries are created successfully before releasing
39+
- Creates timestamped pre-releases to avoid version conflicts
40+
- Includes comprehensive build metadata and download instructions
41+
42+
For development builds or custom compilation, see the [Building](#building) section below.
2243

2344
## Features
2445

@@ -57,6 +78,47 @@ justinstall <github-url|file-url|local-file>
5778

5879
## Contributing
5980

81+
## Building
82+
83+
To build the project locally:
84+
85+
### Prerequisites
86+
87+
- [Bun](https://bun.sh/) runtime (latest version)
88+
- Unix-like environment (Linux, macOS, or WSL on Windows)
89+
90+
### Build Steps
91+
92+
1. Clone the repository:
93+
```bash
94+
git clone https://github.com/Explosion-Scratch/justinstall.git
95+
cd justinstall
96+
```
97+
98+
2. Install dependencies:
99+
```bash
100+
bun install
101+
```
102+
103+
3. Build all platform binaries:
104+
```bash
105+
./build.sh
106+
```
107+
108+
This creates optimized binaries in the `build/` directory for all supported platforms. The build script uses Bun's native compilation feature for maximum performance and minimal dependencies.
109+
110+
### Development
111+
112+
For development and testing:
113+
```bash
114+
# Run directly with Bun
115+
bun run index.js --help
116+
117+
# Or make executable and run
118+
chmod +x index.js
119+
./index.js --help
120+
```
121+
60122
Contributions are welcome! Please feel free to submit a Pull Request.
61123

62124
## Acknowledgements

0 commit comments

Comments
 (0)