Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Ordinary build hygiene on every push and pull request.
#
# There are no tests in this repo yet; `go test ./...` is here anyway so that the
# first one added is run rather than merely committed. The build step is what
# currently catches breakage, and it is a real check for a CLI whose command
# table is hand-maintained.
name: CI

on:
push:
branches: [main]
pull_request:

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true

- name: Check formatting
run: |
unformatted=$(gofmt -l .)
if [ -n "$unformatted" ]; then
echo "Files not gofmt-formatted:"
echo "$unformatted"
exit 1
fi

- name: Vet
run: go vet ./...

- name: Test
run: go test ./...

- name: Build
run: go build ./...

# The release matrix, checked on every PR rather than discovered on a tag.
# Cheap: the stdlib for each target is cached by setup-go.
- name: Cross-compile the release targets
run: |
for target in linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64 windows/arm64; do
echo "==> $target"
CGO_ENABLED=0 GOOS=${target%/*} GOARCH=${target#*/} go build -o /dev/null .
done
39 changes: 39 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Cuts a release when a v* tag is pushed: cross-compiled binaries via goreleaser,
# checksums, and a GitHub release whose notes come from the commits in the tag.
#
# No container image here, unlike the platform's release workflow -- this binary
# is installed onto a host, not run as a service in a cluster, and an image would
# be a second definition of the same artifact with nobody to consume it.
name: Release

on:
push:
tags: ['v*']

permissions:
contents: write # create the GitHub release

jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# goreleaser derives the version and the changelog from tags, and a
# shallow clone has neither.
fetch-depth: 0

- uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true

- name: Test
run: go test ./...

- uses: goreleaser/goreleaser-action@v6
with:
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
*.test
*.out
.DS_Store

# goreleaser output
dist/
92 changes: 92 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Release configuration for the client CLI.
#
# One binary, six targets, no build hooks -- `stone` is a plain Go client with
# nothing embedded in it, which is the whole difference between this file and the
# platform's. It talks to a running server over HTTPS and NATS, so there is no
# console to compile first and no reason to ship anything but the binary.
#
# The binary is `stone`; the repo and module are `stone-cli`. Archives are named
# after the binary, because that is the name a user types and searches for.
version: 2

project_name: stone-cli

builds:
- id: stone
main: .
binary: stone
env:
# Nothing in the dependency tree needs cgo, so every target below
# cross-compiles from one runner.
- CGO_ENABLED=0
ldflags:
# cmd.version is unexported, which -X handles fine; it is read into
# rootCmd.Version at init, after the linker has written it.
- -s -w -X github.com/stone-age-io/stone-cli/cmd.version={{.Version}}
goos: [linux, darwin, windows]
# windows/arm64 is included here and excluded in the platform, deliberately:
# this is a laptop and CI-runner tool, and ARM Windows laptops exist. A
# server binary has no such audience.
goarch: [amd64, arm64]

archives:
- id: stone
ids: [stone]
formats: [tar.gz]
format_overrides:
- goos: windows
formats: [zip]
files:
- LICENSE
- README.md
# The audience-neutral description of the command surface, for people
# driving the CLI from another tool or assistant. It travels with the
# binary because it documents exactly this version's commands.
- SKILLS.md
name_template: >-
stone_
{{- .Version }}_
{{- .Os }}_
{{- .Arch }}

checksum:
name_template: 'checksums.txt'
algorithm: sha256

changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
- '^chore:'
- '^ci:'

release:
github:
owner: stone-age-io
name: stone-cli
header: |
## stone {{ .Tag }}

The command-line client for the Stone-Age.io platform. Extract the binary
onto a laptop or CI runner and point it at a running server:

```
stone context create local --url https://platform.example.com
stone auth login
```

**`stone` is not `stone-age`.** This is the client; `stone-age` is the
control-plane server, released from the
[platform](https://github.com/stone-age-io/platform) repo. They share a
project, not a job.
footer: |
Pre-1.0: treat a minor version as potentially breaking, and pin what you
deploy.

The CLI's field list is hand-maintained rather than derived from the
platform's `schema.json`, so a given `stone` can lag a platform release. If a
field exists in the console but has no flag, that is why.

**Full changelog**: https://github.com/stone-age-io/stone-cli/commits/{{ .Tag }}
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2025-2026 Brian Miller

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Loading