brain-edge 0.2.0

The HTTP/JSON edge for the Brain memory database — a self-hostable binary and an embeddable library that speaks the same API the Arc cloud hosts.
Documentation
name: CI

# feature -> dev -> main, with the dev -> main PR as the release gate.
# `pull_request` covers both hops; `push` is main-only and deliberately excludes
# dev. In brain-db, dev being both a push trigger and the head of the standing
# dev -> main PR made every merge into dev raise two runs of this workflow on
# one commit — 71 minutes of wall-clock burned across three collisions before it
# was caught.
on:
  push:
    branches: [main]
  pull_request:
    branches: [main, dev]

# Cancel a superseded PR run; never cancel a push to main, where a half-run
# release check is worse than a slightly stale one.
concurrency:
  group: ci-${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1

jobs:
  rust:
    name: Rust
    runs-on: ubuntu-26.04
    steps:
      - uses: actions/checkout@v7

      - uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy

      - uses: Swatinem/rust-cache@v2

      # rustfmt.toml pins style_edition = "2024"; without it rustfmt would read
      # the 2021 language edition from Cargo.toml and reformat the whole crate.
      - name: Format check
        run: cargo fmt --all -- --check

      # The lint set lives in Cargo.toml's `[lints]` so rust-analyzer enforces
      # the same rules; `-D warnings` is what turns them into a gate.
      - name: Clippy
        run: cargo clippy --all-targets --all-features -- -D warnings

      - name: Test
        run: cargo test --all-targets

      # --locked so a drifting transitive dep fails here rather than in the
      # release image, which builds --locked too.
      - name: Build (release, locked)
        run: cargo build --release --locked --bin brain-edge

  docker:
    name: Docker image
    runs-on: ubuntu-26.04
    steps:
      - uses: actions/checkout@v7

      - uses: docker/setup-buildx-action@v4

      # Build only; publishing is a separate concern.
      - name: Build image
        uses: docker/build-push-action@v7
        with:
          context: .
          push: false
          load: true
          tags: brain-edge:ci
          cache-from: type=gha
          cache-to: type=gha,mode=max

      # Proves the entrypoint actually runs in the slim runtime stage — a shared
      # library the builder had and the runtime doesn't only shows up here, never
      # at compile time. /health/live is the static liveness route, so this needs
      # no Brain behind it; /health/ready would, and would rightly fail.
      - name: Smoke-test the image
        run: |
          docker run -d --name edge -p 8080:8080 brain-edge:ci
          for i in $(seq 1 30); do
            if curl -fsS http://127.0.0.1:8080/health/live; then
              echo "edge is live"
              docker rm -f edge
              exit 0
            fi
            sleep 1
          done
          echo "::error title=Smoke test failed::/health/live never answered"
          docker logs edge
          docker rm -f edge
          exit 1