ci: add goreleaser release workflow

This commit is contained in:
Peter Steinberger 2026-05-08 08:53:47 +01:00
parent 40510af5c8
commit 2d3a2cf0e7
No known key found for this signature in database
11 changed files with 249 additions and 3 deletions

64
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,64 @@
name: release
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
tag_name:
description: "Existing release tag to publish, for example v0.1.0"
required: true
type: string
permissions:
contents: write
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
NODE_VERSION: "24"
PNPM_VERSION: "11.0.7"
jobs:
release:
name: GoReleaser
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Check out
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ inputs.tag_name || github.ref }}
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true
- name: Set up pnpm
uses: pnpm/action-setup@v4
with:
version: ${{ env.PNPM_VERSION }}
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run local gate
run: pnpm check
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v6
with:
distribution: goreleaser
version: "~> v2"
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

91
.goreleaser.yml Normal file
View File

@ -0,0 +1,91 @@
version: 2
project_name: clickclack
before:
hooks:
- pnpm build
builds:
- id: clickclack
main: ./apps/api/cmd/clickclack
binary: clickclack
env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin
- freebsd
goarch:
- amd64
- arm64
flags:
- -trimpath
ldflags:
- >-
-s -w
-X main.version={{ .Version }}
-X main.commit={{ .ShortCommit }}
-X main.date={{ .Date }}
archives:
- id: bundles
ids:
- clickclack
name_template: >-
{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{- if eq .Arch "arm64" -}}aarch64{{- else -}}{{ .Arch }}{{- end -}}
formats:
- tar.gz
format_overrides:
- goos: windows
formats:
- zip
files:
- LICENSE
- README.md
- SPEC.md
- CHANGELOG.md
- docs/**/*
checksum:
name_template: "sha256sums.txt"
algorithm: sha256
snapshot:
version_template: "{{ incpatch .Version }}-next"
changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"
- "^ci:"
- "^chore:"
- "^Merge pull request"
- "^Merge branch"
nfpms:
- id: linux-packages
ids:
- clickclack
package_name: clickclack
file_name_template: "{{ .ConventionalFileName }}"
homepage: https://clickclack.chat
maintainer: OpenClaw <steipete@gmail.com>
description: Self-hostable chat with Slack-style threads, durable realtime, OpenAPI, and a TypeScript SDK.
license: MIT
formats:
- deb
- rpm
bindir: /usr/bin
section: utils
priority: optional
contents:
- src: ./README.md
dst: /usr/share/doc/clickclack/README.md
- src: ./LICENSE
dst: /usr/share/doc/clickclack/LICENSE
- src: ./SPEC.md
dst: /usr/share/doc/clickclack/SPEC.md

View File

@ -17,3 +17,5 @@
quickstart CTA contrast in dark mode.
- Split GitHub Actions into explicit Go, TypeScript, Playwright, and Docker
gates, with `gofmt` and `oxfmt --check` enforced in CI.
- Added GoReleaser config and release workflow for Linux, macOS, Windows, and
FreeBSD archives, plus Linux `.deb` and `.rpm` packages.

View File

