shelley: add GitHub Actions for auto-release and tests

Philip Zeyliger and Claude created

- Add release workflow that triggers on every push to main
- Add test workflow that runs Go tests on push/PR
- Add .goreleaser.yml for cross-platform builds (linux/darwin, amd64/arm64)
- Update README with installation instructions (curl, homebrew, source)

Versions follow pattern v0.N.9OCTAL where N is commit count and
9OCTAL is the SHA encoded as octal.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

Change summary

.github/workflows/release.yml | 73 +++++++++++++++++++++++++++++++++++++
.github/workflows/test.yml    | 43 +++++++++++++++++++++
.goreleaser.yml               | 64 ++++++++++++++++++++++++++++++++
README.md                     | 35 ++++++++++++++++-
4 files changed, 213 insertions(+), 2 deletions(-)

Detailed changes

.github/workflows/release.yml 🔗

@@ -0,0 +1,73 @@
+name: Release
+
+on:
+  push:
+    branches:
+      - main
+
+permissions:
+  contents: write
+
+jobs:
+  goreleaser:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+        with:
+          fetch-depth: 0
+
+      - name: Generate version tag
+        id: version
+        run: |
+          # Get commit count as version number
+          COUNT=$(git rev-list --count HEAD)
+          SHORT_SHA=$(git rev-parse --short=6 HEAD)
+          # Convert 6-char hex SHA to octal, prefixed with 9 to ensure valid semver
+          SHA_OCTAL=$(printf '%o' "0x${SHORT_SHA}")
+          VERSION="0.${COUNT}.9${SHA_OCTAL}"
+          TAG="v${VERSION}"
+
+          echo "version=${VERSION}" >> $GITHUB_OUTPUT
+          echo "tag=${TAG}" >> $GITHUB_OUTPUT
+          echo "sha=${SHORT_SHA}" >> $GITHUB_OUTPUT
+
+          # Create and push tag
+          git config user.name "github-actions[bot]"
+          git config user.email "github-actions[bot]@users.noreply.github.com"
+          git tag -a "${TAG}" -m "Release ${TAG} (${SHORT_SHA})"
+          git push origin "${TAG}"
+
+      - name: Set up Go
+        uses: actions/setup-go@v5
+        with:
+          go-version: '1.24'
+
+      - name: Set up Node.js
+        uses: actions/setup-node@v4
+        with:
+          node-version: '20'
+
+      - name: Build UI
+        run: |
+          cd ui
+          npm ci
+          npm run build
+
+      - name: Build templates
+        run: |
+          for dir in templates/*/; do
+            name=$(basename "$dir")
+            echo "Creating $name.tar.gz..."
+            tar -czf "templates/$name.tar.gz" -C "templates/$name" --exclude='.DS_Store' .
+          done
+
+      - name: Run GoReleaser
+        uses: goreleaser/goreleaser-action@v6
+        with:
+          distribution: goreleaser
+          version: latest
+          args: release --clean
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}

.github/workflows/test.yml 🔗

@@ -0,0 +1,43 @@
+name: Test
+
+on:
+  push:
+    branches:
+      - main
+  pull_request:
+    branches:
+      - main
+
+jobs:
+  test:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+
+      - name: Set up Go
+        uses: actions/setup-go@v5
+        with:
+          go-version: '1.24'
+
+      - name: Set up Node.js
+        uses: actions/setup-node@v4
+        with:
+          node-version: '20'
+
+      - name: Build UI
+        run: |
+          cd ui
+          npm ci
+          npm run build
+
+      - name: Build templates
+        run: |
+          for dir in templates/*/; do
+            name=$(basename "$dir")
+            echo "Creating $name.tar.gz..."
+            tar -czf "templates/$name.tar.gz" -C "templates/$name" --exclude='.DS_Store' .
+          done
+
+      - name: Run Go tests
+        run: go test -v ./...

.goreleaser.yml 🔗

@@ -0,0 +1,64 @@
+version: 2
+
+before:
+  hooks:
+    - go mod tidy
+
+builds:
+  - id: shelley
+    binary: shelley
+    main: ./cmd/shelley
+    env:
+      - CGO_ENABLED=0
+    goos:
+      - linux
+      - darwin
+    goarch:
+      - amd64
+      - arm64
+    ldflags:
+      - -s -w
+
+archives:
+  - id: shelley
+    format: binary
+    name_template: >-
+      {{ .ProjectName }}_
+      {{- .Os }}_
+      {{- .Arch }}
+
+checksum:
+  name_template: 'checksums.txt'
+
+snapshot:
+  version_template: "{{ incpatch .Version }}-next"
+
+changelog:
+  sort: asc
+  filters:
+    exclude:
+      - '^docs:'
+      - '^test:'
+      - '^chore:'
+      - 'typo'
+
+release:
+  github:
+    owner: boldsoftware
+    name: shelley
+  draft: false
+  prerelease: auto
+
+brews:
+  - repository:
+      owner: philz
+      name: homebrew-tap
+      token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}"
+    directory: Formula
+    homepage: https://github.com/boldsoftware/shelley
+    description: "A mobile-friendly, web-based, multi-modal coding agent"
+    license: Apache-2.0
+    install: |
+      bin.install "shelley"
+    test: |
+      system "#{bin}/shelley", "--help"

README.md 🔗

@@ -3,18 +3,49 @@
 Shelley is a mobile-friendly, web-based, multi-conversation, multi-modal,
 multi-model, single-user coding agent built for but not exclusive to
 [exe.dev](https://exe.dev/). It does not come with authorization or sandboxing:
-bring your own. 
+bring your own.
 
 *Mobile-friendly* because ideas can come any time.
 
 *Web-based*, because terminal-based scroll back is punishment for shoplifting in some countries.
 
-*Multi-modal* because screenshots, charts, and graphs are necessary, not to mention delightful. 
+*Multi-modal* because screenshots, charts, and graphs are necessary, not to mention delightful.
 
 *Multi-model* to benefit from all the innovation going on.
 
 *Single-user* because it makes sense to bring the agent to the compute.
 
+# Installation
+
+## Pre-Built Binaries (macOS/Linux)
+
+```bash
+curl -Lo shelley "https://github.com/boldsoftware/shelley/releases/latest/download/shelley_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')" && chmod +x shelley
+```
+
+The binaries are on the [releases page](https://github.com/boldsoftware/shelley/releases/latest).
+
+## Homebrew (macOS/Linux)
+
+```bash
+brew install philz/tap/shelley
+```
+
+## Build from Source
+
+You'll need Go and Node.
+
+```bash
+git clone https://github.com/boldsoftware/shelley.git
+cd shelley
+make
+```
+
+# Releases
+
+New releases are automatically created on every commit to `main`. Versions
+follow the pattern `v0.N.9OCTAL` where N is the total commit count and 9OCTAL is the commit SHA encoded as octal (prefixed with 9).
+
 # Architecture 
 
 The technical stack is Go for the backend, SQLite for storage, and Typescript