Skip to content

Commit b4a2113

Browse files
authored
Merge pull request #15 from erdos-one/ci/setup-release-automation
2 parents a06810d + 766f168 commit b4a2113

File tree

7 files changed

+172
-31
lines changed

7 files changed

+172
-31
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Release Please
2+
3+
# This workflow runs on every push to main and:
4+
# 1. Analyzes commits since the last release using Conventional Commits
5+
# 2. Creates/updates a Release PR with version bump and changelog
6+
# 3. When the Release PR is merged, creates a tag and GitHub release
7+
# 4. The tag triggers the GoReleaser workflow (release.yml) to build binaries
8+
#
9+
# Required Secret: GH_PAT with permissions:
10+
# - Actions: Read-only
11+
# - Contents: Read and write
12+
# - Pull requests: Read and write
13+
14+
on:
15+
push:
16+
branches:
17+
- main
18+
19+
permissions:
20+
contents: write
21+
pull-requests: write
22+
23+
jobs:
24+
release-please:
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: googleapis/release-please-action@v4
28+
id: release
29+
with:
30+
token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }}

.github/workflows/release.yml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
name: Release
22

3+
# This workflow is triggered when release-please creates a tag.
4+
# It builds binaries with GoReleaser and updates the install script.
5+
36
on:
47
push:
58
tags:
@@ -12,11 +15,11 @@ jobs:
1215
goreleaser:
1316
runs-on: ubuntu-latest
1417
steps:
15-
- uses: actions/checkout@v3
18+
- uses: actions/checkout@v4
1619
with:
1720
fetch-depth: 0
1821
- run: git fetch --force --tags
19-
- uses: actions/setup-go@v3
22+
- uses: actions/setup-go@v5
2023
with:
2124
go-version: '>=1.19.5'
2225
cache: true
@@ -29,9 +32,10 @@ jobs:
2932
env:
3033
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3134
install-script:
35+
needs: goreleaser
3236
runs-on: ubuntu-latest
3337
steps:
34-
- uses: actions/checkout@v3
38+
- uses: actions/checkout@v4
3539
- name: Make install script
3640
run: bash scripts/make-install.sh
3741
- name: Commit install script
@@ -40,7 +44,7 @@ jobs:
4044
git config user.email github-action@github.com
4145
git add install.sh
4246
if ! git diff --staged --quiet; then
43-
git commit -m "$(git describe --tags --abbrev=0) install script update"
47+
git commit -m "chore: update install script for $(git describe --tags --abbrev=0) [skip ci]"
4448
echo "CHANGES_COMMITTED=true" >> $GITHUB_ENV
4549
else
4650
echo "No changes to commit"

.goreleaser.yaml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ checksum:
2525
snapshot:
2626
name_template: "{{ incpatch .Version }}-next"
2727
changelog:
28-
sort: asc
29-
filters:
30-
exclude:
31-
- '^docs:'
32-
- '^test:'
28+
disable: true
3329
sboms:
3430
- artifacts: archive

.release-please-manifest.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
".": "0.2.1"
3+
}

