A container registry that uses the AT Protocol for manifest storage and S3 for blob storage.
atcr.io
docker
container
atproto
go
1#!/usr/bin/env bash
2#
3# update-homebrew-formula.sh - Update Homebrew formula after a GoReleaser release
4#
5# Usage: ./scripts/update-homebrew-formula.sh <version> [--push]
6#
7# Example: ./scripts/update-homebrew-formula.sh v0.0.2
8# ./scripts/update-homebrew-formula.sh v0.0.2 --push
9#
10# This script:
11# 1. Downloads pre-built archives from Tangled for each platform
12# 2. Computes SHA256 checksums
13# 3. Generates the updated formula
14# 4. Optionally clones the homebrew-tap repo, commits, and pushes
15#
16# If GoReleaser dist/ directory exists locally, checksums are read from there instead.
17#
18
19set -euo pipefail
20
21RED='\033[0;31m'
22GREEN='\033[0;32m'
23YELLOW='\033[1;33m'
24NC='\033[0m'
25
26TANGLED_REPO="https://tangled.org/evan.jarrett.net/at-container-registry"
27TAP_REPO="https://tangled.org/evan.jarrett.net/homebrew-tap"
28BINARY_NAME="docker-credential-atcr"
29FORMULA_PATH="Formula/docker-credential-atcr.rb"
30
31PLATFORMS=(
32 "Darwin_arm64"
33 "Darwin_x86_64"
34 "Linux_arm64"
35 "Linux_x86_64"
36)
37
38if [ $# -lt 1 ]; then
39 echo -e "${RED}Error: Missing required argument${NC}"
40 echo "Usage: $0 <version> [--push]"
41 echo ""
42 echo "Example: $0 v0.0.2"
43 echo " $0 v0.0.2 --push"
44 exit 1
45fi
46
47VERSION="$1"
48PUSH=false
49if [ "${2:-}" = "--push" ]; then
50 PUSH=true
51fi
52
53# Add 'v' prefix if not present
54if [[ ! "$VERSION" =~ ^v ]]; then
55 VERSION="v${VERSION}"
56fi
57VERSION_NO_V="${VERSION#v}"
58
59echo -e "${GREEN}Updating Homebrew formula for ${VERSION}${NC}"
60echo ""
61
62TEMP_DIR=$(mktemp -d)
63trap 'rm -rf "$TEMP_DIR"' EXIT
64
65# Compute SHA256 for each platform archive
66declare -A CHECKSUMS
67
68sha256_of_file() {
69 if command -v sha256sum &> /dev/null; then
70 sha256sum "$1" | awk '{print $1}'
71 elif command -v shasum &> /dev/null; then
72 shasum -a 256 "$1" | awk '{print $1}'
73 else
74 echo -e "${RED}Error: sha256sum or shasum not found${NC}" >&2
75 exit 1
76 fi
77}
78
79# Check if GoReleaser dist/ has the archives locally
80GORELEASER_DIST="dist"
81if [ -f "${GORELEASER_DIST}/checksums.txt" ]; then
82 echo -e "${YELLOW}Using local GoReleaser dist/ for checksums${NC}"
83 for platform in "${PLATFORMS[@]}"; do
84 archive="${BINARY_NAME}_${VERSION_NO_V}_${platform}.tar.gz"
85 checksum=$(grep "${archive}" "${GORELEASER_DIST}/checksums.txt" | awk '{print $1}')
86 if [ -z "$checksum" ]; then
87 echo -e "${RED}Missing checksum for ${archive} in dist/checksums.txt${NC}"
88 exit 1
89 fi
90 CHECKSUMS[$platform]="$checksum"
91 echo -e " ${GREEN}✓${NC} ${platform}: ${checksum}"
92 done
93else
94 echo -e "${YELLOW}Downloading archives from Tangled to compute checksums...${NC}"
95 for platform in "${PLATFORMS[@]}"; do
96 archive="${BINARY_NAME}_${VERSION_NO_V}_${platform}.tar.gz"
97 url="${TANGLED_REPO}/tags/${VERSION}/download/${archive}"
98 dest="${TEMP_DIR}/${archive}"
99
100 echo -n " ${platform}... "
101 if curl -sSfL -o "$dest" "$url"; then
102 CHECKSUMS[$platform]=$(sha256_of_file "$dest")
103 echo -e "${GREEN}✓${NC} ${CHECKSUMS[$platform]}"
104 else
105 echo -e "${RED}✗ Failed to download${NC}"
106 echo " URL: ${url}"
107 exit 1
108 fi
109 done
110fi
111
112echo ""
113
114# Generate the formula
115FORMULA=$(cat <<RUBY
116# typed: false
117# frozen_string_literal: true
118
119class DockerCredentialAtcr < Formula
120 desc "Docker credential helper for ATCR (ATProto Container Registry)"
121 homepage "https://atcr.io"
122 version "${VERSION_NO_V}"
123 license "MIT"
124
125 on_macos do
126 on_arm do
127 url "${TANGLED_REPO}/tags/${VERSION}/download/${BINARY_NAME}_${VERSION_NO_V}_Darwin_arm64.tar.gz"
128 sha256 "${CHECKSUMS[Darwin_arm64]}"
129 end
130 on_intel do
131 url "${TANGLED_REPO}/tags/${VERSION}/download/${BINARY_NAME}_${VERSION_NO_V}_Darwin_x86_64.tar.gz"
132 sha256 "${CHECKSUMS[Darwin_x86_64]}"
133 end
134 end
135
136 on_linux do
137 on_arm do
138 url "${TANGLED_REPO}/tags/${VERSION}/download/${BINARY_NAME}_${VERSION_NO_V}_Linux_arm64.tar.gz"
139 sha256 "${CHECKSUMS[Linux_arm64]}"
140 end
141 on_intel do
142 url "${TANGLED_REPO}/tags/${VERSION}/download/${BINARY_NAME}_${VERSION_NO_V}_Linux_x86_64.tar.gz"
143 sha256 "${CHECKSUMS[Linux_x86_64]}"
144 end
145 end
146
147 def install
148 bin.install "docker-credential-atcr"
149 end
150
151 test do
152 assert_match version.to_s, shell_output("#{bin}/docker-credential-atcr version 2>&1")
153 end
154
155 def caveats
156 <<~EOS
157 To configure Docker to use ATCR credential helper, add the following
158 to your ~/.docker/config.json:
159
160 {
161 "credHelpers": {
162 "atcr.io": "atcr"
163 }
164 }
165
166 Or run: docker-credential-atcr configure-docker
167
168 To authenticate with ATCR:
169 docker push atcr.io/<your-handle>/<image>:latest
170
171 Configuration is stored in: ~/.atcr/config.json
172 EOS
173 end
174end
175RUBY
176)
177
178# Write to local formula
179echo "$FORMULA" > "${FORMULA_PATH}"
180echo -e "${GREEN}✓ Updated ${FORMULA_PATH}${NC}"
181
182if [ "$PUSH" = true ]; then
183 echo ""
184 echo -e "${YELLOW}Pushing to homebrew-tap repo...${NC}"
185
186 TAP_DIR="${TEMP_DIR}/homebrew-tap"
187 git clone "$TAP_REPO" "$TAP_DIR" 2>/dev/null || {
188 echo -e "${YELLOW}Tap repo not found, initializing new repo${NC}"
189 mkdir -p "$TAP_DIR"
190 cd "$TAP_DIR"
191 git init
192 git remote add origin "$TAP_REPO"
193 }
194
195 mkdir -p "${TAP_DIR}/Formula"
196 cp "${FORMULA_PATH}" "${TAP_DIR}/Formula/"
197
198 cd "$TAP_DIR"
199 git add Formula/docker-credential-atcr.rb
200 git commit -m "Update docker-credential-atcr to ${VERSION}"
201 git push origin HEAD
202
203 echo -e "${GREEN}✓ Pushed to ${TAP_REPO}${NC}"
204else
205 echo ""
206 echo -e "${YELLOW}Next steps:${NC}"
207 echo "1. Review the formula: ${FORMULA_PATH}"
208 echo "2. Push to your homebrew-tap repo on Tangled:"
209 echo " cd /path/to/homebrew-tap"
210 echo " cp ${FORMULA_PATH} Formula/"
211 echo " git add Formula/ && git commit -m 'Update to ${VERSION}' && git push"
212 echo ""
213 echo "Or re-run with --push to do this automatically:"
214 echo " $0 ${VERSION} --push"
215fi
216
217echo ""
218echo -e "${GREEN}Users can install/upgrade with:${NC}"
219echo " brew tap atcr/tap ${TAP_REPO}"
220echo " brew install docker-credential-atcr"
221echo " brew upgrade docker-credential-atcr"