name: Build/publish release

on: [push, pull_request]

jobs:
  publish:
    name: Binary ${{ matrix.target }} (on ${{ matrix.os }})
    runs-on: ${{ matrix.os }}
    outputs:
      version: ${{ steps.extract_version.outputs.version }}
    strategy:
      matrix:
        include:
          - os: ubuntu-latest
            target: x86_64-unknown-linux-musl
            cross: true
          - os: ubuntu-latest
            target: x86_64-unknown-linux-gnu
            cross: true
          - os: ubuntu-latest
            target: aarch64-unknown-linux-musl
            cross: true
          - os: ubuntu-latest
            target: aarch64-unknown-linux-gnu
            cross: true
          - os: ubuntu-latest
            target: armv7-unknown-linux-musleabihf
            cross: true
          - os: ubuntu-latest
            target: armv7-unknown-linux-gnueabihf
            cross: true
          - os: ubuntu-latest
            target: arm-unknown-linux-musleabihf
            cross: true
          - os: windows-latest
            target: x86_64-pc-windows-msvc
            cross: false
          - os: macos-latest
            target: x86_64-apple-darwin
            cross: false
          - os: ubuntu-latest
            target: x86_64-unknown-freebsd
            cross: true
          - os: ubuntu-latest
            target: wasm32-unknown-unknown

    steps:
      - name: Checkout code
        uses: actions/checkout@v5

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

      - run: cargo install trunk wasm-bindgen-cli
        if: matrix.target == 'wasm32-unknown-unknown'

      - run: sudo apt install musl-tools
        if: startsWith(matrix.os, 'ubuntu') && matrix.target != 'wasm32-unknown-unknown'

      - name: Set exe extension for Windows
        run: echo "RUSTFLAGS=--cfg getrandom_backend=\"wasm_js\"" >> "$GITHUB_ENV"
        if: matrix.target == 'wasm32-unknown-unknown'

      - name: cargo build
        uses: houseabsolute/actions-rust-cross@v0
        with:
          command: build
          args: --release --locked ${{ matrix.cargo_flags }}
          target: ${{ matrix.target }}

      - name: trunk build
        run: trunk build --release
        if: matrix.target == 'wasm32-unknown-unknown'

      - name: Set exe extension for Windows
        run: echo "EXE=.exe" >> $env:GITHUB_ENV
        if: startsWith(matrix.os, 'windows')

      - name: Compress binaries
        uses: svenstaro/upx-action@v2
        with:
          files: target/${{ matrix.target }}/release/genact${{ env.EXE }}
          args: --best --lzma
          strip: false  # We're stripping already in Cargo.toml
        if: matrix.target != 'wasm32-unknown-unknown' && matrix.target != 'x86_64-unknown-freebsd' && matrix.target != 'x86_64-apple-darwin'

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.target }}
          path: target/${{ matrix.target }}/release/genact${{ env.EXE }}
        if: matrix.target != 'wasm32-unknown-unknown'

      - name: Get version from tag
        id: extract_version
        run: |
          echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
        shell: bash
        if: matrix.target != 'wasm32-unknown-unknown'

      - name: Install CHANGELOG parser
        uses: taiki-e/install-action@parse-changelog

      - name: Get CHANGELOG entry
        run: parse-changelog CHANGELOG.md ${{ steps.extract_version.outputs.version }} | tee changelog_entry
        if: startsWith(github.ref_name, 'v') && github.ref_type == 'tag'
        shell: bash

      - name: Read changelog entry from file
        id: changelog_entry
        uses: juliangruber/read-file-action@v1
        with:
          path: ./changelog_entry
        if: startsWith(github.ref_name, 'v') && github.ref_type == 'tag'

      - name: Release
        uses: svenstaro/upload-release-action@v2
        with:
          repo_token: ${{ secrets.GITHUB_TOKEN }}
          file: target/${{ matrix.target }}/release/genact${{ env.EXE }}
          tag: ${{ github.ref_name }}
          asset_name: genact-${{ steps.extract_version.outputs.version }}-${{ matrix.target }}${{ env.EXE }}
          body: ${{ steps.changelog_entry.outputs.content }}
        if: startsWith(github.ref_name, 'v') && github.ref_type == 'tag' && matrix.target != 'wasm32-unknown-unknown'

      - name: Deploy
        uses: peaceiris/actions-gh-pages@v4
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dist
        if: startsWith(github.ref_name, 'v') && github.ref_type == 'tag' && matrix.target == 'wasm32-unknown-unknown'

  container-images:
    name: Publish images
    runs-on: ubuntu-latest
    needs: publish
    if: (startsWith(github.ref_name, 'v') && github.ref_type == 'tag') || github.event.repository.default_branch == github.ref_name

    steps:
      - name: Checkout code
        uses: actions/checkout@v5

      - name: Download artifact aarch64-unknown-linux-musl
        uses: actions/download-artifact@v4
        with:
          name: aarch64-unknown-linux-musl
          path: target/aarch64-unknown-linux-musl/release

      - name: Download artifact x86_64-unknown-linux-musl
        uses: actions/download-artifact@v4
        with:
          name: x86_64-unknown-linux-musl
          path: target/x86_64-unknown-linux-musl/release

      - name: Download artifact armv7-unknown-linux-musleabihf
        uses: actions/download-artifact@v4
        with:
          name: armv7-unknown-linux-musleabihf
          path: target/armv7-unknown-linux-musleabihf/release

      - name: podman login
        run: podman login --username ${{ secrets.DOCKERHUB_USERNAME }} --password ${{ secrets.DOCKERHUB_TOKEN }} docker.io

      - name: podman build linux/arm64
        run: podman build --format docker --platform linux/arm64/v8 --manifest genact -f Containerfile target/aarch64-unknown-linux-musl/release

      - name: podman build linux/amd64
        run: podman build --format docker --platform linux/amd64 --manifest genact -f Containerfile target/x86_64-unknown-linux-musl/release

      - name: podman build linux/arm
        run: podman build --format docker --platform linux/arm/v7 --manifest genact -f Containerfile target/armv7-unknown-linux-musleabihf/release

      - name: podman manifest push latest
        run: podman manifest push genact docker.io/svenstaro/genact:latest

      - name: podman manifest push tag version
        run: podman manifest push genact docker.io/svenstaro/genact:${{ needs.publish.outputs.version }}
        if: startsWith(github.ref_name, 'v')
