Release 0.3.10 (#1488) #16
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release CLI Binaries | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'Version tag (e.g., v0.2.0)' | |
| required: true | |
| type: string | |
| concurrency: | |
| group: release-${{ github.ref }} | |
| cancel-in-progress: false | |
| jobs: | |
| build: | |
| strategy: | |
| matrix: | |
| include: | |
| - os: ubuntu-latest | |
| target: bun-linux-x64 | |
| binary: archon-linux-x64 | |
| - os: ubuntu-latest | |
| target: bun-linux-arm64 | |
| binary: archon-linux-arm64 | |
| - os: ubuntu-latest | |
| target: bun-windows-x64 | |
| binary: archon-windows-x64.exe | |
| - os: macos-latest | |
| target: bun-darwin-x64 | |
| binary: archon-darwin-x64 | |
| - os: macos-latest | |
| target: bun-darwin-arm64 | |
| binary: archon-darwin-arm64 | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: 1.3.11 | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Build binary | |
| env: | |
| # On workflow_dispatch, github.ref_name is the branch name (e.g. 'main'), | |
| # not the version tag — fall back to the user-supplied `version` input. | |
| VERSION: ${{ github.event_name == 'workflow_dispatch' && inputs.version || github.ref_name }} | |
| GIT_COMMIT: ${{ github.sha }} | |
| TARGET: ${{ matrix.target }} | |
| OUTFILE: dist/${{ matrix.binary }} | |
| run: | | |
| # Strip 'v' prefix from tag (e.g. v0.3.1 → 0.3.1) | |
| VERSION="${VERSION#v}" | |
| # Short commit (first 8 chars of SHA) | |
| GIT_COMMIT="${GIT_COMMIT::8}" | |
| mkdir -p dist | |
| VERSION="$VERSION" GIT_COMMIT="$GIT_COMMIT" TARGET="$TARGET" OUTFILE="$OUTFILE" bash scripts/build-binaries.sh | |
| - name: Smoke-test built binary | |
| if: matrix.target == 'bun-linux-x64' && runner.os == 'Linux' | |
| env: | |
| RAW_VERSION: ${{ github.event_name == 'workflow_dispatch' && inputs.version || github.ref_name }} | |
| run: | | |
| chmod +x dist/${{ matrix.binary }} | |
| if ! VERSION_OUTPUT=$(./dist/${{ matrix.binary }} version 2>&1); then | |
| echo "::error::Binary failed to execute" | |
| echo "$VERSION_OUTPUT" | |
| exit 1 | |
| fi | |
| echo "$VERSION_OUTPUT" | |
| # Must not error with "Failed to read version" or similar | |
| if echo "$VERSION_OUTPUT" | grep -qE "Failed to read version|package\.json not found|bad installation"; then | |
| echo "::error::Binary is broken — version command cannot read embedded version" | |
| echo "::error::This means BUNDLED_IS_BINARY was not set to true at build time." | |
| exit 1 | |
| fi | |
| # Must report 'Build: binary', not 'Build: source' | |
| if ! echo "$VERSION_OUTPUT" | grep -q "Build: binary"; then | |
| echo "::error::Binary reports wrong build type" | |
| echo "::error::Expected 'Build: binary' in version output" | |
| exit 1 | |
| fi | |
| # Must report the (stripped) tag version. Compare against the same | |
| # value that was baked into the binary (VERSION#v), not the raw ref, | |
| # so the check doesn't rely on the CLI re-adding a 'v' prefix. | |
| EXPECTED_VERSION="${RAW_VERSION#v}" | |
| if echo "$VERSION_OUTPUT" | grep -qE "v?${EXPECTED_VERSION}(\s|$)"; then | |
| echo "::notice::Binary correctly reports version ${EXPECTED_VERSION}" | |
| else | |
| echo "::error::Binary does not report version ${EXPECTED_VERSION}" | |
| exit 1 | |
| fi | |
| - name: Smoke-test bundled defaults load | |
| if: matrix.target == 'bun-linux-x64' && runner.os == 'Linux' | |
| run: | | |
| # `workflow list` requires running from a git repo | |
| BIN="$PWD/dist/${{ matrix.binary }}" | |
| TMP_REPO=$(mktemp -d) | |
| cd "$TMP_REPO" | |
| git init -q | |
| git -c user.email=ci@example.com -c user.name=ci commit --allow-empty -q -m init | |
| if ! OUTPUT=$("$BIN" workflow list 2>&1); then | |
| echo "::error::workflow list failed to execute" | |
| echo "$OUTPUT" | |
| exit 1 | |
| fi | |
| echo "$OUTPUT" | |
| if echo "$OUTPUT" | grep -q "archon-assist"; then | |
| echo "::notice::Bundled workflows loaded correctly" | |
| else | |
| echo "::error::Bundled workflows did not load — embedded JSON may be missing from the binary" | |
| exit 1 | |
| fi | |
| - name: Smoke-test Claude binary-path resolver (negative case) | |
| if: matrix.target == 'bun-linux-x64' && runner.os == 'Linux' | |
| run: | | |
| # With no CLAUDE_BIN_PATH and no config, running a Claude workflow must | |
| # fail with a clear, user-facing error — NOT with "Module not found | |
| # /Users/runner/..." which would indicate the resolver was bypassed. | |
| BIN="$PWD/dist/${{ matrix.binary }}" | |
| TMP_REPO=$(mktemp -d) | |
| cd "$TMP_REPO" | |
| git init -q | |
| git -c user.email=ci@example.com -c user.name=ci commit --allow-empty -q -m init | |
| # Run without CLAUDE_BIN_PATH set. Expect a clean resolver error. | |
| # Capture both stdout and stderr; we only care that the resolver message is present. | |
| # --no-worktree skips isolation: this test exercises the Claude resolver | |
| # path, not worktree setup. Without it we hit the worktree auto-sync added | |
| # in #1310 first and fail on "neither origin/HEAD nor origin/main exist" | |
| # because the fresh `git init` tmp repo has no origin configured. | |
| set +e | |
| OUTPUT=$(env -u CLAUDE_BIN_PATH "$BIN" workflow run archon-assist --no-worktree "hello" 2>&1) | |
| EXIT_CODE=$? | |
| set -e | |
| echo "$OUTPUT" | |
| if echo "$OUTPUT" | grep -qE 'Module not found.*Users/runner'; then | |
| echo "::error::Resolver was bypassed — SDK hit the import.meta.url fallback (regression of #1210)" | |
| exit 1 | |
| fi | |
| if ! echo "$OUTPUT" | grep -q "Claude Code not found"; then | |
| echo "::error::Expected 'Claude Code not found' error when CLAUDE_BIN_PATH is unset" | |
| exit 1 | |
| fi | |
| if ! echo "$OUTPUT" | grep -q "CLAUDE_BIN_PATH"; then | |
| echo "::error::Error message does not reference CLAUDE_BIN_PATH remediation" | |
| exit 1 | |
| fi | |
| echo "::notice::Resolver error path works (exit code: $EXIT_CODE)" | |
| - name: Smoke-test Claude subprocess spawn (positive case) | |
| if: matrix.target == 'bun-linux-x64' && runner.os == 'Linux' | |
| run: | | |
| # Install Claude Code via the native installer (Anthropic's recommended | |
| # default) and run a workflow with CLAUDE_BIN_PATH set. The subprocess | |
| # must spawn cleanly. We do NOT require the query to succeed (no auth | |
| # in CI — an auth error is fine and expected); we only fail if the SDK | |
| # can't find the executable, which would indicate a resolver regression. | |
| curl -fsSL https://claude.ai/install.sh | bash | |
| CLI_PATH="$HOME/.local/bin/claude" | |
| if [ ! -x "$CLI_PATH" ]; then | |
| echo "::error::Claude Code binary not found after curl install at $CLI_PATH" | |
| ls -la "$HOME/.local/bin/" || true | |
| exit 1 | |
| fi | |
| echo "Using CLAUDE_BIN_PATH=$CLI_PATH" | |
| BIN="$PWD/dist/${{ matrix.binary }}" | |
| TMP_REPO=$(mktemp -d) | |
| cd "$TMP_REPO" | |
| git init -q | |
| git -c user.email=ci@example.com -c user.name=ci commit --allow-empty -q -m init | |
| # --no-worktree: same rationale as the negative-case test above — this | |
| # test exercises the Claude subprocess spawn path, not worktree setup. | |
| set +e | |
| OUTPUT=$(CLAUDE_BIN_PATH="$CLI_PATH" "$BIN" workflow run archon-assist --no-worktree "hello" 2>&1) | |
| EXIT_CODE=$? | |
| set -e | |
| echo "$OUTPUT" | |
| if echo "$OUTPUT" | grep -qE 'Module not found.*(cli\.js|Users/runner)'; then | |
| echo "::error::Subprocess could not find the executable (resolver regression)" | |
| exit 1 | |
| fi | |
| if echo "$OUTPUT" | grep -q "Claude Code not found"; then | |
| echo "::error::Resolver failed even though CLAUDE_BIN_PATH was set to an existing file" | |
| exit 1 | |
| fi | |
| # Any of these outcomes are acceptable — they prove the subprocess spawned: | |
| # - auth error ("credit balance", "unauthorized", "authentication") | |
| # - rate-limit / API error | |
| # - successful query (if auth was injected via some other mechanism) | |
| echo "::notice::Claude subprocess spawn path is healthy (exit code: $EXIT_CODE)" | |
| - name: Upload binary artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ matrix.binary }} | |
| path: dist/${{ matrix.binary }} | |
| retention-days: 1 | |
| release: | |
| needs: build | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: dist | |
| merge-multiple: true | |
| - name: Setup Bun | |
| uses: oven-sh/setup-bun@v2 | |
| with: | |
| bun-version: 1.3.11 | |
| - name: Install dependencies | |
| run: bun install --frozen-lockfile | |
| - name: Build web UI | |
| run: bun --filter @archon/web build | |
| - name: Package web dist | |
| run: | | |
| tar czf dist/archon-web.tar.gz -C packages/web/dist . | |
| - name: Generate checksums | |
| run: | | |
| cd dist | |
| sha256sum archon-* archon-web.tar.gz > checksums.txt | |
| cat checksums.txt | |
| - name: Get version | |
| id: version | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| echo "version=${{ inputs.version }}" >> $GITHUB_OUTPUT | |
| else | |
| echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Create Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ steps.version.outputs.version }} | |
| name: Archon CLI ${{ steps.version.outputs.version }} | |
| draft: false | |
| prerelease: ${{ contains(steps.version.outputs.version, '-') }} | |
| generate_release_notes: true | |
| files: | | |
| dist/archon-* | |
| dist/archon-web.tar.gz | |
| dist/checksums.txt | |
| body: | | |
| ## Installation | |
| ### Quick Install (Recommended) | |
| **macOS / Linux** | |
| ```bash | |
| curl -fsSL https://archon.diy/install | bash | |
| ``` | |
| **Windows (PowerShell)** | |
| ```powershell | |
| irm https://archon.diy/install.ps1 | iex | |
| ``` | |
| **Homebrew (macOS / Linux)** | |
| ```bash | |
| brew install coleam00/archon/archon | |
| ``` | |
| **Docker** | |
| ```bash | |
| docker run --rm -v "$PWD:/workspace" ghcr.io/coleam00/archon:latest workflow list | |
| ``` | |
| ### Manual Installation | |
| **macOS (Apple Silicon)** | |
| ```bash | |
| curl -fsSL https://github.com/coleam00/Archon/releases/latest/download/archon-darwin-arm64 -o /usr/local/bin/archon | |
| chmod +x /usr/local/bin/archon | |
| ``` | |
| **macOS (Intel)** | |
| ```bash | |
| curl -fsSL https://github.com/coleam00/Archon/releases/latest/download/archon-darwin-x64 -o /usr/local/bin/archon | |
| chmod +x /usr/local/bin/archon | |
| ``` | |
| **Linux (x64)** | |
| ```bash | |
| curl -fsSL https://github.com/coleam00/Archon/releases/latest/download/archon-linux-x64 -o /usr/local/bin/archon | |
| chmod +x /usr/local/bin/archon | |
| ``` | |
| **Linux (ARM64)** | |
| ```bash | |
| curl -fsSL https://github.com/coleam00/Archon/releases/latest/download/archon-linux-arm64 -o /usr/local/bin/archon | |
| chmod +x /usr/local/bin/archon | |
| ``` | |
| **Windows (Manual)** | |
| Download `archon-windows-x64.exe` from the assets below, rename to `archon.exe`, and add to your PATH. | |
| ### Verify installation | |
| ```bash | |
| archon version | |
| ``` | |
| update-homebrew: | |
| needs: release | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: dev | |
| - name: Get version | |
| id: version | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| echo "version=${{ inputs.version }}" >> $GITHUB_OUTPUT | |
| else | |
| echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Wait for release assets | |
| run: sleep 30 | |
| - name: Update Homebrew formula | |
| run: bash scripts/update-homebrew.sh ${{ steps.version.outputs.version }} | |
| - name: Commit updated formula | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git add homebrew/archon.rb | |
| git diff --cached --quiet || git commit -m "chore: update Homebrew formula for ${{ steps.version.outputs.version }}" | |
| git push origin dev |