feat(release): add automated release workflow and install script
- Embed version info in binaries via ldflags - Create multi-platform builds, archives, and checksums - Add Gitea release creation and asset upload in CI - Introduce GoReleaser config for standardized builds - Add version command and install script for easy deployment - Update README with pre-built installation instructions
This commit is contained in:
parent
b8906e44c1
commit
b8482b6fb0
@ -25,15 +25,48 @@ jobs:
|
||||
|
||||
- name: Build for multiple platforms
|
||||
run: |
|
||||
GOOS=linux GOARCH=amd64 go build -ldflags "-s -w" -trimpath -o build/grokkit-linux-amd64 .
|
||||
GOOS=linux GOARCH=arm64 go build -ldflags "-s -w" -trimpath -o build/grokkit-linux-arm64 .
|
||||
GOOS=darwin GOARCH=amd64 go build -ldflags "-s -w" -trimpath -o build/grokkit-darwin-amd64 .
|
||||
GOOS=darwin GOARCH=arm64 go build -ldflags "-s -w" -trimpath -o build/grokkit-darwin-arm64 .
|
||||
GOOS=windows GOARCH=amd64 go build -ldflags "-s -w" -trimpath -o build/grokkit-windows-amd64.exe .
|
||||
|
||||
- name: Create Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
files: |
|
||||
build/grokkit-*
|
||||
generate_release_notes: true
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
COMMIT=$(git rev-parse --short HEAD)
|
||||
DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
mkdir -p build
|
||||
for plat in 'linux/amd64' 'linux/arm64' 'darwin/amd64' 'darwin/arm64' 'windows/amd64'; do
|
||||
IFS='/' read -r OS ARCH <<< "$plat"
|
||||
BIN="grokkit-${OS}-${ARCH}"
|
||||
if [ "$OS" = "windows" ]; then BIN="${BIN}.exe"; fi
|
||||
GOOS="$OS" GOARCH="$ARCH" go build -ldflags "-s -w -X 'gmgauthier.com/grokkit/internal/version.Version=${VERSION}' -X 'gmgauthier.com/grokkit/internal/version.Commit=${COMMIT}' -X 'gmgauthier.com/grokkit/internal/version.BuildDate=${DATE}' -trimpath" -o "build/${BIN}" .
|
||||
done
|
||||
- name: Prepare assets
|
||||
run: |
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
for bin in build/grokkit-* ; do
|
||||
if [ ! -f "$bin" ]; then continue; fi
|
||||
OSARCH=$(basename "$bin" | sed 's/grokkit-//' | sed 's/\.exe$//')
|
||||
tar czf "build/grokkit-${OSARCH}-${VERSION}.tar.gz" -C build "$(basename "$bin")"
|
||||
done
|
||||
sha256sum build/grokkit-*.tar.gz | tee build/checksums.txt
|
||||
cp scripts/grokkit-install.sh build/
|
||||
- name: Install dependencies
|
||||
run: apt update && apt install -y jq
|
||||
- name: Create Release & Upload Assets
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
run: |
|
||||
VERSION=${GITHUB_REF#refs/tags/}
|
||||
GITEA_API=https://repos.gmgauthier.com/api/v1
|
||||
# Create release
|
||||
curl -X POST "${GITEA_API}/repos/${GITHUB_REPOSITORY}/releases" \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"tag_name\": \"${VERSION}\",\"name\": \"Grokkit ${VERSION}\",\"body\": \"## Quick Install\\n\\n```bash\\ncurl -L https://repos.gmgauthier.com/gmgauthier/grokkit/releases/download/v${VERSION}/grokkit-install.sh | VERSION=${VERSION} bash\\n```\\n\\nAssets include platform binaries (tar.gz), checksums.txt. See CHANGELOG.md.\"}" > release.json
|
||||
RELEASE_ID=$(jq .id release.json)
|
||||
# Upload assets
|
||||
for asset in build/* ; do
|
||||
name=$(basename "$asset")
|
||||
mime="application/octet-stream"
|
||||
[[ "$name" =~ \.tar\.gz$ ]] && mime="application/gzip"
|
||||
[[ "$name" =~ \.(txt|sh)$ ]] && mime="text/plain"
|
||||
curl -X POST "${GITEA_API}/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets?name=${name}" \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: ${mime}" \
|
||||
--data-binary "@$asset"
|
||||
done
|
||||
|
||||
27
.goreleaser.yaml
Normal file
27
.goreleaser.yaml
Normal file
@ -0,0 +1,27 @@
|
||||
builds:
|
||||
- env:
|
||||
- CGO_ENABLED=0
|
||||
goos:
|
||||
- linux
|
||||
- darwin
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- arm64
|
||||
binary: grokkit
|
||||
ldflags:
|
||||
- -s -w
|
||||
- -X gmgauthier.com/grokkit/internal/version.Version={{.Version}}
|
||||
- -X gmgauthier.com/grokkit/internal/version.Commit={{.Commit}}
|
||||
- -X gmgauthier.com/grokkit/internal/version.BuildDate={{.Date}}
|
||||
- -trimpath
|
||||
|
||||
archives:
|
||||
- format: tar.gz
|
||||
name_template: 'grokkit_{{.Os}}_{{.Arch}}_{{.Version}}.tar.gz'
|
||||
- format: zip
|
||||
name_template: 'grokkit_{{.Os}}_{{.Arch}}_{{.Version}}.zip'
|
||||
os: windows
|
||||
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
@ -23,6 +23,15 @@ make build
|
||||
|
||||
# Verify installation
|
||||
grokkit --help
|
||||
|
||||
### From pre-built release (recommended)
|
||||
```bash
|
||||
VERSION=1.0.0 # Replace with latest version tag (omit 'v')
|
||||
curl -L https://repos.gmgauthier.com/gmgauthier/grokkit/releases/download/v${VERSION}/grokkit-install.sh | VERSION=${VERSION} bash -
|
||||
```
|
||||
Verify:
|
||||
```bash
|
||||
grokkit version
|
||||
```
|
||||
|
||||
## 📋 Table of Contents
|
||||
|
||||
11
cmd/root.go
11
cmd/root.go
@ -3,9 +3,11 @@ package cmd
|
||||
import (
|
||||
"os"
|
||||
|
||||
"fmt"
|
||||
"github.com/spf13/cobra"
|
||||
"gmgauthier.com/grokkit/config"
|
||||
"gmgauthier.com/grokkit/internal/logger"
|
||||
"gmgauthier.com/grokkit/internal/version"
|
||||
)
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
@ -35,6 +37,14 @@ func Execute() {
|
||||
}
|
||||
}
|
||||
|
||||
var versionCmd = &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Print the version information",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Printf("grokkit version %s (commit %s)\\n", version.Version, version.Commit)
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(chatCmd)
|
||||
rootCmd.AddCommand(editCmd)
|
||||
@ -45,6 +55,7 @@ func init() {
|
||||
rootCmd.AddCommand(historyCmd)
|
||||
rootCmd.AddCommand(agentCmd)
|
||||
rootCmd.AddCommand(completionCmd)
|
||||
rootCmd.AddCommand(versionCmd)
|
||||
|
||||
// Add model flag to all commands
|
||||
rootCmd.PersistentFlags().StringP("model", "m", "", "Grok model to use (overrides config)")
|
||||
|
||||
7
internal/version/version.go
Normal file
7
internal/version/version.go
Normal file
@ -0,0 +1,7 @@
|
||||
package version
|
||||
|
||||
var (
|
||||
Version = "dev"
|
||||
Commit = ""
|
||||
BuildDate = ""
|
||||
)
|
||||
50
scripts/grokkit-install.sh
Normal file
50
scripts/grokkit-install.sh
Normal file
@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
VERSION=${VERSION:-${1:?Provide VERSION env or arg, e.g. VERSION=1.0.0 bash grokkit-install.sh}}
|
||||
|
||||
GITEA_BASE=https://repos.gmgauthier.com/gmgauthier/grokkit
|
||||
|
||||
# Detect platform
|
||||
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
|
||||
case "$OS" in
|
||||
linux) OS=linux ;;
|
||||
darwin) OS=darwin ;;
|
||||
esac
|
||||
|
||||
ARCH=$(uname -m)
|
||||
case "$ARCH" in
|
||||
x86_64|amd64) ARCH=amd64 ;;
|
||||
arm64|aarch64) ARCH=arm64 ;;
|
||||
esac
|
||||
|
||||
ASSET="grokkit_${OS}_${ARCH}_${VERSION}.tar.gz"
|
||||
|
||||
echo "Installing grokkit ${VERSION} for ${OS}/${ARCH}..."
|
||||
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
trap "rm -rf \"${TEMP_DIR}\"" EXIT
|
||||
|
||||
cd "${TEMP_DIR}"
|
||||
|
||||
# Download
|
||||
curl -fL "${GITEA_BASE}/releases/download/v${VERSION}/${ASSET}" -o asset.tar.gz
|
||||
curl -fL "${GITEA_BASE}/releases/download/v${VERSION}/checksums.txt" -o checksums.txt
|
||||
|
||||
# Verify checksum
|
||||
HASH=$(grep " ${ASSET}$" checksums.txt | cut -d " " -f1)
|
||||
echo "${HASH} asset.tar.gz" | shasum -a 256 --check - || { echo "Checksum mismatch!"; exit 1; }
|
||||
|
||||
# Extract
|
||||
tar xzf asset.tar.gz
|
||||
BINARY="grokkit"
|
||||
|
||||
# Install
|
||||
INSTALL_DIR="${HOME}/.local/bin"
|
||||
mkdir -p "${INSTALL_DIR}"
|
||||
mv "${BINARY}" "${INSTALL_DIR}/grokkit"
|
||||
chmod +x "${INSTALL_DIR}/grokkit"
|
||||
|
||||
echo "✅ grokkit ${VERSION} installed to ${INSTALL_DIR}/grokkit"
|
||||
echo "Add to PATH if needed: export PATH=\"${INSTALL_DIR}:\$PATH\""
|
||||
grokkit version
|
||||
Loading…
Reference in New Issue
Block a user