diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..c331093 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,41 @@ +name: Release + +on: + push: + tags: + - 'v*' + +permissions: + contents: write + +jobs: + goreleaser: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '>=1.21.0' + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v5 + with: + distribution: goreleaser + version: latest + args: release --clean + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Update Homebrew tap + if: success() + uses: dawidd6/action-homebrew-bump-formula@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + tap: scalvert/homebrew-tap + formula: glean-cli + tag: ${{ github.ref_name }} diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..4130a62 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,50 @@ +before: + hooks: + - go mod tidy + +builds: + - env: + - CGO_ENABLED=0 + goos: + - linux + - windows + - darwin + goarch: + - amd64 + - arm64 + ldflags: + - -s -w -X main.version={{.Version}} + +archives: + - format: tar.gz + name_template: >- + {{ .ProjectName }}_ + {{- title .Os }}_ + {{- if eq .Arch "amd64" }}x86_64 + {{- else }}{{ .Arch }}{{ end }} + format_overrides: + - goos: windows + format: zip + +brews: + - repository: + owner: scalvert + name: homebrew-tap + homepage: "https://github.com/scalvert/glean-cli" + description: "A command-line interface for Glean operations" + license: "MIT" + install: | + bin.install "glean" + +checksum: + name_template: 'checksums.txt' + +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' + - '^ci:' + - Merge pull request + - Merge branch diff --git a/README.md b/README.md index 1294381..5b0f290 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,30 @@ A command-line interface for interacting with Glean's API and services. This CLI ## Installation +You can install the Glean CLI in several ways: + +### Using Homebrew (macOS and Linux) + +```bash +brew install scalvert/tap/glean-cli +``` + +### Using Go + ```bash go install github.com/scalvert/glean-cli@latest ``` +### Using Shell Script (macOS and Linux) + +```bash +curl -fsSL https://raw.githubusercontent.com/scalvert/glean-cli/main/install.sh | sh +``` + +### Manual Installation + +You can also download the latest binary for your platform from the [releases page](https://github.com/scalvert/glean-cli/releases). + ## Usage ```bash diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000..e06f136 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,160 @@ +# Release Process + +This document outlines the process for creating new releases of the Glean CLI. + +## Versioning + +We follow [Semantic Versioning](https://semver.org/) (SemVer): +- MAJOR version (X.0.0) - incompatible API changes +- MINOR version (0.X.0) - add functionality in a backward compatible manner +- PATCH version (0.0.X) - backward compatible bug fixes + +## Prerequisites + +Install the required tools: +```bash +# Install svu for automated versioning +go install github.com/caarlos0/svu@latest +``` + +## Release Steps + +You can create a new release using either the automated task or the manual steps below. + +### Automated Release + +```bash +# This will run all checks, create and push the tag +task release +``` + +### Manual Steps + +If you need more control over the release process, you can follow these steps manually: + +1. **Ensure Main Branch is Ready** + ```bash + git checkout main + git pull origin main + ``` + +2. **Run Tests and Checks** + ```bash + task test + task lint + ``` + +3. **Create Release** + ```bash + # Preview the next version based on conventional commits + svu next + + # Create and push the tag with the next version + git tag -a $(svu next) -m "Release $(svu next)" + git push origin $(svu next) + ``` + + Note: `svu` automatically determines the next version based on your commit messages: + - `feat:` -> MINOR version bump + - `fix:` -> PATCH version bump + - `BREAKING CHANGE:` in commit body -> MAJOR version bump + +4. **Monitor Release Process** + - The GitHub Action will automatically: + - Create a GitHub release + - Build binaries for all supported platforms + - Generate release notes from commits + - Upload artifacts to the release + - Update the Homebrew formula + +5. **Verify Release** + - Check the [GitHub releases page](https://github.com/scalvert/glean-cli/releases) + - Verify Homebrew formula was updated + - Test installation methods: + ```bash + # Homebrew + brew update + brew install scalvert/tap/glean-cli + + # Go Install + go install github.com/scalvert/glean-cli@latest + + # Shell Script + curl -fsSL https://raw.githubusercontent.com/scalvert/glean-cli/main/install.sh | sh + ``` + +## Release Artifacts + +Each release includes: +- Binary distributions for: + - macOS (x86_64, arm64) + - Linux (x86_64, arm64) + - Windows (x86_64, arm64) +- Source code (zip, tar.gz) +- Checksums file +- Changelog + +## Commit Convention + +To make the most of automated versioning, follow these commit message conventions: + +``` +: + +[optional body] + +[optional footer(s)] +``` + +Types: +- `feat:` - New feature (MINOR version bump) +- `fix:` - Bug fix (PATCH version bump) +- `docs:` - Documentation only changes +- `style:` - Changes that do not affect the meaning of the code +- `refactor:` - Code change that neither fixes a bug nor adds a feature +- `perf:` - Code change that improves performance +- `test:` - Adding missing tests or correcting existing tests +- `chore:` - Changes to the build process or auxiliary tools + +Breaking Changes: +- Add `BREAKING CHANGE:` to the commit body to trigger a MAJOR version bump +- Example: + ``` + feat: change API endpoint structure + + BREAKING CHANGE: The API endpoint structure has changed from /v1/* to /api/v1/* + ``` + +## Troubleshooting + +1. **GitHub Action Failed** + - Check the Action logs for errors + - Ensure GITHUB_TOKEN has required permissions + - Verify the tag follows the format `v*` (e.g., v1.0.0) + +2. **Homebrew Update Failed** + - Check if homebrew-tap repository exists + - Verify repository permissions + - Check the "Update Homebrew tap" step in the Action logs + +3. **Bad Release** + If a release has issues: + ```bash + # Get current version + current_version=$(svu current) + + # Delete tag locally + git tag -d $current_version + + # Delete tag remotely + git push --delete origin $current_version + ``` + Then fix the issues and retry the release process. + +## Notes + +- Release notes are automatically generated from commit messages +- Commits starting with `docs:`, `test:`, `ci:` are excluded from release notes +- The release process is automated via GitHub Actions +- Binary distributions are built using GoReleaser +- All releases are automatically published to GitHub Releases diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..1944d1e --- /dev/null +++ b/install.sh @@ -0,0 +1,49 @@ +#!/bin/sh +set -e + +# Glean CLI Installer +# +# Usage: +# curl -fsSL https://raw.githubusercontent.com/scalvert/glean-cli/main/install.sh | sh + +LATEST_VERSION=$(curl -s https://api.github.com/repos/scalvert/glean-cli/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') +OS=$(uname -s | tr '[:upper:]' '[:lower:]') +ARCH=$(uname -m) + +# Convert architecture names +case "$ARCH" in + x86_64) ARCH="x86_64" ;; + amd64) ARCH="x86_64" ;; + arm64) ARCH="arm64" ;; + aarch64) ARCH="arm64" ;; + *) echo "Unsupported architecture: $ARCH"; exit 1 ;; +esac + +# Construct download URL +DOWNLOAD_URL="https://github.com/scalvert/glean-cli/releases/download/${LATEST_VERSION}/glean-cli_${OS}_${ARCH}.tar.gz" + +# Create temporary directory +TMP_DIR=$(mktemp -d) +cleanup() { + rm -rf "$TMP_DIR" +} +trap cleanup EXIT + +# Download and extract +echo "Downloading Glean CLI ${LATEST_VERSION}..." +curl -fsSL "$DOWNLOAD_URL" -o "$TMP_DIR/glean.tar.gz" +tar -xzf "$TMP_DIR/glean.tar.gz" -C "$TMP_DIR" + +# Install binary +INSTALL_DIR="/usr/local/bin" +if [ ! -w "$INSTALL_DIR" ]; then + echo "Installing Glean CLI requires sudo access to $INSTALL_DIR" + sudo mv "$TMP_DIR/glean" "$INSTALL_DIR/" + sudo chmod +x "$INSTALL_DIR/glean" +else + mv "$TMP_DIR/glean" "$INSTALL_DIR/" + chmod +x "$INSTALL_DIR/glean" +fi + +echo "Glean CLI has been installed to $INSTALL_DIR/glean" +echo "Run 'glean --help' to get started" \ No newline at end of file diff --git a/taskfile.yml b/taskfile.yml index da8d032..d35c1c0 100644 --- a/taskfile.yml +++ b/taskfile.yml @@ -36,8 +36,37 @@ tasks: cmds: - golangci-lint run --fix - install: desc: Install the CLI locally cmds: - go install + + release: + desc: Create and push a new release + cmds: + # Ensure we're on main and up to date + - git checkout main + - git pull origin main + + # Run checks + - task: check + + # Get the next version + - echo "Next version will be $(svu next)" + - echo "Press Ctrl+C to cancel or wait 5 seconds to continue..." + - sleep 5 + + # Create and push the tag + - | + version=$(svu next) + git tag -a $version -m "Release $version" + git push origin $version + + # Instructions for monitoring + - echo "Release process started!" + - echo "Monitor the release at https://github.com/scalvert/glean-cli/actions" + preconditions: + - sh: "git diff-index --quiet HEAD" + msg: "Working directory is not clean. Please commit or stash changes first." + - sh: "command -v svu" + msg: "svu is not installed. Run: go install github.com/caarlos0/svu@latest"