interlink-mcp 0.7.3

Cryptographically-authenticated, cross-machine agent-to-agent chat for Claude Code, over MCP channels
Documentation
name: Release

# Tag a version (e.g. `git tag v0.1.0 && git push --tags`) to build the static
# binaries for every supported target and attach them to a GitHub Release. Those
# assets are what the npm wrapper's postinstall downloads and what a plugin can
# bundle — so this workflow is the single source of prebuilt binaries.
#
# After the binaries are attached, it also publishes to crates.io and npm via
# Trusted Publishing (OIDC) — no long-lived token secrets. One-time setup: configure
# a trusted publisher for each, pointing at repo `wilfreddenton/interlink` + workflow
# `release.yml`:
#   - crates.io: crate settings → Trusted Publishing
#   - npm:       package settings → Trusted Publisher (GitHub Actions)
# Bump the version in Cargo.toml, npm/package.json and plugin.json to match the tag
# before pushing it; the publish jobs use those files' versions.

on:
  push:
    tags: ["v*"]

permissions:
  contents: write # create the release and upload assets

env:
  CARGO_TERM_COLOR: always

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        include:
          # Each target builds on its NATIVE runner — no cross linker, no C
          # toolchain, just `rustup target add`. The pure-Rust/no-C invariant is
          # exactly what makes this a plain matrix instead of a cross-compile mess.
          - { os: ubuntu-latest, target: x86_64-unknown-linux-musl, static: true }
          - { os: ubuntu-24.04-arm, target: aarch64-unknown-linux-musl, static: true }
          - { os: macos-latest, target: aarch64-apple-darwin, static: false }
          - { os: windows-latest, target: x86_64-pc-windows-msvc, static: false }
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}
      - uses: Swatinem/rust-cache@v2

      - name: Build
        shell: bash
        run: |
          # A self-contained Windows binary needs the CRT linked statically;
          # musl is already fully static, macOS links only libSystem.
          if [ "${{ matrix.target }}" = "x86_64-pc-windows-msvc" ]; then
            export RUSTFLAGS="-C target-feature=+crt-static"
          fi
          cargo build --release --all-features --target ${{ matrix.target }}

      - name: Assert static (Linux musl)
        if: matrix.static
        run: file target/${{ matrix.target }}/release/interlink-mcp | grep -qi static

      - name: Stage assets
        id: stage
        shell: bash
        run: |
          target="${{ matrix.target }}"
          bindir="target/$target/release"
          ext=""
          [ "${{ runner.os }}" = "Windows" ] && ext=".exe"

          # (1) The raw interlink-mcp binary, per target — one file the npm
          #     wrapper downloads and runs directly.
          cp "$bindir/interlink-mcp$ext" "interlink-mcp-$target$ext"

          # (2) A full archive with all the binaries — for humans, and for a
          #     plugin that bundles them instead of using the npm wrapper.
          stage="interlink-$target"
          mkdir "$stage"
          cp "$bindir/interlink-mcp$ext" "$bindir/interlink-bus$ext" \
             "$bindir/interlink-keygen$ext" "$bindir/interlinked$ext" "$stage/"
          if [ "${{ runner.os }}" = "Windows" ]; then
            7z a "$stage.zip" "$stage" >/dev/null
            echo "archive=$stage.zip" >> "$GITHUB_OUTPUT"
          else
            tar czf "$stage.tar.gz" "$stage"
            echo "archive=$stage.tar.gz" >> "$GITHUB_OUTPUT"
          fi
          echo "binary=interlink-mcp-$target$ext" >> "$GITHUB_OUTPUT"

      - name: Attach to release
        uses: softprops/action-gh-release@v2
        with:
          files: |
            ${{ steps.stage.outputs.binary }}
            ${{ steps.stage.outputs.archive }}

  # crates.io publish — runs once the binaries are attached (so the release is whole).
  # Uses crates.io Trusted Publishing (OIDC): the official auth action exchanges the
  # run's OIDC token for a short-lived crates.io token — no CRATES_IO_TOKEN secret.
  # Requires a trusted publisher configured on crates.io for the `interlink-mcp` crate
  # → repo `wilfreddenton/interlink`, workflow `release.yml`.
  crates-io:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - uses: rust-lang/crates-io-auth-action@v1
        id: auth
      - name: cargo publish
        run: cargo publish --locked
        env:
          CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}

  # npm publish — the wrapper whose postinstall downloads the just-attached binary.
  # Uses npm Trusted Publishing (OIDC): no NPM_TOKEN secret, short-lived per-run
  # credentials, and automatic provenance. Requires a trusted publisher configured on
  # npmjs.com for this package → repo `wilfreddenton/interlink`, workflow
  # `release.yml`. Needs `id-token: write` and npm >= 11.5.1.
  npm:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          registry-url: https://registry.npmjs.org
      - name: Upgrade npm (trusted publishing needs >= 11.5.1)
        run: npm install -g npm@latest
      - name: npm publish (OIDC)
        working-directory: npm
        run: npm publish