@ -46,7 +46,8 @@ short `read_when` hint at the top — open the one that matches your change.
- [Data model](docs/data-model.md) — tables, IDs, invariants.
- [CLI](docs/cli.md), [Agent-friendly CLI](docs/agent-friendly-cli.md),
[Configuration](docs/configuration.md),
[Deployment](docs/deployment.md), [Development](docs/development.md).
[Deployment](docs/deployment.md), [Development](docs/development.md),
[Releasing](docs/releasing.md).
- [TypeScript SDK](docs/sdk.md).
Per-feature docs:
@ -156,6 +157,7 @@ pnpm coverage # Go coverage with 90% gate
pnpm test:e2e # Playwright
pnpm fmt # gofmt + oxfmt write
pnpm fmt:check # gofmt + oxfmt check, CI-compatible
goreleaser release --snapshot --clean # local release smoke test
```
## Deployment

View File

@ -17,6 +17,12 @@ import (
sqlitestore "github.com/openclaw/clickclack/apps/api/internal/store/sqlite"
)
var (
version = "dev"
commit = "none"
date = "unknown"
)
func main() {
if err := run(); err != nil {
log.Fatal(err)
@ -39,6 +45,9 @@ func run() error {
return backup(os.Args[2:])
case "export":
return exportData(os.Args[2:])
case "version":
fmt.Printf("clickclack %s (%s, %s)\n", version, commit, date)
return nil
default:
return client(os.Args[1:])
}

View File

@ -70,6 +70,7 @@ it for anything that isn't a local clone.
- [Configuration](configuration.md) — flag/env/file precedence.
- [Deployment](deployment.md) — single binary, Docker, data layout, OAuth.
- [Development](development.md) — pnpm scripts, monorepo layout, gates.
- [Releasing](releasing.md) — GoReleaser targets, artifacts, and tag flow.
## Look under the hood

View File

@ -30,6 +30,22 @@ The Go build step requires the SPA `dist/` to be present because `webassets`
uses `go:embed`. The `pnpm build` script copies `apps/web/dist` into
`apps/api/internal/webassets/dist`; CI must run it before `go build`.
## Releases
GoReleaser is configured in `.goreleaser.yml`. It builds `clickclack` for
Linux, macOS, Windows, and FreeBSD on `amd64` and `arm64`, with Windows
archives emitted as `.zip` and the others as `.tar.gz`. Linux `.deb` and
`.rpm` packages are generated through nfpm.
```sh
pnpm install
goreleaser release --snapshot --clean
```
The GoReleaser config runs `pnpm build` before compiling so the embedded SPA
is refreshed. Publishing is handled by `.github/workflows/release.yml` on
`v*` tags or manual dispatch with an existing tag.
## Docker
The provided `Dockerfile` is multi-stage:

View File

@ -55,6 +55,7 @@ The Vite dev server proxies `/api` and `/api/realtime/ws` to `localhost:8080`.
| `pnpm fmt` | `gofmt` + `oxfmt` over Go and TS/Svelte. |
| `pnpm fmt:check` | CI-compatible formatting check with `gofmt -l` and `oxfmt --check`. |
| `pnpm lint` | `oxlint` over web, SDK, examples, and tests. |
| `goreleaser release --snapshot --clean` | Local release smoke test for all configured OS/arch targets. |
| `pnpm typecheck` | `tsgo --noEmit -p tsconfig.json` for root Playwright config/tests. |
| `pnpm test` | `go test ./... && pnpm build`. |
| `pnpm test:e2e` | Playwright suite in `tests/e2e`. |

View File

@ -53,8 +53,21 @@ docker run --rm -v clickclack-data:/app/data clickclack \
## Pre-built binaries
There are no published release artifacts yet — V1 ships from source. Once
binaries land, this page will list the canonical install line.
GitHub releases publish `clickclack` archives for Linux, macOS, Windows, and
FreeBSD on `amd64` and `arm64`, plus Linux `.deb` and `.rpm` packages.
```sh
# macOS/Linux tarball shape
tar -xzf clickclack_<version>_<os>_<arch>.tar.gz
./clickclack version
# Linux packages
sudo dpkg -i clickclack_<version>_amd64.deb
sudo rpm -i clickclack-<version>-1.x86_64.rpm
```
Release archives include `LICENSE`, `README.md`, `SPEC.md`, `CHANGELOG.md`,
and the docs tree. Checksums are published as `sha256sums.txt`.
## What you get

46
docs/releasing.md Normal file
View File

@ -0,0 +1,46 @@
---
read_when:
- cutting a ClickClack release
- changing GoReleaser, package artifacts, or release automation
---
# Releasing
ClickClack uses GoReleaser v2. The config is `.goreleaser.yml`; the GitHub
Actions publisher is `.github/workflows/release.yml`.
## Local Smoke Test
```sh
pnpm install
goreleaser check
goreleaser release --snapshot --clean
```
The snapshot build runs `pnpm build`, then cross-compiles `clickclack` for:
- `linux/amd64`
- `linux/arm64`
- `darwin/amd64`
- `darwin/arm64`
- `windows/amd64`
- `windows/arm64`
- `freebsd/amd64`
- `freebsd/arm64`
It also emits Linux `.deb` and `.rpm` packages and `sha256sums.txt`.
## Publish
Push a semver tag:
```sh
git tag v0.1.0
git push origin v0.1.0
```
The release workflow checks out the tag, installs Go and pnpm, runs
`pnpm check`, then runs `goreleaser release --clean` with `GITHUB_TOKEN`.
Manual release dispatch is available for an existing tag through the
`release` workflow's `tag_name` input.

View File

@ -38,6 +38,7 @@ const sections = [
"configuration.md",
"deployment.md",
"development.md",
"releasing.md",
"sdk.md",
]],
["Reference", [