minigraf 1.0.0

Zero-config, single-file, embedded graph database with bi-temporal Datalog queries
Documentation
name: C Release

on:
  push:
    tags:
      - '**[0-9]+.[0-9]+.[0-9]+*'
  workflow_dispatch:
    inputs:
      tag:
        description: 'Release tag to upload C artifacts to (e.g. "v0.24.0")'
        required: false
        type: string

jobs:
  build:
    name: Build C library (${{ matrix.os }})
    runs-on: ${{ matrix.os }}
    permissions:
      contents: read
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
            target: x86_64-unknown-linux-gnu
            artifact-name: linux-x86_64
            lib-name: libminigraf.so
            src-lib: libminigraf_c.so
          - os: ubuntu-24.04-arm
            target: aarch64-unknown-linux-gnu
            artifact-name: linux-aarch64
            lib-name: libminigraf.so
            src-lib: libminigraf_c.so
          - os: macos-14
            target: universal2
            artifact-name: macos-universal2
            lib-name: libminigraf.dylib
            src-lib: libminigraf_c.dylib
          - os: windows-latest
            target: x86_64-pc-windows-msvc
            artifact-name: windows-x86_64
            lib-name: minigraf.dll
            src-lib: minigraf_c.dll

    steps:
      - uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target == 'universal2' && 'aarch64-apple-darwin x86_64-apple-darwin' || matrix.target }}

      - name: Build (universal2)
        if: matrix.target == 'universal2'
        run: |
          cargo build --release -p minigraf-c --target aarch64-apple-darwin
          cargo build --release -p minigraf-c --target x86_64-apple-darwin
          lipo -create \
            target/aarch64-apple-darwin/release/libminigraf_c.dylib \
            target/x86_64-apple-darwin/release/libminigraf_c.dylib \
            -output ${{ matrix.lib-name }}

      - name: Build (other)
        if: matrix.target != 'universal2'
        run: cargo build --release -p minigraf-c --target ${{ matrix.target }}

      - name: Rename and package (unix)
        if: runner.os != 'Windows' && matrix.target != 'universal2'
        run: |
          cp target/${{ matrix.target }}/release/${{ matrix.src-lib }} ${{ matrix.lib-name }}
          tar czf minigraf-c-${{ inputs.tag || github.ref_name }}-${{ matrix.artifact-name }}.tar.gz \
            ${{ matrix.lib-name }} minigraf-c/include/minigraf.h

      - name: Rename and package (universal2)
        if: matrix.target == 'universal2'
        run: |
          tar czf minigraf-c-${{ inputs.tag || github.ref_name }}-${{ matrix.artifact-name }}.tar.gz \
            ${{ matrix.lib-name }} minigraf-c/include/minigraf.h

      - name: Rename and package (windows)
        if: runner.os == 'Windows'
        run: |
          copy target\${{ matrix.target }}\release\${{ matrix.src-lib }} ${{ matrix.lib-name }}
          Compress-Archive -Path ${{ matrix.lib-name }},minigraf-c\include\minigraf.h `
            -DestinationPath minigraf-c-${{ inputs.tag || github.ref_name }}-${{ matrix.artifact-name }}.zip
        shell: pwsh

      - name: Upload artifact (unix)
        if: runner.os != 'Windows'
        uses: actions/upload-artifact@v4
        with:
          name: c-release-${{ matrix.artifact-name }}
          path: minigraf-c-${{ inputs.tag || github.ref_name }}-${{ matrix.artifact-name }}.tar.gz

      - name: Upload artifact (windows)
        if: runner.os == 'Windows'
        uses: actions/upload-artifact@v4
        with:
          name: c-release-${{ matrix.artifact-name }}
          path: minigraf-c-${{ inputs.tag || github.ref_name }}-${{ matrix.artifact-name }}.zip

  upload-to-release:
    name: Upload artifacts to GitHub Release
    needs: build
    runs-on: ubuntu-latest
    permissions:
      contents: write

    steps:
      - name: Download all artifacts
        uses: actions/download-artifact@v4
        with:
          pattern: c-release-*
          path: artifacts
          merge-multiple: true

      - name: Wait for GitHub Release to exist, then upload
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          TAG: ${{ inputs.tag || github.ref_name }}
        run: |
          echo "Waiting for release $TAG to be created by cargo-dist..."
          for i in $(seq 1 40); do
            if gh release view "$TAG" --repo "$GITHUB_REPOSITORY" > /dev/null 2>&1; then
              echo "Release found on attempt $i"
              break
            fi
            echo "Attempt $i/40: release not yet available, waiting 15s..."
            sleep 15
          done
          if ! gh release view "$TAG" --repo "$GITHUB_REPOSITORY" > /dev/null 2>&1; then
            echo "ERROR: Release $TAG not found after 40 attempts (10 minutes). Aborting."
            exit 1
          fi
          gh release upload "$TAG" artifacts/* \
            --repo "$GITHUB_REPOSITORY" \
            --clobber