CLAUDE.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,27 @@ go run main.go [command] [flags]
3333
```
3434

3535
### Release Process
36-
The project uses GoReleaser for building releases. Tags trigger the release workflow:
36+
The project uses release-please for automated versioning and GoReleaser for building releases.
37+
38+
**Automated Process:**
39+
1. Push commits to main using Conventional Commits format:
40+
- `feat:` for new features (minor version bump)
41+
- `fix:` for bug fixes (patch version bump)
42+
- `feat!:` or `BREAKING CHANGE:` for breaking changes (major version bump)
43+
2. release-please automatically creates/updates a Release PR
44+
3. Review and merge the Release PR
45+
4. release-please creates a tag, triggering GoReleaser to build and publish
46+
47+
**Conventional Commit Examples:**
3748
```bash
38-
# Create a new release (triggers GitHub Actions)
49+
git commit -m "feat: add bucket encryption support"
50+
git commit -m "fix: resolve timeout issue in sync command"
51+
git commit -m "feat!: change configuration file format"
52+
```
53+
54+
**Manual release (not recommended):**
55+
```bash
56+
# Only use if automated process fails
3957
git tag v0.1.0
4058
git push origin v0.1.0
4159
```

release-please-config.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
3+
"release-type": "go",
4+
"packages": {
5+
".": {}
6+
},
7+
"changelog-sections": [
8+
{"type": "feat", "section": "Features"},
9+
{"type": "fix", "section": "Bug Fixes"},
10+
{"type": "perf", "section": "Performance Improvements"},
11+
{"type": "deps", "section": "Dependencies"},
12+
{"type": "revert", "section": "Reverts"},
13+
{"type": "docs", "section": "Documentation"},
14+
{"type": "style", "section": "Styling"},
15+
{"type": "chore", "section": "Miscellaneous", "hidden": true},
16+
{"type": "refactor", "section": "Code Refactoring", "hidden": true},
17+
{"type": "test", "section": "Tests", "hidden": true},
18+
{"type": "build", "section": "Build System", "hidden": true},
19+
{"type": "ci", "section": "Continuous Integration", "hidden": true}
20+
]
21+
}

scripts/make-install.sh

Lines changed: 89 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,97 @@
11
#!/bin/bash
2+
set -euo pipefail # Exit on error, undefined vars, pipe failures
3+
4+
# Get repository information with validation
25
REPO_USER=$(git config --get remote.origin.url | cut -d'/' -f4)
3-
REPO_NAME=$(basename `git rev-parse --show-toplevel`)
6+
REPO_NAME=$(basename "$(git rev-parse --show-toplevel)")
47
TAG_NAME=$(git describe --tags --abbrev=0)
58
BINARY_NAME="r2"
69

7-
cat > install.sh << EOF
10+
# Validate required variables
11+
if [ -z "$REPO_USER" ] || [ -z "$REPO_NAME" ] || [ -z "$TAG_NAME" ]; then
12+
echo "Error: Failed to determine repository information" >&2
13+
echo "REPO_USER: ${REPO_USER:-empty}" >&2
14+
echo "REPO_NAME: ${REPO_NAME:-empty}" >&2
15+
echo "TAG_NAME: ${TAG_NAME:-empty}" >&2
16+
exit 1
17+
fi
18+
19+
cat > install.sh << 'EOF'
820
#!/bin/sh
9-
OS=\`uname -s\`
10-
ARCH=\`uname -m\`
11-
12-
curl -fsSLo \$HOME/${BINARY_NAME}-\${OS}-\${ARCH}.tar.gz \\
13-
https://github.com/${REPO_USER}/${REPO_NAME}/releases/download/${TAG_NAME}/${BINARY_NAME}-\${OS}-\${ARCH}.tar.gz
14-
15-
mkdir -p \$HOME/${BINARY_NAME}-${TAG_NAME}
16-
tar -xzf \$HOME/${BINARY_NAME}-\${OS}-\${ARCH}.tar.gz -C \$HOME/${BINARY_NAME}-${TAG_NAME}
17-
chmod +x \$HOME/${BINARY_NAME}-${TAG_NAME}/${BINARY_NAME}
18-
19-
if [ "\$EUID" -eq 0 ]; then
20-
mv \$HOME/${BINARY_NAME}-${TAG_NAME}/${BINARY_NAME} /usr/bin/${BINARY_NAME}
21-
rm -r \$HOME/${BINARY_NAME}-${TAG_NAME}
21+
set -e # Exit on error
22+
23+
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
24+
ARCH=$(uname -m)
25+
26+
# Normalize architecture names to match GoReleaser output
27+
case "$ARCH" in
28+
x86_64|amd64) ARCH="x86_64" ;;
29+
i386|i686) ARCH="i386" ;;
30+
armv7l) ARCH="armv7" ;;
31+
aarch64) ARCH="arm64" ;;
32+
esac
33+
34+
# Normalize OS names to match GoReleaser output (title case)
35+
case "$OS" in
36+
linux) OS="Linux" ;;
37+
darwin) OS="Darwin" ;;
38+
*) echo "Unsupported OS: $OS" >&2; exit 1 ;;
39+
esac
40+
41+
EOF
42+
43+
# Insert dynamic values (use double quotes for variable expansion)
44+
cat >> install.sh << EOF
45+
BINARY_NAME="${BINARY_NAME}"
46+
TAG_NAME="${TAG_NAME}"
47+
REPO_USER="${REPO_USER}"
48+
REPO_NAME="${REPO_NAME}"
49+
50+
EOF
51+
52+
# Continue with static content (use single quotes to prevent expansion)
53+
cat >> install.sh << 'EOF'
54+
ARCHIVE="${BINARY_NAME}-${OS}-${ARCH}.tar.gz"
55+
DOWNLOAD_URL="https://github.com/${REPO_USER}/${REPO_NAME}/releases/download/${TAG_NAME}/${ARCHIVE}"
56+
INSTALL_DIR="$HOME/${BINARY_NAME}-${TAG_NAME}"
57+
58+
# Cleanup function
59+
cleanup() {
60+
rm -f "$HOME/$ARCHIVE"
61+
}
62+
trap cleanup EXIT
63+
64+
echo "Downloading ${BINARY_NAME} ${TAG_NAME} for ${OS}-${ARCH}..."
65+
curl -fsSL -o "$HOME/$ARCHIVE" "$DOWNLOAD_URL" || {
66+
echo "Error: Failed to download from $DOWNLOAD_URL" >&2
67+
exit 1
68+
}
69+
70+
echo "Extracting to ${INSTALL_DIR}..."
71+
mkdir -p "$INSTALL_DIR"
72+
tar -xzf "$HOME/$ARCHIVE" -C "$INSTALL_DIR" || {
73+
echo "Error: Failed to extract archive" >&2
74+
exit 1
75+
}
76+
77+
chmod +x "$INSTALL_DIR/$BINARY_NAME"
78+
79+
if [ "$(id -u)" -eq 0 ]; then
80+
echo "Installing to /usr/bin/${BINARY_NAME}..."
81+
mv "$INSTALL_DIR/$BINARY_NAME" "/usr/bin/$BINARY_NAME"
82+
rm -rf "$INSTALL_DIR"
83+
echo "Installation complete! Run '${BINARY_NAME} --version' to verify."
2284
else
23-
echo "Couldn't add ${BINARY_NAME} to /usr/bin because script is not running at admin"
24-
echo "Please run the following commands:"
25-
echo " mv \$HOME/${BINARY_NAME}-${TAG_NAME}/${BINARY_NAME}-\${OS}-\${ARCH} /usr/bin/${BINARY_NAME}"
26-
echo " rm -r \$HOME/${BINARY_NAME}-${TAG_NAME}"
85+
echo "Installation successful!"
86+
echo ""
87+
echo "Since you're not running as root, manual steps required:"
88+
echo " sudo mv \"$INSTALL_DIR/$BINARY_NAME\" \"/usr/bin/$BINARY_NAME\""
89+
echo " rm -rf \"$INSTALL_DIR\""
90+
echo ""
91+
echo "Or add to your PATH:"
92+
echo " export PATH=\"$INSTALL_DIR:\$PATH\""
2793
fi
28-
EOF
94+
EOF
95+
96+
chmod +x install.sh
97+
echo "Generated install.sh for ${TAG_NAME}"

0 commit comments

Comments
 (0)