···11+# Tangled Workflow: Release Credential Helper to Tangled.org
22+#
33+# This workflow builds the docker-credential-atcr binary and publishes it
44+# to Tangled.org for distribution via Homebrew.
55+#
66+# Current limitation: Tangled doesn't support triggering on tags yet,
77+# so this triggers on push to main. Manually verify you've tagged the
88+# release before pushing.
99+1010+when:
1111+ - event: ["manual"]
1212+ branch: ["main"]
1313+1414+engine: "nixery"
1515+1616+dependencies:
1717+ nixpkgs:
1818+ - go_1_24 # Go 1.24+ for building
1919+ - git # For finding tags
2020+ - goreleaser # For building multi-platform binaries
2121+ # - goat # TODO: Add goat CLI for uploading to Tangled (if available in nixpkgs)
2222+2323+environment:
2424+ CGO_ENABLED: "0" # Build static binaries
2525+2626+steps:
2727+ - name: Find latest git tag
2828+ command: |
2929+ # Get the most recent version tag
3030+ LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.1")
3131+ echo "Latest tag: $LATEST_TAG"
3232+ echo "$LATEST_TAG" > .version
3333+3434+ # Also get the commit hash for reference
3535+ COMMIT_HASH=$(git rev-parse HEAD)
3636+ echo "Commit: $COMMIT_HASH"
3737+3838+ - name: Build binaries with GoReleaser
3939+ command: |
4040+ # Read version from previous step
4141+ VERSION=$(cat .version)
4242+ export VERSION
4343+4444+ # Build for all platforms using GoReleaser
4545+ # This creates artifacts in dist/ directory
4646+ goreleaser build --clean --snapshot --config .goreleaser.yaml
4747+4848+ # List what was built
4949+ echo "Built artifacts:"
5050+ ls -lh dist/
5151+5252+ - name: Package artifacts
5353+ command: |
5454+ VERSION=$(cat .version)
5555+ VERSION_NO_V=${VERSION#v} # Remove 'v' prefix for filenames
5656+5757+ cd dist
5858+5959+ # Create tarballs for each platform (GoReleaser might already do this)
6060+ # Darwin x86_64
6161+ if [ -d "docker-credential-atcr_darwin_amd64_v1" ]; then
6262+ tar czf "docker-credential-atcr_${VERSION_NO_V}_Darwin_x86_64.tar.gz" \
6363+ -C docker-credential-atcr_darwin_amd64_v1 docker-credential-atcr
6464+ fi
6565+6666+ # Darwin arm64
6767+ if [ -d "docker-credential-atcr_darwin_arm64" ]; then
6868+ tar czf "docker-credential-atcr_${VERSION_NO_V}_Darwin_arm64.tar.gz" \
6969+ -C docker-credential-atcr_darwin_arm64 docker-credential-atcr
7070+ fi
7171+7272+ # Linux x86_64
7373+ if [ -d "docker-credential-atcr_linux_amd64_v1" ]; then
7474+ tar czf "docker-credential-atcr_${VERSION_NO_V}_Linux_x86_64.tar.gz" \
7575+ -C docker-credential-atcr_linux_amd64_v1 docker-credential-atcr
7676+ fi
7777+7878+ # Linux arm64
7979+ if [ -d "docker-credential-atcr_linux_arm64" ]; then
8080+ tar czf "docker-credential-atcr_${VERSION_NO_V}_Linux_arm64.tar.gz" \
8181+ -C docker-credential-atcr_linux_arm64 docker-credential-atcr
8282+ fi
8383+8484+ echo "Created tarballs:"
8585+ ls -lh *.tar.gz
8686+8787+ - name: Upload to Tangled.org
8888+ command: |
8989+ VERSION=$(cat .version)
9090+ VERSION_NO_V=${VERSION#v}
9191+9292+ # TODO: Authenticate with goat CLI
9393+ # You'll need to set up credentials/tokens for goat
9494+ # Example (adjust based on goat's actual auth mechanism):
9595+ # goat login --pds https://your-pds.example.com --handle your.handle
9696+9797+ # TODO: Upload each artifact to Tangled.org
9898+ # This creates sh.tangled.repo.artifact records in your ATProto PDS
9999+ # Adjust these commands based on scripts/publish-artifact.sh pattern
100100+101101+ # Example structure (you'll need to fill in actual goat commands):
102102+ # for artifact in dist/*.tar.gz; do
103103+ # echo "Uploading $artifact..."
104104+ # goat upload \
105105+ # --repo "at-container-registry" \
106106+ # --tag "$VERSION" \
107107+ # --file "$artifact"
108108+ # done
109109+110110+ echo "TODO: Implement goat upload commands"
111111+ echo "See scripts/publish-artifact.sh for reference"
112112+ echo ""
113113+ echo "After uploading, you'll receive a TAG_HASH from Tangled."
114114+ echo "Update Formula/docker-credential-atcr.rb with:"
115115+ echo " VERSION = \"$VERSION_NO_V\""
116116+ echo " TAG_HASH = \"<hash-from-tangled>\""
117117+ echo ""
118118+ echo "Then run: scripts/update-homebrew-formula.sh $VERSION_NO_V <tag-hash>"
119119+120120+ - name: Generate checksums for verification
121121+ command: |
122122+ VERSION=$(cat .version)
123123+ VERSION_NO_V=${VERSION#v}
124124+125125+ cd dist
126126+127127+ echo "SHA256 checksums for Homebrew formula:"
128128+ echo "======================================="
129129+130130+ for file in docker-credential-atcr_${VERSION_NO_V}_*.tar.gz; do
131131+ if [ -f "$file" ]; then
132132+ sha256sum "$file"
133133+ fi
134134+ done
135135+136136+ echo ""
137137+ echo "Copy these checksums to Formula/docker-credential-atcr.rb"
+54
Formula/docker-credential-atcr.rb
···11+# typed: false
22+# frozen_string_literal: true
33+44+class DockerCredentialAtcr < Formula
55+ desc "Docker credential helper for ATCR (ATProto Container Registry)"
66+ homepage "https://atcr.io"
77+ url "https://github.com/atcr-io/atcr/archive/refs/tags/v0.0.1.tar.gz"
88+ sha256 "REPLACE_WITH_TARBALL_SHA256"
99+ license "MIT"
1010+ head "https://github.com/atcr-io/atcr.git", branch: "main"
1111+1212+ depends_on "go" => :build
1313+1414+ def install
1515+ # Build the credential helper binary
1616+ # Use ldflags to inject version information
1717+ ldflags = %W[
1818+ -s -w
1919+ -X main.version=#{version}
2020+ -X main.commit=#{tap.user}
2121+ -X main.date=#{time.iso8601}
2222+ ]
2323+2424+ system "go", "build", *std_go_args(ldflags:, output: bin/"docker-credential-atcr"), "./cmd/credential-helper"
2525+ end
2626+2727+ test do
2828+ # Test that the binary exists and is executable
2929+ assert_match version.to_s, shell_output("#{bin}/docker-credential-atcr version 2>&1")
3030+ end
3131+3232+ def caveats
3333+ <<~EOS
3434+ To configure Docker to use ATCR credential helper, add the following
3535+ to your ~/.docker/config.json:
3636+3737+ {
3838+ "credHelpers": {
3939+ "atcr.io": "atcr"
4040+ }
4141+ }
4242+4343+ Note: The credential helper name is "atcr" (Docker automatically prefixes
4444+ with "docker-credential-" when looking for the binary).
4545+4646+ To authenticate with ATCR:
4747+ docker push atcr.io/<your-handle>/<image>:latest
4848+4949+ This will open your browser to complete the OAuth device flow.
5050+5151+ Configuration is stored in: ~/.atcr/device.json
5252+ EOS
5353+ end
5454+end
+11-2
INSTALLATION.md
···3737.\install.ps1
3838```
39394040-### Using Homebrew (macOS)
4141-You can read the full manifest spec here, but the dependencies block is the real interesting bit. Dependencies for your workflow, like Go, Node.js, Python etc. can be pulled in from nixpkgs. Nixpkgs—for the uninitiated—is a vast collection of packages for the Nix package manager. Fortunately, you needn’t know nor care about Nix to use it! Just head to https://search.nixos.org to find your package of choice (I’ll bet 1€ that it’s there1), toss it in the list and run your build. The Nix-savvy of you lot will be happy to know that you can use custom registries too.
4040+### Using Homebrew (macOS and Linux)
4141+4242```bash
4343+# Add the ATCR tap
4344brew tap atcr-io/tap
4545+4646+# Install the credential helper
4447brew install docker-credential-atcr
4548```
4949+5050+The Homebrew formula supports:
5151+- **macOS**: Intel (x86_64) and Apple Silicon (arm64)
5252+- **Linux**: x86_64 and arm64
5353+5454+Homebrew will automatically download the correct binary for your platform.
46554756### Manual Installation
4857