http-server-rs 0.0.69

Simple, zero-configuration command-line static HTTP server.
name: Release

concurrency:
  group: ${{ github.ref }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

on:
  push:
    branches:
      - "main"

jobs:
  version:
    name: ๐ŸŒ Auto Version Increment
    runs-on: ubuntu-24.04
    outputs:
      VERSION: ${{ steps.generate.outputs.VERSION }}
      GITHUB_REPOSITORY_NAME: ${{ steps.generate.outputs.GITHUB_REPOSITORY_NAME }}
      GITHUB_REPOSITORY: ${{ steps.generate.outputs.GITHUB_REPOSITORY }}
    steps:
      - id: generate
        run: |
          set -ex

          GITHUB_URL="https://api.github.com/repos/${{ github.repository }}"
          LAST_VERSION=$(curl -sSL "$GITHUB_URL/releases/latest" | jq -r '.tag_name // empty')

          if [ -z "$LAST_VERSION" ]; then
            # No releases yet
            NEW_VERSION="0.0.1"
          else
            IFS='.' read -r MAJOR MINOR PATCH <<< "$LAST_VERSION"
            NEW_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))"
          fi

          echo "Bumping ${LAST_VERSION:-<none>} -> $NEW_VERSION"

          GITHUB_REPOSITORY_NAME="${GITHUB_REPOSITORY#*/}"

          echo $NEW_VERSION
          echo $GITHUB_REPOSITORY
          echo $GITHUB_REPOSITORY_NAME

          echo "VERSION=$NEW_VERSION" >> "$GITHUB_OUTPUT"
          echo "GITHUB_REPOSITORY_NAME=$GITHUB_REPOSITORY_NAME" >> "$GITHUB_OUTPUT"
          echo "GITHUB_REPOSITORY=$GITHUB_REPOSITORY" >> "$GITHUB_OUTPUT"

  test:
    name: ๐Ÿงช Test
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v7
      - run: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && echo "$HOME/.cargo/bin" >> $GITHUB_PATH
      - uses: Swatinem/rust-cache@v2
      - run: cargo test

  format:
    name: ๐Ÿ“ Format
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v7
      - run: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && echo "$HOME/.cargo/bin" >> $GITHUB_PATH
      - uses: Swatinem/rust-cache@v2
      - run: cargo install cargo-xfmt
      - run: cargo xfmt --check

  lint:
    name: ๐Ÿค“ Lint
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v7
      - run: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && echo "$HOME/.cargo/bin" >> $GITHUB_PATH
      - uses: Swatinem/rust-cache@v2
      - run: cargo clippy --all-targets --workspace -- -D warnings

  # Due to platform differences I have opted out of using a matrix.
  # Examples;
  #   - Windows executables have different names
  #   - Linux glibc builds require containers (not used here but I use this as a template)
  build_linux_amd64:
    name: ๐Ÿฅ Linux AMD64
    runs-on: ubuntu-latest
    needs:
      - version
      - format
      - lint
      - test
    env:
      VERSION: ${{needs.version.outputs.VERSION}}
      GITHUB_REPOSITORY_NAME: ${{needs.version.outputs.GITHUB_REPOSITORY_NAME}}
    steps:
      - uses: actions/checkout@v7
      - run: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && echo "$HOME/.cargo/bin" >> $GITHUB_PATH
      - uses: Swatinem/rust-cache@v2
        with: { key: "x86_64-unknown-linux-musl" }
      - run: sudo apt-get update
      - run: sudo apt-get install -y musl-tools
      - run: rustup target add x86_64-unknown-linux-musl
      - run: sed "s/0.0.0-local/${VERSION}/g" "Cargo.toml" > "Cargo.toml.new" && mv "Cargo.toml.new" "Cargo.toml"
      - run: cargo build --target x86_64-unknown-linux-musl --release
      - run: mkdir -p artifacts/${GITHUB_REPOSITORY_NAME}-linux-amd64
      - run: cp target/x86_64-unknown-linux-musl/release/${GITHUB_REPOSITORY_NAME} ./artifacts/${GITHUB_REPOSITORY_NAME}-linux-amd64
      - uses: actions/upload-artifact@v7
        with:
          name: ${{ env.GITHUB_REPOSITORY_NAME }}-linux-amd64
          path: ${{ github.workspace }}/artifacts/**/*
          if-no-files-found: error
          retention-days: 1

  build_linux_arm64:
    name: ๐Ÿฅ Linux ARM64
    runs-on: ubuntu-26.04-arm
    needs:
      - version
      - format
      - lint
      - test
    env:
      VERSION: ${{needs.version.outputs.VERSION}}
      GITHUB_REPOSITORY_NAME: ${{needs.version.outputs.GITHUB_REPOSITORY_NAME}}
    steps:
      - uses: actions/checkout@v7
      - run: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && echo "$HOME/.cargo/bin" >> $GITHUB_PATH
      - uses: Swatinem/rust-cache@v2
        with: { key: "aarch64-unknown-linux-musl" }
      - run: sudo apt-get update
      - run: sudo apt-get install -y musl-tools
      - run: rustup target add aarch64-unknown-linux-musl
      - run: sed "s/0.0.0-local/${VERSION}/g" "Cargo.toml" > "Cargo.toml.new" && mv "Cargo.toml.new" "Cargo.toml"
      - run: cargo build --target aarch64-unknown-linux-musl --release
      - run: mkdir -p artifacts/${GITHUB_REPOSITORY_NAME}-linux-arm64
      - run: cp target/aarch64-unknown-linux-musl/release/${GITHUB_REPOSITORY_NAME} ./artifacts/${GITHUB_REPOSITORY_NAME}-linux-arm64
      - uses: actions/upload-artifact@v7
        with:
          name: ${{ env.GITHUB_REPOSITORY_NAME }}-linux-arm64
          path: ${{ github.workspace }}/artifacts/**/*
          if-no-files-found: error
          retention-days: 1

  build_macos_arm64:
    name: ๐ŸŽ MacOS ARM64
    runs-on: macos-latest
    needs:
      - version
      - format
      - lint
      - test
    env:
      VERSION: ${{needs.version.outputs.VERSION}}
      GITHUB_REPOSITORY_NAME: ${{needs.version.outputs.GITHUB_REPOSITORY_NAME}}
    steps:
      - uses: actions/checkout@v7
      - run: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && echo "$HOME/.cargo/bin" >> $GITHUB_PATH
      - uses: Swatinem/rust-cache@v2
        with: { key: "aarch64-apple-darwin" }
      - run: rustup target add aarch64-apple-darwin
      - run: sed "s/0.0.0-local/${VERSION}/g" "Cargo.toml" > "Cargo.toml.new" && mv "Cargo.toml.new" "Cargo.toml"
      - run: cargo build --target aarch64-apple-darwin --release
      - run: mkdir -p artifacts/${GITHUB_REPOSITORY_NAME}-macos-arm64
      - run: cp target/aarch64-apple-darwin/release/${GITHUB_REPOSITORY_NAME} ./artifacts/${GITHUB_REPOSITORY_NAME}-macos-arm64
      - uses: actions/upload-artifact@v7
        with:
          name: ${{ env.GITHUB_REPOSITORY_NAME }}-macos-arm64
          path: ${{ github.workspace }}/artifacts/**/*
          if-no-files-found: error
          retention-days: 1

  build_windows_amd64:
    name: ๐ŸŸฆ Windows AMD64
    runs-on: windows-latest
    needs:
      - version
      - format
      - lint
      - test
    env:
      VERSION: ${{needs.version.outputs.VERSION}}
      GITHUB_REPOSITORY_NAME: ${{needs.version.outputs.GITHUB_REPOSITORY_NAME}}
    steps:
      - uses: actions/checkout@v7
      - run: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && echo "$HOME/.cargo/bin" >> $GITHUB_PATH
      - uses: Swatinem/rust-cache@v2
        with: { key: "x86_64-pc-windows-msvc" }
      - run: rustup target add x86_64-pc-windows-msvc
      - run: sed "s/0.0.0-local/${VERSION}/g" "Cargo.toml" > "Cargo.toml.new" && mv "Cargo.toml.new" "Cargo.toml"
      - run: cargo build --target x86_64-pc-windows-msvc --release
      - run: mkdir -p artifacts/${GITHUB_REPOSITORY_NAME}-windows-amd64
      - run: cp target/x86_64-pc-windows-msvc/release/${GITHUB_REPOSITORY_NAME}.exe ./artifacts/${GITHUB_REPOSITORY_NAME}-windows-amd64
      - uses: actions/upload-artifact@v7
        with:
          name: ${{ env.GITHUB_REPOSITORY_NAME }}-windows-amd64
          path: ${{ github.workspace }}/artifacts/**/*
          if-no-files-found: error
          retention-days: 1

  build_windows_arm64:
    name: ๐ŸŸฆ Windows ARM64
    runs-on: windows-latest
    needs:
      - version
      - format
      - lint
      - test
    env:
      VERSION: ${{needs.version.outputs.VERSION}}
      GITHUB_REPOSITORY_NAME: ${{needs.version.outputs.GITHUB_REPOSITORY_NAME}}
    steps:
      - uses: actions/checkout@v7
      - run: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && echo "$HOME/.cargo/bin" >> $GITHUB_PATH
      - uses: Swatinem/rust-cache@v2
        with: { key: "aarch64-pc-windows-msvc" }
      - run: rustup target add aarch64-pc-windows-msvc
      - run: sed "s/0.0.0-local/${VERSION}/g" "Cargo.toml" > "Cargo.toml.new" && mv "Cargo.toml.new" "Cargo.toml"
      - run: cargo build --target aarch64-pc-windows-msvc --release
      - run: mkdir -p artifacts/${GITHUB_REPOSITORY_NAME}-windows-arm64
      - run: cp target/aarch64-pc-windows-msvc/release/${GITHUB_REPOSITORY_NAME}.exe ./artifacts/${GITHUB_REPOSITORY_NAME}-windows-arm64
      - uses: actions/upload-artifact@v7
        with:
          name: ${{ env.GITHUB_REPOSITORY_NAME }}-windows-arm64
          path: ${{ github.workspace }}/artifacts/**/*
          if-no-files-found: error
          retention-days: 1

  publish_github_release:
    name: "๐Ÿฑโ€๐Ÿ‘ค Publish Github Release"
    runs-on: ubuntu-24.04
    needs:
      - build_linux_amd64
      - build_linux_arm64
      - build_macos_arm64
      - build_windows_amd64
      - build_windows_arm64
      - version
    steps:
      - uses: actions/checkout@v7
      - uses: actions/download-artifact@v8
        with:
          path: artifacts
          merge-multiple: true
      - name: Publish` Github Release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          VERSION: ${{needs.version.outputs.VERSION}}
        run: |
          set -ex

          echo "Tag: ${VERSION}"

          gh release delete "$VERSION" --yes --cleanup-tag 2>/dev/null || true
          gh release create $VERSION --draft --notes "Automatically built binaries"
          gh release edit "$VERSION" --title "v${VERSION}"

          cd artifacts
          ls -la

          for name in *; do
            echo $name

            cd $name
            chmod +x ./*

            tar -czf ./$name.tar.gz ./*
            gh release upload $VERSION ${name}.tar.gz
            rm -rf ./*.tar.gz

            tar -cJf ./$name.tar.xz ./*
            gh release upload $VERSION ${name}.tar.xz
            rm -rf ./*.tar.xz

            zip ./$name.zip ./*
            gh release upload $VERSION ${name}.zip
            rm -rf ./*.zip

            cd ..
          done

          gh release edit $VERSION --draft=false

  changelog:
    name: "๐Ÿ“ Generate Changelog"
    runs-on: ubuntu-latest
    needs:
      - version
      - publish_github_release
    steps:
      - uses: actions/checkout@v7
      - env:
          VERSION: ${{needs.version.outputs.VERSION}}
        run: |
          payload="$(jq -n \
            --arg repository "$GITHUB_REPOSITORY" \
            --arg version "$VERSION" \
            '{repository: $repository, version: $version}')"

          curl -fsS -X POST "${{ secrets.SENTINEL_CHANGELOG_WEBHOOK }}" \
            -H "Content-Type: application/json" \
            -d "$payload" || true

  publish_crates_io:
    name: "๐Ÿฆ€ Publish: Crate"
    runs-on: ubuntu-latest
    needs:
      - version
      - publish_github_release
    steps:
      - uses: actions/checkout@v7
      - run: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && echo "$HOME/.cargo/bin" >> $GITHUB_PATH
      - uses: Swatinem/rust-cache@v2
      - env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
          VERSION: ${{needs.version.outputs.VERSION}}
        run: |
          set -e
          sed "s/0.0.0-local/${VERSION}/g" "Cargo.toml" > "Cargo.toml.new" && mv "Cargo.toml.new" "Cargo.toml"
          cargo publish --allow-dirty

  publish_npm:
    name: "๐Ÿ” Publish: NPM"
    runs-on: ubuntu-latest
    needs:
      - version
      - publish_github_release
    steps:
      - uses: actions/checkout@v7
      - uses: actions/download-artifact@v8
        with:
          path: artifacts
          merge-multiple: true
      - name: Publish` Github Release
        env:
          VERSION: ${{needs.version.outputs.VERSION}}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
        run: |
          set -e

          echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" >> $HOME/.npmrc
          echo "GH_TAG: ${GH_TAG}"
          echo "VERSION: ${VERSION}"

          # Update versions
          sed "s/0.0.0-local/${VERSION}/g" "npm/http-server-rs/package.json" > "npm/http-server-rs/package.json.new" && mv "npm/http-server-rs/package.json.new" "npm/http-server-rs/package.json"

          # Copy binaries
          cp "artifacts/http-server-rs-linux-amd64/http-server-rs" "npm/http-server-rs/http-server-rs-linux-x64"
          chmod +x "npm/http-server-rs/http-server-rs-linux-x64"

          cp "artifacts/http-server-rs-linux-arm64/http-server-rs" "npm/http-server-rs/http-server-rs-linux-arm64"
          chmod +x "npm/http-server-rs/http-server-rs-linux-arm64"

          cp "artifacts/http-server-rs-macos-arm64/http-server-rs" "npm/http-server-rs/http-server-rs-darwin-arm64"
          chmod +x "npm/http-server-rs/http-server-rs-darwin-arm64"

          cp "artifacts/http-server-rs-windows-amd64/http-server-rs.exe" "npm/http-server-rs/http-server-rs-win32-x64.exe"
          chmod +x "npm/http-server-rs/http-server-rs-win32-x64.exe"

          cp "artifacts/http-server-rs-windows-arm64/http-server-rs.exe" "npm/http-server-rs/http-server-rs-win32-arm64.exe"
          chmod +x "npm/http-server-rs/http-server-rs-win32-arm64.exe"

          # Copy README
          cp "README.md" "npm/http-server-rs/README.md"

          # Publish to NPM
          npm publish "./npm/http-server-rs"