name: Release

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

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Rust toolchain
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          toolchain: stable
          target: |
            x86_64-unknown-linux-gnu

      - name: Cache Rust dependencies
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/
            ~/target/
          key: cargo-test-${{ hashFiles('**/Cargo.lock') }}

      - name: Test
        run: cargo test

  crates-jwkserve:
    runs-on: ubuntu-latest
    needs: [test]
    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Rust toolchain
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          toolchain: stable

      - name: Cache Rust dependencies
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/
            ~/target/
          key: cargo-publish-${{ hashFiles('**/Cargo.lock') }}

      - name: Install Cargo Set-Version
        run: cargo install cargo-set-version || true

      - name: Set Version
        run: |
          TAG_NAME=${GITHUB_REF#refs/tags/}
          VERSION=${TAG_NAME#v}
          cargo set-version $VERSION
          
      - name: Publish jwkserve library
        run: |
          cargo publish --allow-dirty --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

  build-arm:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Rust toolchain
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          toolchain: stable
          target: |
            aarch64-unknown-linux-gnu

      - name: Cache Rust dependencies
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/
            ~/target/
          key: cargo-build-arm-${{ hashFiles('**/Cargo.lock') }}

      - name: Install Zig
        uses: mlugg/setup-zig@v2
        with:
          version: 0.13.0

      - name: Install cargo-zigbuild
        run: cargo install cargo-zigbuild || true

      - name: Install Cargo Set-Version
        run: cargo install cargo-set-version || true

      - name: Set Version
        run: |
          TAG_NAME=${GITHUB_REF#refs/tags/}
          VERSION=${TAG_NAME#v}
          cargo set-version $VERSION

      - name: Build ARM
        run: cargo zigbuild --release --target aarch64-unknown-linux-gnu

      - name: Upload ARM artifact
        uses: actions/upload-artifact@v4
        with:
          name: jwkserve-arm
          path: target/aarch64-unknown-linux-gnu/release/jwkserve

  build-x86:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Rust toolchain
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          toolchain: stable
          target: |
            x86_64-unknown-linux-gnu

      - name: Cache Rust dependencies
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/bin/
            ~/target/
          key: cargo-build-x86-${{ hashFiles('**/Cargo.lock') }}

      - name: Install Zig
        uses: mlugg/setup-zig@v2
        with:
          version: 0.13.0

      - name: Install cargo-zigbuild
        run: cargo install cargo-zigbuild || true

      - name: Install Cargo Set-Version
        run: cargo install cargo-set-version || true

      - name: Set Version
        run: |
          TAG_NAME=${GITHUB_REF#refs/tags/}
          VERSION=${TAG_NAME#v}
          cargo set-version $VERSION

      - name: Build X86
        run: cargo zigbuild --release --target x86_64-unknown-linux-gnu

      - name: Upload X86 artifact
        uses: actions/upload-artifact@v4
        with:
          name: jwkserve-x86
          path: target/x86_64-unknown-linux-gnu/release/jwkserve

  docker:
    needs: [build-arm, build-x86, test]
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Download ARM artifact
        uses: actions/download-artifact@v4
        with: 
          name: jwkserve-arm
          path: ./target/aarch64-unknown-linux-gnu/release/

      - name: Download X86 artifact
        uses: actions/download-artifact@v4
        with:
          name: jwkserve-x86
          path: ./target/x86_64-unknown-linux-gnu/release/

      - name: Set up Docker
        uses: docker/setup-docker-action@v4
        with:
          daemon-config: |
            {
              "debug": true,
              "features": {
                "containerd-snapshotter": true
              }
            }

      - name: Login to DockerHub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Create build context
        run: |
          mkdir -p build-context
          cp -r target build-context
          cp Dockerfile build-context/

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: build-context
          path: build-context

      - name: Build and push
        uses: docker/build-push-action@v6
        with:
          context: build-context
          platforms: linux/amd64,linux/arm64
          push: true
          tags: sbstjn/jwkserve:${{ github.ref_name }},sbstjn/jwkserve:latest
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: Login to Scaleway Container Registry
        uses: docker/login-action@v3
        with:
          username: nologin
          password: ${{ secrets.SCALEWAY_API_KEY }}
          registry: ${{ secrets.CONTAINER_REGISTRY_ENDPOINT }}

      - name: Create private key file
        run: |
          cd infrastructure
          echo "${{ secrets.JWKSERVE_KEY }}" > private.key

      - name: Build Scaleway Container
        run: |
          cd infrastructure
          docker build \
            --platform linux/amd64 \
            -f Dockerfile . \
            -t rg.fr-par.scw.cloud/funcscwjwkservey7lpl8qx/jwkserve:latest

      - name: Push to Scaleway Container Registry
        run: docker push rg.fr-par.scw.cloud/funcscwjwkservey7lpl8qx/jwkserve:latest

      - name: Install Scaleway CLI
        run: curl -s https://raw.githubusercontent.com/scaleway/scaleway-cli/master/scripts/get.sh | sh

      - name: Deploy Scaleway Container
        env:
          SCW_ACCESS_KEY: ${{ secrets.SCW_ACCESS_KEY }}
          SCW_SECRET_KEY: ${{ secrets.SCW_SECRET_KEY }}
          SCW_DEFAULT_REGION: fr-par
        run: scw container container deploy 16513618-be5b-4ecc-a663-474685c62d7e
