diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d9cbe0a..d776cfb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,8 +1,7 @@ name: Release -# A version tag publishes a release. The manual trigger runs the same build but -# stops before publishing and keeps the archives as workflow artifacts, which is -# the safe way to check the pipeline without creating a release. +# A version tag publishes a release with GoReleaser. The manual trigger runs the +# same verification and a snapshot build, but stops before publishing. on: push: tags: ['v*'] @@ -16,8 +15,8 @@ concurrency: cancel-in-progress: false jobs: - release: - name: build and publish + verify: + name: verify runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 @@ -53,91 +52,71 @@ jobs: exit 1 fi - - name: build the archives - run: make release + - name: test + run: go test ./... -count=1 + + - name: check the GoReleaser configuration + uses: goreleaser/goreleaser-action@v7 + with: + distribution: goreleaser + version: '~> v2' + args: check + + - name: build the archives without publishing + uses: goreleaser/goreleaser-action@v7 + with: + distribution: goreleaser + version: '~> v2' + args: release --snapshot --clean - name: smoke test the linux build shell: bash run: | set -e - version='${{ steps.version.outputs.value }}' + archive=$(ls dist/cli-proxy_*_linux_amd64.tar.gz | head -1) + echo "testing $archive" tmp=$(mktemp -d) - tar -xzf "dist/cli-proxy_${version}/cli-proxy_${version}_linux_amd64.tar.gz" -C "$tmp" - got=$("$tmp/cli-proxy" -version) - echo "binary reports: $got" - if [ "$got" != "cli-proxy $version" ]; then - echo "::error::unexpected version output: $got" - exit 1 - fi - "$tmp/cli-proxy" -h >/dev/null + tar -xzf "$archive" -C "$tmp" test -f "$tmp/README.md" test -f "$tmp/LICENSE" + "$tmp/cli-proxy" -h >/dev/null + "$tmp/cli-proxy" -version - name: verify the checksums shell: bash - run: | - cd "dist/cli-proxy_${{ steps.version.outputs.value }}" - sha256sum -c checksums.txt + run: cd dist && sha256sum -c checksums.txt - - name: keep the archives as workflow artifacts + - name: keep the snapshot archives uses: actions/upload-artifact@v7 with: - name: cli-proxy-archives - path: dist/cli-proxy_*/ + name: cli-proxy-snapshot + path: | + dist/cli-proxy_*.tar.gz + dist/cli-proxy_*.zip + dist/checksums.txt if-no-files-found: error retention-days: 14 + release: + name: publish + needs: verify + if: startsWith(github.ref, 'refs/tags/') + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + fetch-depth: 0 + + - uses: actions/setup-go@v7 + with: + go-version-file: go.mod + check-latest: true + - name: publish the release - if: startsWith(github.ref, 'refs/tags/') - shell: bash + uses: goreleaser/goreleaser-action@v7 + with: + distribution: goreleaser + version: '~> v2' + args: release --clean env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - set -euo pipefail - tag="${GITHUB_REF_NAME}" - version='${{ steps.version.outputs.value }}' - dir="dist/cli-proxy_${version}" - - # A short preamble, then the commits since the previous tag. - cat > /tmp/notes.md <<'PREAMBLE' - Статический бинарник без внешних зависимостей — только стандартная - библиотека Go. В каждом архиве программа, `README.md` и `LICENSE`; - контрольные суммы — в `checksums.txt`. - - | Платформа | Файл | - |---|---| - | Linux x86-64 | `cli-proxy_<версия>_linux_amd64.tar.gz` | - | Linux arm64 | `cli-proxy_<версия>_linux_arm64.tar.gz` | - | macOS Apple Silicon | `cli-proxy_<версия>_darwin_arm64.tar.gz` | - | macOS Intel | `cli-proxy_<версия>_darwin_amd64.tar.gz` | - | Windows x86-64 | `cli-proxy_<версия>_windows_amd64.zip` | - - ```sh - tar -xzf cli-proxy_<версия>_darwin_arm64.tar.gz - ./cli-proxy -install-cert # довериться корневому сертификату - ./cli-proxy -system-proxy # направить системный прокси сюда - ``` - - ## Изменения - PREAMBLE - - # The template uses a placeholder so the heredoc can stay quoted. - sed "s/<версия>/${version}/g" /tmp/notes.md > /tmp/notes.fixed - mv /tmp/notes.fixed /tmp/notes.md - - previous=$(git describe --tags --abbrev=0 "${tag}^" 2>/dev/null || true) - if [ -n "$previous" ]; then - echo "listing commits ${previous}..${tag}" >&2 - git log --no-merges --pretty='- %s' "${previous}..${tag}" >> /tmp/notes.md - else - git log --no-merges --pretty='- %s' "${tag}" >> /tmp/notes.md - fi - echo >> /tmp/notes.md - - gh release create "$tag" \ - --title "cli-proxy $tag" \ - --notes-file /tmp/notes.md \ - --verify-tag \ - "${dir}"/cli-proxy_"${version}"_*.tar.gz \ - "${dir}"/cli-proxy_"${version}"_*.zip \ - "${dir}"/checksums.txt + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..b8f1f6b --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,90 @@ +version: 2 + +project_name: cli-proxy + +before: + hooks: + - go mod tidy + +builds: + - id: cli-proxy + main: . + binary: cli-proxy + env: + - CGO_ENABLED=0 + goos: + - linux + - darwin + - windows + goarch: + - amd64 + - arm64 + flags: + - -trimpath + ldflags: + - -s -w + +archives: + - id: release + # Prebuilt archives keep the name the README documents: + # cli-proxy___.tar.gz, and .zip on Windows. + name_template: >- + {{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }} + formats: + - tar.gz + format_overrides: + - goos: windows + formats: + - zip + files: + - README.md + - LICENSE + +checksum: + name_template: checksums.txt + algorithm: sha256 + +snapshot: + version_template: '{{ incpatch .Version }}-snapshot' + +changelog: + use: git + sort: asc + filters: + exclude: + - '^docs:' + - '^ci:' + - '^test:' + - '^chore' + +release: + draft: false + prerelease: auto + name_template: 'cli-proxy {{ .Tag }}' + header: | + Статический бинарник без внешних зависимостей — только стандартная + библиотека Go. В каждом архиве программа, `README.md` и `LICENSE`; + контрольные суммы — в `checksums.txt`. + + | Платформа | Файл | + |---|---| + | Linux x86-64 | `cli-proxy_{{ .Version }}_linux_amd64.tar.gz` | + | Linux arm64 | `cli-proxy_{{ .Version }}_linux_arm64.tar.gz` | + | macOS Apple Silicon | `cli-proxy_{{ .Version }}_darwin_arm64.tar.gz` | + | macOS Intel | `cli-proxy_{{ .Version }}_darwin_amd64.tar.gz` | + | Windows x86-64 | `cli-proxy_{{ .Version }}_windows_amd64.zip` | + + ```sh + brew install sadgoodman/tap/cli-proxy + ``` + + ```sh + tar -xzf cli-proxy_{{ .Version }}_darwin_arm64.tar.gz + ./cli-proxy -install-cert # довериться корневому сертификату + ./cli-proxy -system-proxy # направить системный прокси сюда + ``` + footer: | + **Полное руководство:** [docs/guide.md](https://github.com/sadgoodman/cli-proxy/blob/master/docs/guide.md) + (есть также [русская версия](https://github.com/sadgoodman/cli-proxy/blob/master/docs/guide.ru.md)). + + Установка одной командой: `brew install sadgoodman/tap/cli-proxy`. diff --git a/Makefile b/Makefile index f0aed22..6b89f98 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ BINARY := cli-proxy GOFLAGS ?= LDFLAGS := -s -w VERSION := $(shell sed -n 's/^const version = "\(.*\)"/\1/p' main.go) -PLATFORMS := linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64 +PLATFORMS := linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64 windows/arm64 RELDIR := dist/$(BINARY)_$(VERSION) .PHONY: all build slim test vet fmt run clean cross release @@ -37,6 +37,8 @@ cross: GOOS=windows GOARCH=amd64 go build -trimpath -ldflags="$(LDFLAGS)" -o dist/$(BINARY)-windows-amd64.exe . # Build the archives attached to a GitHub release, plus checksums. +# CI uses GoReleaser for this; the target is kept so a release can be reproduced +# locally without installing anything. release: clean rm -rf $(RELDIR) @for target in $(PLATFORMS); do \ diff --git a/README.es.md b/README.es.md index 4f0de17..495eea1 100644 --- a/README.es.md +++ b/README.es.md @@ -59,6 +59,10 @@ estático, **sin dependencias externas** — solo la biblioteca estándar. ## Instalación +```sh +brew install sadgoodman/tap/cli-proxy +``` + Descarga un archivo precompilado desde la [última versión][rel], o compílalo desde el código fuente con Go 1.25+. diff --git a/README.md b/README.md index a76478c..7f7d7a7 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,10 @@ dependencies** — standard library only. ## Install +```sh +brew install sadgoodman/tap/cli-proxy +``` + Download a prebuilt archive from the [latest release][rel], or build from source with Go 1.25+. diff --git a/README.ru.md b/README.ru.md index 3766c20..53bcaed 100644 --- a/README.ru.md +++ b/README.ru.md @@ -53,6 +53,10 @@ ## Установка +```sh +brew install sadgoodman/tap/cli-proxy +``` + Скачайте готовый архив из [последнего релиза][rel] или соберите из исходников (нужен Go 1.25+). diff --git a/README.zh.md b/README.zh.md index a78a3b8..d53cc2b 100644 --- a/README.zh.md +++ b/README.zh.md @@ -47,6 +47,10 @@ ## 安装 +```sh +brew install sadgoodman/tap/cli-proxy +``` + 从[最新发布][rel]下载预编译压缩包,或使用 Go 1.25+ 从源码构建。 | 平台 | 资源文件 | diff --git a/docs/guide.md b/docs/guide.md index 5f7efab..582053f 100644 --- a/docs/guide.md +++ b/docs/guide.md @@ -70,6 +70,30 @@ dependencies** — the Go standard library only. keyboard-driven, plus the mouse: hovering highlights rows, tabs and buttons, clicking selects. Menu items switch with `←`/`→` (or `Tab`). +## Installing + +Homebrew is the shortest route: + +```sh +brew install sadgoodman/tap/cli-proxy +``` + +Otherwise download a prebuilt archive from the [latest release][rel]: + +| Platform | Asset | +|---|---| +| Linux x86-64 | `cli-proxy__linux_amd64.tar.gz` | +| Linux arm64 | `cli-proxy__linux_arm64.tar.gz` | +| macOS Apple Silicon | `cli-proxy__darwin_arm64.tar.gz` | +| macOS Intel | `cli-proxy__darwin_amd64.tar.gz` | +| Windows x86-64 | `cli-proxy__windows_amd64.zip` | + +`checksums.txt` in the same release carries the SHA-256 of every archive. + +The Homebrew formula updates itself: [`sadgoodman/homebrew-tap`][tap] is checked +against the latest release every hour. To pick a release up immediately, run the +**Update formulae** workflow from the Actions tab. + ## Building ```sh @@ -556,7 +580,7 @@ make cross # build for every supported platform 1. it checks the version in `main.go` against the tag and fails if they disagree; -2. it builds the archives (`make release`), verifies the checksums and runs the +2. it builds the archives with GoReleaser (`goreleaser release`), verifies the checksums and runs the built Linux binary; 3. it publishes a GitHub Release with the archives, `checksums.txt` and the list of commits since the previous tag. diff --git a/docs/guide.ru.md b/docs/guide.ru.md index f0e32a9..08266e9 100644 --- a/docs/guide.ru.md +++ b/docs/guide.ru.md @@ -66,6 +66,30 @@ клавиатурный, плюс мышь: наведение подсвечивает строки, вкладки и кнопки, клик выбирает. Пункты меню переключаются стрелками `←`/`→` (или `Tab`). +## Установка + +Через Homebrew — короче всего: + +```sh +brew install sadgoodman/tap/cli-proxy +``` + +Или скачайте готовый архив из [последнего релиза][rel]: + +| Платформа | Файл | +|---|---| +| Linux x86-64 | `cli-proxy_<версия>_linux_amd64.tar.gz` | +| Linux arm64 | `cli-proxy_<версия>_linux_arm64.tar.gz` | +| macOS Apple Silicon | `cli-proxy_<версия>_darwin_arm64.tar.gz` | +| macOS Intel | `cli-proxy_<версия>_darwin_amd64.tar.gz` | +| Windows x86-64 | `cli-proxy_<версия>_windows_amd64.zip` | + +В том же релизе лежит `checksums.txt` с SHA-256 каждого архива. + +Формула Homebrew обновляется сама: репозиторий [`sadgoodman/homebrew-tap`][tap] +раз в час сверяется с последним релизом. Если нужно сразу после выпуска, +запустите workflow **Update formulae** во вкладке Actions. + ## Сборка ```sh @@ -541,7 +565,7 @@ make cross # собрать под все поддерживаемые пл `.github/workflows/release.yml` реагирует на тег вида `v*`: 1. сверяет версию из `main.go` с тегом и падает, если они разошлись; -2. собирает архивы (`make release`), проверяет контрольные суммы и запускает +2. собирает архивы через GoReleaser (`goreleaser release`), проверяет контрольные суммы и запускает собранный linux-бинарник; 3. публикует GitHub Release с архивами, `checksums.txt` и списком коммитов с прошлого тега.