http-nu 0.15.0

The surprisingly performant, Nushell-scriptable, cross.stream-powered, Datastar-ready HTTP server that fits in your back pocket.
Documentation
name: release-binaries

on:
  push:
    branches:
      - '**'
    tags:
      - 'v*'

permissions:
  contents: write      # required for gh release

jobs:
  #-----------------------------------------------------------
  # 1. Build matrix - each row runs on its own VM
  #-----------------------------------------------------------
  build:
    name: Build ${{ matrix.target }}
    runs-on: ubuntu-latest

    strategy:
      matrix:
        include:
          - target: darwin-arm64
            dagger_fn: darwin-build
            artifact_suffix: darwin-arm64.tar.gz

          - target: windows-amd64
            dagger_fn: windows-build
            artifact_suffix: windows-amd64.tar.gz

          - target: linux-arm64
            dagger_fn: linux-arm-64-build
            artifact_suffix: linux-arm64.tar.gz

          - target: linux-amd64
            dagger_fn: linux-amd-64-build
            artifact_suffix: linux-amd64.tar.gz

    steps:
      # 1) Check out source
      - uses: actions/checkout@v4

      # 2) Sanitize ref name (replace / with -)
      - name: Set version
        id: version
        run: |
          VERSION="${{ github.ref_name }}"
          VERSION_SAFE="${VERSION//\//-}"
          echo "version=$VERSION_SAFE" >> "$GITHUB_OUTPUT"
          echo "artifact=http-nu-${VERSION_SAFE}-${{ matrix.artifact_suffix }}" >> "$GITHUB_OUTPUT"

      # 3) Free up disk space (Windows cross-compile needs ~20GB)
      - name: Free disk space
        run: |
          sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL
          sudo docker image prune --all --force

      # 4) Cache Dagger BuildKit cache (restore and save)
      - name: Cache Dagger
        uses: actions/cache@v4
        with:
          path: ~/.cache/dagger
          key: dagger-${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}
          restore-keys: |
            dagger-${{ runner.os }}-${{ matrix.target }}-

      # 5) Boot the Dagger engine
      - name: Setup Dagger
        uses: dagger/dagger-for-github@8.0.0
        with:
          version: "0.18.10"
          cloud-token: ${{ secrets.DAGGER_CLOUD_TOKEN }}

      # 6) Defensive: pre-pull the engine image
      - name: Pre-pull Dagger Engine
        run: docker pull registry.dagger.io/engine:v0.18.10

      # 7) Run one Dagger build function and export artifact
      - name: Build with Dagger
        uses: dagger/dagger-for-github@8.0.0
        with:
          version: "0.18.10"
          call: ${{ matrix.dagger_fn }} --src upload --src . --version ${{ steps.version.outputs.version }} export --path ./artifacts/${{ steps.version.outputs.artifact }}
          cloud-token: ${{ secrets.DAGGER_CLOUD_TOKEN }}

      # 8) Upload artifact for fan-in job
      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: ${{ steps.version.outputs.artifact }}
          path: ./artifacts/${{ steps.version.outputs.artifact }}

  #-----------------------------------------------------------
  # 2. Fan-in job - gather artifacts and create prerelease
  #-----------------------------------------------------------
  release:
    name: Create Release
    if: startsWith(github.ref, 'refs/tags/')
    runs-on: ubuntu-latest
    needs: build

    steps:
      - uses: actions/checkout@v4
      - name: Download artifacts
        uses: actions/download-artifact@v4
        with:
          path: artifacts
          merge-multiple: true

      - name: Generate changelog if missing
        run: |
          tag="${{ github.ref_name }}"
          changelog="changes/${tag}.md"
          if [ ! -f "$changelog" ]; then
            # Get the previous tag by sorting all tags and finding the one before current
            previous_tag=$(git tag --list 'v*' --sort=-version:refname | grep -A1 "^${tag}$" | tail -1)
            if [ -n "$previous_tag" ] && [ "$previous_tag" != "$tag" ]; then
              git log --format=%s "${previous_tag}..${tag}" > "$changelog"
            else
              git log --format=%s "${tag}" > "$changelog"
            fi
          fi

      - name: Publish release
        uses: softprops/action-gh-release@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name:   ${{ github.ref_name }}
          name:       Release ${{ github.ref_name }}
          prerelease: ${{ contains(github.ref_name, '-dev.') }}
          draft:      false
          body_path:  changes/${{ github.ref_name }}.md
          body:       Release build from commit ${{ github.sha }}
          files: artifacts/*