agentvfs 0.1.6

Virtual filesystem CLI backed by embedded databases for AI agents
Documentation
name: Release

on:
  push:
    tags:
      - 'v*'

env:
  CARGO_TERM_COLOR: always

# softprops/action-gh-release needs write access on the contents scope to
# create releases and upload assets. Without this, the default GITHUB_TOKEN
# is read-only and every "Create Release" / "Upload artifacts" step 403s.
permissions:
  contents: write

jobs:
  create-release:
    name: Create Release
    runs-on: ubuntu-latest
    outputs:
      upload_url: ${{ steps.create_release.outputs.upload_url }}
      version: ${{ steps.get_version.outputs.version }}
    steps:
      - uses: actions/checkout@v4

      - name: Get version
        id: get_version
        run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT

      - name: Create Release
        id: create_release
        uses: softprops/action-gh-release@v1
        with:
          name: v${{ steps.get_version.outputs.version }}
          draft: false
          prerelease: false
          generate_release_notes: true

  build-release:
    name: Build (${{ matrix.target }})
    needs: create-release
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - target: x86_64-unknown-linux-gnu
            os: ubuntu-latest
            archive: tar.gz
          - target: aarch64-unknown-linux-gnu
            os: ubuntu-latest
            archive: tar.gz
            cross: true
          - target: x86_64-apple-darwin
            os: macos-latest
            archive: tar.gz
          - target: aarch64-apple-darwin
            os: macos-latest
            archive: tar.gz
          - target: x86_64-pc-windows-msvc
            os: windows-latest
            archive: zip

    steps:
      - uses: actions/checkout@v4

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}

      - name: Install cross
        if: matrix.cross
        run: cargo install cross

      - name: Cache cargo
        uses: Swatinem/rust-cache@v2

      - name: Build (native)
        if: ${{ !matrix.cross }}
        run: cargo build --release --target ${{ matrix.target }}

      - name: Build (cross)
        if: matrix.cross
        run: cross build --release --target ${{ matrix.target }}

      - name: Set platform name
        id: platform
        shell: bash
        run: |
          case "${{ matrix.target }}" in
            x86_64-unknown-linux-gnu) echo "name=linux-x86_64" >> $GITHUB_OUTPUT ;;
            aarch64-unknown-linux-gnu) echo "name=linux-aarch64" >> $GITHUB_OUTPUT ;;
            x86_64-apple-darwin) echo "name=darwin-x86_64" >> $GITHUB_OUTPUT ;;
            aarch64-apple-darwin) echo "name=darwin-aarch64" >> $GITHUB_OUTPUT ;;
            x86_64-pc-windows-msvc) echo "name=windows-x86_64" >> $GITHUB_OUTPUT ;;
          esac

      - name: Package (Unix)
        if: matrix.archive == 'tar.gz'
        run: |
          mkdir -p dist
          cp target/${{ matrix.target }}/release/avfs dist/
          cd dist
          tar -czvf avfs-${{ needs.create-release.outputs.version }}-${{ steps.platform.outputs.name }}.tar.gz avfs
          sha256sum avfs-${{ needs.create-release.outputs.version }}-${{ steps.platform.outputs.name }}.tar.gz > avfs-${{ needs.create-release.outputs.version }}-${{ steps.platform.outputs.name }}.tar.gz.sha256

      - name: Package (Windows)
        if: matrix.archive == 'zip'
        shell: pwsh
        run: |
          New-Item -ItemType Directory -Force -Path dist
          Copy-Item "target/${{ matrix.target }}/release/avfs.exe" -Destination dist/
          Compress-Archive -Path dist/avfs.exe -DestinationPath "dist/avfs-${{ needs.create-release.outputs.version }}-${{ steps.platform.outputs.name }}.zip"
          $hash = (Get-FileHash "dist/avfs-${{ needs.create-release.outputs.version }}-${{ steps.platform.outputs.name }}.zip" -Algorithm SHA256).Hash.ToLower()
          "$hash  avfs-${{ needs.create-release.outputs.version }}-${{ steps.platform.outputs.name }}.zip" | Out-File -Encoding utf8 "dist/avfs-${{ needs.create-release.outputs.version }}-${{ steps.platform.outputs.name }}.zip.sha256"

      - name: Upload artifacts
        uses: softprops/action-gh-release@v1
        with:
          files: |
            dist/avfs-${{ needs.create-release.outputs.version }}-${{ steps.platform.outputs.name }}.${{ matrix.archive }}
            dist/avfs-${{ needs.create-release.outputs.version }}-${{ steps.platform.outputs.name }}.${{ matrix.archive }}.sha256

  publish-checksums:
    name: Publish Checksums
    needs: [create-release, build-release]
    runs-on: ubuntu-latest
    steps:
      - name: Download all artifacts
        uses: actions/download-artifact@v4
        with:
          path: artifacts

      - name: Collect checksums
        run: |
          mkdir -p dist
          find artifacts -name "*.sha256" -exec cat {} \; > dist/checksums.txt || true
          cat dist/checksums.txt || echo "No checksums found"

      - name: Upload checksums
        uses: softprops/action-gh-release@v1
        with:
          files: dist/checksums.txt
        if: always()

  publish-crate:
    name: Publish to crates.io
    needs: build-release
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable

      - name: Publish to crates.io
        run: cargo publish
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
        continue-on-error: true

  # npm and PyPI wrapper publishing is intentionally NOT done in CI.
  # These wrappers download platform binaries from the GitHub release at install
  # time, so they must only be published *after* this workflow's build-release
  # matrix has uploaded all platform archives. We publish them locally from
  # release.sh (which waits for the release artifacts to appear) so that a
  # broken or partial CI run can't push a wrapper that points at missing assets.
  # See release.sh: wait_for_github_release / publish_npm / publish_pypi.