ScuttleBot

build: add GoReleaser — cross-platform binaries, Docker to GHCR Replaces hand-rolled release.yml with goreleaser-action v6. Builds scuttlebot, scuttlectl, claude-relay, codex-relay, gemini-relay for linux/darwin (amd64+arm64) and windows/amd64. Artifacts per release: - scuttlebot_{ver}_{os}_{arch}.tar.gz — daemon + CLI + example config - scuttlebot-relays_{ver}_{os}_{arch}.tar.gz — relay binaries - checksums.txt (SHA256) - ghcr.io/conflicthq/scuttlebot:{tag} (amd64 + arm64 manifest) Dockerfile.release copies the pre-built binary into alpine:3.20 (no Go toolchain in the image).

lmata 2026-04-03 01:40 trunk
Commit a6305f89435bb45a3b42bffbc5be538d9107b5281775c4cb6d74babb12e97672
--- .github/workflows/release.yml
+++ .github/workflows/release.yml
@@ -5,47 +5,41 @@
55
tags:
66
- "v*"
77
88
permissions:
99
contents: write
10
+ packages: write
1011
1112
jobs:
1213
release:
1314
runs-on: ubuntu-latest
14
- strategy:
15
- matrix:
16
- include:
17
- - goos: linux
18
- goarch: amd64
19
- - goos: linux
20
- goarch: arm64
21
- - goos: darwin
22
- goarch: amd64
23
- - goos: darwin
24
- goarch: arm64
25
-
2615
steps:
2716
- uses: actions/checkout@v4
17
+ with:
18
+ fetch-depth: 0 # full history for changelog generation
2819
2920
- uses: actions/setup-go@v5
3021
with:
3122
go-version-file: go.mod
3223
cache: true
3324
34
- - name: Build binaries
35
- env:
36
- GOOS: ${{ matrix.goos }}
37
- GOARCH: ${{ matrix.goarch }}
38
- run: |
39
- SUFFIX="${{ matrix.goos }}-${{ matrix.goarch }}"
40
- LDFLAGS="-X main.version=${{ github.ref_name }}"
41
- mkdir -p dist
42
- go build -ldflags="${LDFLAGS}" -o "dist/scuttlebot-${SUFFIX}" ./cmd/scuttlebot
43
- go build -ldflags="${LDFLAGS}" -o "dist/scuttlectl-${SUFFIX}" ./cmd/scuttlectl
44
- go build -ldflags="${LDFLAGS}" -o "dist/claude-relay-${SUFFIX}" ./cmd/claude-relay
45
- go build -ldflags="${LDFLAGS}" -o "dist/codex-relay-${SUFFIX}" ./cmd/codex-relay
46
- go build -ldflags="${LDFLAGS}" -o "dist/gemini-relay-${SUFFIX}" ./cmd/gemini-relay
47
-
48
- - name: Upload to release
49
- uses: softprops/action-gh-release@v2
50
- with:
51
- files: dist/*
25
+ - name: Set up QEMU (multi-arch Docker builds)
26
+ uses: docker/setup-qemu-action@v3
27
+
28
+ - name: Set up Docker Buildx
29
+ uses: docker/setup-buildx-action@v3
30
+
31
+ - name: Log in to GHCR
32
+ uses: docker/login-action@v3
33
+ with:
34
+ registry: ghcr.io
35
+ username: ${{ github.actor }}
36
+ password: ${{ secrets.GITHUB_TOKEN }}
37
+
38
+ - name: Run GoReleaser
39
+ uses: goreleaser/goreleaser-action@v6
40
+ with:
41
+ distribution: goreleaser
42
+ version: "~> v2"
43
+ args: release --clean
44
+ env:
45
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5246
5347
ADDED .goreleaser.yaml
5448
ADDED deploy/docker/Dockerfile.release
--- .github/workflows/release.yml
+++ .github/workflows/release.yml
@@ -5,47 +5,41 @@
5 tags:
6 - "v*"
7
8 permissions:
9 contents: write
 
10
11 jobs:
12 release:
13 runs-on: ubuntu-latest
14 strategy:
15 matrix:
16 include:
17 - goos: linux
18 goarch: amd64
19 - goos: linux
20 goarch: arm64
21 - goos: darwin
22 goarch: amd64
23 - goos: darwin
24 goarch: arm64
25
26 steps:
27 - uses: actions/checkout@v4
 
 
28
29 - uses: actions/setup-go@v5
30 with:
31 go-version-file: go.mod
32 cache: true
33
34 - name: Build binaries
35 env:
36 GOOS: ${{ matrix.goos }}
37 GOARCH: ${{ matrix.goarch }}
38 run: |
39 SUFFIX="${{ matrix.goos }}-${{ matrix.goarch }}"
40 LDFLAGS="-X main.version=${{ github.ref_name }}"
41 mkdir -p dist
42 go build -ldflags="${LDFLAGS}" -o "dist/scuttlebot-${SUFFIX}" ./cmd/scuttlebot
43 go build -ldflags="${LDFLAGS}" -o "dist/scuttlectl-${SUFFIX}" ./cmd/scuttlectl
44 go build -ldflags="${LDFLAGS}" -o "dist/claude-relay-${SUFFIX}" ./cmd/claude-relay
45 go build -ldflags="${LDFLAGS}" -o "dist/codex-relay-${SUFFIX}" ./cmd/codex-relay
46 go build -ldflags="${LDFLAGS}" -o "dist/gemini-relay-${SUFFIX}" ./cmd/gemini-relay
47
48 - name: Upload to release
49 uses: softprops/action-gh-release@v2
50 with:
51 files: dist/*
 
 
 
52
53 DDED .goreleaser.yaml
54 DDED deploy/docker/Dockerfile.release
--- .github/workflows/release.yml
+++ .github/workflows/release.yml
@@ -5,47 +5,41 @@
5 tags:
6 - "v*"
7
8 permissions:
9 contents: write
10 packages: write
11
12 jobs:
13 release:
14 runs-on: ubuntu-latest
 
 
 
 
 
 
 
 
 
 
 
 
15 steps:
16 - uses: actions/checkout@v4
17 with:
18 fetch-depth: 0 # full history for changelog generation
19
20 - uses: actions/setup-go@v5
21 with:
22 go-version-file: go.mod
23 cache: true
24
25 - name: Set up QEMU (multi-arch Docker builds)
26 uses: docker/setup-qemu-action@v3
27
28 - name: Set up Docker Buildx
29 uses: docker/setup-buildx-action@v3
30
31 - name: Log in to GHCR
32 uses: docker/login-action@v3
33 with:
34 registry: ghcr.io
35 username: ${{ github.actor }}
36 password: ${{ secrets.GITHUB_TOKEN }}
37
38 - name: Run GoReleaser
39 uses: goreleaser/goreleaser-action@v6
40 with:
41 distribution: goreleaser
42 version: "~> v2"
43 args: release --clean
44 env:
45 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
46
47 DDED .goreleaser.yaml
48 DDED deploy/docker/Dockerfile.release
--- a/.goreleaser.yaml
+++ b/.goreleaser.yaml
@@ -0,0 +1,161 @@
1
+version: 2
2
+
3
+project_name: scuttlebot
4
+
5
+before:
6
+ hooks:
7
+ - go mod tidy
8
+
9
+builds:
10
+ - id: scuttlebot
11
+ main: ./cmd/scuttlebot
12
+ binary: scuttlebot
13
+ env: [CGO_ENABLED=0]
14
+ goos: [linux, darwin, windows]
15
+ goarch: [amd64, arm64]
16
+ ignore:
17
+ - goos: windows
18
+ goarch: arm64
19
+ ldflags: ["-s -w -X main.version={{.Version}}"]
20
+
21
+ - id: scuttlectl
22
+ main: ./cmd/scuttlectl
23
+ binary: scuttlectl
24
+ env: [CGO_ENABLED=0]
25
+ goos: [linux, darwin, windows]
26
+ goarch: [amd64, arm64]
27
+ ignore:
28
+ - goos: windows
29
+ goarch: arm64
30
+ ldflags: ["-s -w -X main.version={{.Version}}"]
31
+
32
+ # Relays only ship for unix — agents run on dev machines, not Windows servers.
33
+ - id: claude-relay
34
+ main: ./cmd/claude-relay
35
+ binary: claude-relay
36
+ env: [CGO_ENABLED=0]
37
+ goos: [linux, darwin]
38
+ goarch: [amd64, arm64]
39
+ ldflags: ["-s -w -X main.version={{.Version}}"]
40
+
41
+ - id: codex-relay
42
+ main: ./cmd/codex-relay
43
+ binary: codex-relay
44
+ env: [CGO_ENABLED=0]
45
+ goos: [linux, darwin]
46
+ goarch: [amd64, arm64]
47
+ ldflags: ["-s -w -X main.version={{.Version}}"]
48
+
49
+ - id: gemini-relay
50
+ main: ./cmd/gemini-relay
51
+ binary: gemini-relay
52
+ env: [CGO_ENABLED=0]
53
+ goos: [linux, darwin]
54
+ goarch: [amd64, arm64]
55
+ ldflags: ["-s -w -X main.version={{.Version}}"]
56
+
57
+packaged together — .
58
+ - id: server
59
+ ids: [scuttlebot, scuttlectl]
60
+ name_template: "scuttlebot_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
61
+ format_overrides:
62
+ - goos: windows
63
+ formats: [zip]
64
+ files:
65
+ - LICENSE
66
+ - README.md
67
+ - deploy/standalone/scuttlebot.yaml.example
68
+
69
+ # Relay binaries — archive for developer machines.
70
+ - id: relays
71
+ ids: [claude-relay, codex-relay, gemini-relay]
72
+ name_template: "scuttlebot-relays_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
73
+ files:
74
+ - LICENSE
75
+
76
+ # Flat binaries — raw executables for curl-and-run installs.
77
+ # Named: scuttlebot_linux_amd64, claude-relay_darwin_arm64, etc.
78
+ - id: binaries
79
+ format: binary
80
+ name_template: "{{ .Binary }}_{{ .Os }}_{{ .Arch }}"
81
+
82
+checksum:
83
+ name_template: "checksums.txt"
84
+ algorithm: sha256
85
+
86
+changelog:
87
+ sort: asc
88
+ use: github
89
+ filters:
90
+ exclude:
91
+ - "^Merge"
92
+ groups:
93
+ - title: Features
94
+ regexp: "^feat"
95
+ order: 0
96
+ - title: Bug fixes
97
+ regexp: "^fix"
98
+ order: 1
99
+ - title: Security
100
+ regexp: "^security"
101
+ order: 2
102
+ - title: Documentation
103
+ regexp: "^docs"
104
+ order: 3
105
+ - title: Other
106
+ order: 99
107
+
108
+dockers:
109
+ - id: scuttlebot-amd64
110
+ ids: [scuttlebot]
111
+ image_templates:
112
+ - "ghcr.io/conflicthq/scuttlebot:{{ .Tag }}-amd64"
113
+ dockerfile: deploy/docker/Dockerfile.release
114
+ use: buildx
115
+ build_flag_templates:
116
+ - "--platform=linux/amd64"
117
+ - "--label=org.opencontainers.image.title=scuttlebot"
118
+ - "--label=org.opencontainers.image.version={{ .Version }}"
119
+ - "--label=org.opencontainers.image.source=https://github.com/ConflictHQ/scuttlebot"
120
+
121
+ - id: scuttlebot-arm64
122
+ ids: [scuttlebot]
123
+ image_templates:
124
+ - "ghcr.io/conflicthq/scuttlebot:{{ .Tag }}-arm64"
125
+ dockerfile: deploy/docker/Dockerfile.release
126
+ use: buildx
127
+ build_flag_templates:
128
+ - "--platform=linux/arm64"
129
+ - "--label=org.opencontainers.image.title=scuttlebot"
130
+ - "--label=org.opencontainers.image.version={{ .Version }}"
131
+ - "--label=org.opencontainers.image.source=https://github.com/ConflictHQ/scuttlebot"
132
+ goarch: arm64
133
+
134
+docker_manifests:
135
+ - name_template: "ghcr.io/conflicthq/scuttlebot:{{ .Tag }}"
136
+ image_templates:
137
+ - "ghcr.io/conflicthq/scuttlebot:{{ .Tag }}-amd64"
138
+ - "ghcr.io/conflicthq/scuttlebot:{{ .Tag }}-arm64"
139
+ - name_template: "ghcr.io/conflicthq/scuttlebot:latest"
140
+ image_templates:
141
+ - "ghcr.io/conflicthq/scuttlebot:{{ .Tag }}-amd64"
142
+ - "ghcr.io/conflicthq/scuttlebot:{{ .Tag }}-arm64"
143
+
144
+release:
145
+ github:
146
+ owner: ConflictHQ
147
+ name: scuttlebot
148
+ draft: false
149
+ prerelease: auto
150
+ header: |
151
+ ## scuttlebot {{ .Tag }}
152
+
153
+ Run a fleet of AI agents. Watch them work. Talk to them directly.
154
+
155
+ **[Documentation →](https://scuttlebot.dev)**
156
+
157
+ ### Install
158
+
159
+ ```bash
160
+ # macOS / Linux — daemon + CLI
161
+ curl -sSL https://github.com/ConflictHQ/scuttlebot/releases/download/{{ .Tag }}/scuttlebot_{{ .Version }}_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed s/x86_64/amd6
--- a/.goreleaser.yaml
+++ b/.goreleaser.yaml
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/.goreleaser.yaml
+++ b/.goreleaser.yaml
@@ -0,0 +1,161 @@
1 version: 2
2
3 project_name: scuttlebot
4
5 before:
6 hooks:
7 - go mod tidy
8
9 builds:
10 - id: scuttlebot
11 main: ./cmd/scuttlebot
12 binary: scuttlebot
13 env: [CGO_ENABLED=0]
14 goos: [linux, darwin, windows]
15 goarch: [amd64, arm64]
16 ignore:
17 - goos: windows
18 goarch: arm64
19 ldflags: ["-s -w -X main.version={{.Version}}"]
20
21 - id: scuttlectl
22 main: ./cmd/scuttlectl
23 binary: scuttlectl
24 env: [CGO_ENABLED=0]
25 goos: [linux, darwin, windows]
26 goarch: [amd64, arm64]
27 ignore:
28 - goos: windows
29 goarch: arm64
30 ldflags: ["-s -w -X main.version={{.Version}}"]
31
32 # Relays only ship for unix — agents run on dev machines, not Windows servers.
33 - id: claude-relay
34 main: ./cmd/claude-relay
35 binary: claude-relay
36 env: [CGO_ENABLED=0]
37 goos: [linux, darwin]
38 goarch: [amd64, arm64]
39 ldflags: ["-s -w -X main.version={{.Version}}"]
40
41 - id: codex-relay
42 main: ./cmd/codex-relay
43 binary: codex-relay
44 env: [CGO_ENABLED=0]
45 goos: [linux, darwin]
46 goarch: [amd64, arm64]
47 ldflags: ["-s -w -X main.version={{.Version}}"]
48
49 - id: gemini-relay
50 main: ./cmd/gemini-relay
51 binary: gemini-relay
52 env: [CGO_ENABLED=0]
53 goos: [linux, darwin]
54 goarch: [amd64, arm64]
55 ldflags: ["-s -w -X main.version={{.Version}}"]
56
57 packaged together — .
58 - id: server
59 ids: [scuttlebot, scuttlectl]
60 name_template: "scuttlebot_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
61 format_overrides:
62 - goos: windows
63 formats: [zip]
64 files:
65 - LICENSE
66 - README.md
67 - deploy/standalone/scuttlebot.yaml.example
68
69 # Relay binaries — archive for developer machines.
70 - id: relays
71 ids: [claude-relay, codex-relay, gemini-relay]
72 name_template: "scuttlebot-relays_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
73 files:
74 - LICENSE
75
76 # Flat binaries — raw executables for curl-and-run installs.
77 # Named: scuttlebot_linux_amd64, claude-relay_darwin_arm64, etc.
78 - id: binaries
79 format: binary
80 name_template: "{{ .Binary }}_{{ .Os }}_{{ .Arch }}"
81
82 checksum:
83 name_template: "checksums.txt"
84 algorithm: sha256
85
86 changelog:
87 sort: asc
88 use: github
89 filters:
90 exclude:
91 - "^Merge"
92 groups:
93 - title: Features
94 regexp: "^feat"
95 order: 0
96 - title: Bug fixes
97 regexp: "^fix"
98 order: 1
99 - title: Security
100 regexp: "^security"
101 order: 2
102 - title: Documentation
103 regexp: "^docs"
104 order: 3
105 - title: Other
106 order: 99
107
108 dockers:
109 - id: scuttlebot-amd64
110 ids: [scuttlebot]
111 image_templates:
112 - "ghcr.io/conflicthq/scuttlebot:{{ .Tag }}-amd64"
113 dockerfile: deploy/docker/Dockerfile.release
114 use: buildx
115 build_flag_templates:
116 - "--platform=linux/amd64"
117 - "--label=org.opencontainers.image.title=scuttlebot"
118 - "--label=org.opencontainers.image.version={{ .Version }}"
119 - "--label=org.opencontainers.image.source=https://github.com/ConflictHQ/scuttlebot"
120
121 - id: scuttlebot-arm64
122 ids: [scuttlebot]
123 image_templates:
124 - "ghcr.io/conflicthq/scuttlebot:{{ .Tag }}-arm64"
125 dockerfile: deploy/docker/Dockerfile.release
126 use: buildx
127 build_flag_templates:
128 - "--platform=linux/arm64"
129 - "--label=org.opencontainers.image.title=scuttlebot"
130 - "--label=org.opencontainers.image.version={{ .Version }}"
131 - "--label=org.opencontainers.image.source=https://github.com/ConflictHQ/scuttlebot"
132 goarch: arm64
133
134 docker_manifests:
135 - name_template: "ghcr.io/conflicthq/scuttlebot:{{ .Tag }}"
136 image_templates:
137 - "ghcr.io/conflicthq/scuttlebot:{{ .Tag }}-amd64"
138 - "ghcr.io/conflicthq/scuttlebot:{{ .Tag }}-arm64"
139 - name_template: "ghcr.io/conflicthq/scuttlebot:latest"
140 image_templates:
141 - "ghcr.io/conflicthq/scuttlebot:{{ .Tag }}-amd64"
142 - "ghcr.io/conflicthq/scuttlebot:{{ .Tag }}-arm64"
143
144 release:
145 github:
146 owner: ConflictHQ
147 name: scuttlebot
148 draft: false
149 prerelease: auto
150 header: |
151 ## scuttlebot {{ .Tag }}
152
153 Run a fleet of AI agents. Watch them work. Talk to them directly.
154
155 **[Documentation →](https://scuttlebot.dev)**
156
157 ### Install
158
159 ```bash
160 # macOS / Linux — daemon + CLI
161 curl -sSL https://github.com/ConflictHQ/scuttlebot/releases/download/{{ .Tag }}/scuttlebot_{{ .Version }}_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed s/x86_64/amd6
--- a/deploy/docker/Dockerfile.release
+++ b/deploy/docker/Dockerfile.release
@@ -0,0 +1,8 @@
1
+FROM alpine:3.20
2
+RUN apk add --no-cache ca-certificates tzdata
3
+COPY scuttlebot /usr/local/bin/scuttlebot
4
+ENV SCUTTLEBOT_API_ADDR=:8080
5
+ENV SCUTTLEBOT_MCP_ADDR=:8081
6
+EXPOSE 8080
7
+EXPOSE 8081
8
+ENTRYPOINT ["scuttlebot"]
--- a/deploy/docker/Dockerfile.release
+++ b/deploy/docker/Dockerfile.release
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
--- a/deploy/docker/Dockerfile.release
+++ b/deploy/docker/Dockerfile.release
@@ -0,0 +1,8 @@
1 FROM alpine:3.20
2 RUN apk add --no-cache ca-certificates tzdata
3 COPY scuttlebot /usr/local/bin/scuttlebot
4 ENV SCUTTLEBOT_API_ADDR=:8080
5 ENV SCUTTLEBOT_MCP_ADDR=:8081
6 EXPOSE 8080
7 EXPOSE 8081
8 ENTRYPOINT ["scuttlebot"]

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button