diff --git a/.github/actions/setup-rust-soldr/action.yml b/.github/actions/setup-rust-soldr/action.yml new file mode 100644 index 0000000..b5fdc39 --- /dev/null +++ b/.github/actions/setup-rust-soldr/action.yml @@ -0,0 +1,137 @@ +name: Setup Rust with soldr +description: Install a Rust toolchain plus soldr (zccache-backed build caching) and print cache evidence. +inputs: + toolchain: + description: Rust toolchain to install. + required: false + default: stable + components: + description: Comma-separated Rust components to install. + required: false + default: "" + targets: + description: Comma-separated Rust targets to install. + required: false + default: "" + enable-shims: + description: >- + "true" (default) installs setup-soldr's PATH shims (cargo, rustc, + rustfmt, clippy-driver, rustdoc) so plain `cargo ...` steps route + through soldr; "false" installs soldr without shims so cargo runs + bare — used by native Windows jobs. + required: false + default: "true" +runs: + using: composite + steps: + - name: Install Linux build prerequisites + if: runner.os == 'Linux' + shell: bash + run: | + set -euo pipefail + need_install=false + command -v cc >/dev/null 2>&1 || need_install=true + command -v pkg-config >/dev/null 2>&1 || need_install=true + pkg-config --exists openssl 2>/dev/null || need_install=true + if [ "$need_install" = false ]; then + exit 0 + fi + packages="build-essential pkg-config libssl-dev" + if command -v apt-get >/dev/null 2>&1; then + if [ "$(id -u)" = "0" ]; then + apt-get update + # shellcheck disable=SC2086 + apt-get install -y $packages + elif command -v sudo >/dev/null 2>&1; then + sudo apt-get update + # shellcheck disable=SC2086 + sudo apt-get install -y $packages + else + echo "::error::apt-get is available but the runner is not root and sudo is missing." + exit 1 + fi + exit 0 + fi + echo "::error::No C compiler found and no supported package manager is available." + exit 1 + + - name: Install Rust + uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable + with: + toolchain: ${{ inputs.toolchain }} + components: ${{ inputs.components }} + targets: ${{ inputs.targets }} + + # setup-soldr installs the soldr front door (zccache compilation caching). + # cache-preset: minimal — these are persistent self-hosted runners, so the + # zccache store persists on local disk and GitHub-cache save/restore layers + # would only add network overhead. Compile caching itself stays ON (do NOT + # use `cache: false` — that exports SOLDR_BUILD_CACHE_MODE=off and disables + # zccache entirely). With shims: true, plain `cargo ...` trampolines into + # `soldr cargo ...`. version pins the binary; bump deliberately. + - name: Install soldr + uses: zackees/setup-soldr@c4e66a9114a45193605ff4a27404ef74b9b9a6dc # v0 + with: + version: "0.8.19" + cache-preset: minimal + shims: ${{ inputs.enable-shims }} + toolchain: ${{ inputs.toolchain }} + # platform-default keeps the system linker (cc/gcc). soldr's own + # default (`fast`) injects a clang + mold/rust-lld toolchain the CI + # runner image lacks (`error: linker 'clang' not found`). Matches the + # pre-migration behavior (system default linker). + linker: platform-default + # cargo-chef `cook` prebuild panics / restores mismatched deps; every + # cache-preset keeps it on, so opt out explicitly. zccache compile + # caching (the actual point of soldr) is unaffected. + prebuild-deps: none + # Persist the zccache compile store across runs, rooted under the + # workspace. $GITHUB_WORKSPACE is /_work//, which the runner + # farm bind-mounts persistently per runner. setup-soldr derives + # SOLDR_CACHE_DIR=-soldr, so the store is persistent AND + # per-runner (no shared mount, no cross-runner exec race). + cache-dir: ${{ github.workspace }}/../.soldr + + # GitHub release assets are MUTABLE: the version pin above pins the tag + # name, not the bytes. These hashes anchor the exact 0.8.19 binaries + # validated 2026-07-21. On a soldr version bump: download the new release + # assets, hash the soldr binary, and update both values deliberately. + - name: Verify soldr binary integrity + shell: bash + run: | + set -euo pipefail + case "$(uname -s)" in + Linux) want="8dc4051fe83c498ded65f8aa245d7a5e5576f3998d971e0c6d501464e9f580ac" ;; + MINGW*|MSYS*|CYGWIN*) want="46c95c9e9bfa3ffd99da221ab5bdbcab2723ebc0c98f596905f058ddbb495ddd" ;; + *) echo "::warning::no pinned soldr hash for $(uname -s); skipping integrity check"; exit 0 ;; + esac + bin="$(command -v soldr)" + got="$(sha256sum "$bin" | cut -d' ' -f1)" + if [ "$got" != "$want" ]; then + echo "::error::soldr binary hash mismatch at $bin (got $got want $want) — possible swapped release asset; refusing to build" + exit 1 + fi + echo "soldr binary integrity OK: $got" + + - name: Show Rust cache configuration + shell: bash + run: | + set -euo pipefail + rustc -vV + cargo -V + soldr --version + printf 'SOLDR_CACHE_DIR=%s\n' "${SOLDR_CACHE_DIR:-}" + printf 'RUSTUP_TOOLCHAIN=%s\n' "${RUSTUP_TOOLCHAIN:-}" + # Guard against the silent no-op failure mode: if shims were requested, + # `cargo` on PATH must resolve into setup-soldr's shims dir. A bare + # cargo here means every build silently runs uncached. + if [ "${{ inputs.enable-shims }}" = "true" ]; then + resolved="$(command -v cargo)" + case "$resolved" in + *shims*) printf 'cargo shim engaged: %s\n' "$resolved" ;; + *) + echo "::error::soldr cargo shim NOT engaged (cargo=$resolved); builds would run uncached" + exit 1 + ;; + esac + fi diff --git a/.release-please-manifest.json b/.release-please-manifest.json index bf5f1fb..37fcefa 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.6.2" + ".": "1.0.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 3aaac59..6fa4fad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Format: ## [X.Y.Z] — YYYY-MM-DD Use Added / Changed / Deprecated / Removed / Fixed / Security headers. --> +## [1.0.0](https://github.com/dinglebear-ai/synapse/compare/v0.6.2...v1.0.0) (2026-07-29) + + +### ⚠ BREAKING CHANGES + +* complete Synapse identity cutover ([#80](https://github.com/dinglebear-ai/synapse/issues/80)) + +### Added + +* complete Synapse identity cutover ([#80](https://github.com/dinglebear-ai/synapse/issues/80)) ([cf1f3f9](https://github.com/dinglebear-ai/synapse/commit/cf1f3f9ef5925b28f5a5a1ca2d8da5af28815cc2)) + ## [0.6.2](https://github.com/dinglebear-ai/synapse/compare/v0.6.1...v0.6.2) (2026-07-28) @@ -100,8 +111,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **JSON logging mode** — set `LOG_FORMAT=json` or `RUST_LOG_FORMAT=json` to emit structured NDJSON log lines instead of the default human-readable format. - **Rust edition 2024** — workspace updated to `edition = "2024"`. Release profile now uses `lto = "thin"` and `strip = "symbols"`. - **`rust-toolchain.toml` added** — pins the toolchain channel for reproducible builds. -- **x86_64-only releases.** The release and installer contract now publishes - and accepts Linux x86_64 binaries only. +- **Dropped arm64 support.** The `Docker Publish` workflow previously also built + `linux/arm64` under QEMU emulation, which made the emulated Rust release build + exceed the job timeout and cancel every run; it now builds `linux/amd64` only. + `install.sh` no longer claims to support arm64 hosts (no `aarch64` release + binary is published) and instead points arm64 users to a source build, and the + CI docs were corrected to match. Re-add arm64 via a native runner matrix if it + is needed. ## [0.5.2] — 2026-06-11 @@ -401,7 +417,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `lefthook.yml` — minimal pre-commit hooks (diff_check, toml_fmt, env_guard) - `.github/workflows/ci.yml` — CI: fmt, clippy, nextest, taplo, audit, gitleaks - `.github/workflows/docker-publish.yml` — multi-platform Docker build + Trivy scan -- `.github/workflows/release.yml` — release binaries for Linux +- `.github/workflows/release.yml` — release binaries for linux/amd64 and linux/arm64 - `config.example.toml` — fully annotated config template - `.env.example` — documented secrets template - `CHANGELOG.md` following Keep a Changelog format diff --git a/Cargo.lock b/Cargo.lock index d651f18..1939616 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3025,7 +3025,7 @@ dependencies = [ [[package]] name = "synapse" -version = "0.6.2" +version = "1.0.0" dependencies = [ "anyhow", "async-trait", @@ -4129,7 +4129,7 @@ checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "xtask" -version = "0.6.2" +version = "1.0.0" dependencies = [ "anyhow", "walkdir", diff --git a/Cargo.toml b/Cargo.toml index 32a1485..c30a0ff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = [".", "xtask"] resolver = "3" [workspace.package] -version = "0.6.2" +version = "1.0.0" edition = "2024" rust-version = "1.97.1" authors = ["dinglebear.ai "] diff --git a/docs/generated/openapi.json b/docs/generated/openapi.json index 36c8518..669b77d 100644 --- a/docs/generated/openapi.json +++ b/docs/generated/openapi.json @@ -2,7 +2,7 @@ "openapi": "3.1.0", "info": { "title": "Synapse REST API", - "version": "0.6.2", + "version": "1.0.0", "description": "Generated OpenAPI schema for Synapse's REST surface. Loopback deployments have no HTTP auth; non-loopback deployments require SYNAPSE_MCP_TOKEN or OAuth bearer JWTs. REST actions require their action-specific scopes when auth is mounted." }, "servers": [ diff --git a/packages/synapse-rmcp/package.json b/packages/synapse-rmcp/package.json index bdeac86..02cf6fb 100644 --- a/packages/synapse-rmcp/package.json +++ b/packages/synapse-rmcp/package.json @@ -1,6 +1,6 @@ { "name": "@dinglebear/synapse", - "version": "0.6.2", + "version": "1.0.0", "description": "MCP server and CLI for host and container operations: Docker and Compose control, SSH, host inspection, logs, ZFS, and safe file transfer.", "license": "MIT", "homepage": "https://github.com/dinglebear-ai/synapse#readme", diff --git a/plugins/synapse/mcp.json b/plugins/synapse/mcp.json new file mode 100644 index 0000000..6561583 --- /dev/null +++ b/plugins/synapse/mcp.json @@ -0,0 +1,11 @@ +{ + "mcpServers": { + "synapse": { + "type": "http", + "url": "${user_config.server_url}/mcp", + "headers": { + "Authorization": "Bearer ${user_config.api_token}" + } + } + } +} diff --git a/server.json b/server.json index 063dc84..168bcc1 100644 --- a/server.json +++ b/server.json @@ -3,7 +3,7 @@ "name": "ai.dinglebear/synapse", "title": "Synapse RMCP", "description": "MCP server and CLI for host and container operations: Docker and Compose control, SSH, host inspection, logs, ZFS, and safe file transfer.", - "version": "0.6.2", + "version": "1.0.0", "websiteUrl": "https://github.com/dinglebear-ai/synapse", "repository": { "url": "https://github.com/dinglebear-ai/synapse", @@ -25,7 +25,7 @@ "registryType": "npm", "registryBaseUrl": "https://registry.npmjs.org", "identifier": "@dinglebear/synapse", - "version": "0.6.2", + "version": "1.0.0", "runtimeHint": "npx", "packageArguments": [ { @@ -67,7 +67,7 @@ "format": "string", "isRequired": false, "isSecret": false, - "placeholder": "v0.6.2" + "placeholder": "v1.0.0" }, { "name": "SYNAPSE_RMCP_REPO", @@ -105,11 +105,11 @@ "namespace": "ai.dinglebear", "dnsDomain": "dinglebear.ai", "distribution": { - "npm": "@dinglebear/synapse@0.6.2", + "npm": "@dinglebear/synapse@1.0.0", "nodePackage": "@dinglebear/synapse" }, "buildInfo": { - "version": "0.6.2", + "version": "1.0.0", "repository": "https://github.com/dinglebear-ai/synapse" } }