name: Release

on:
  push:
    tags: ["*"]
  workflow_dispatch:

jobs:
  create-release:
    name: Create Release
    runs-on: ubuntu-latest
    outputs:
      upload_url: ${{ steps.create_release.outputs.upload_url }}
    steps:
      - name: Create Release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref }}
          release_name: ${{ github.ref }}
          draft: true

  release:
    needs: ["create-release"]
    strategy:
      matrix:
        include:
          - os: windows-latest
            artifact-name: stylua-windows-x86_64
            artifact-alias: stylua-win64
            cargo-target: x86_64-pc-windows-msvc
          - os: ubuntu-20.04
            artifact-name: stylua-linux-x86_64
            artifact-alias: stylua-linux
            cargo-target: x86_64-unknown-linux-gnu
          - os: ubuntu-20.04
            artifact-name: stylua-linux-aarch64
            cargo-target: aarch64-unknown-linux-gnu
            linker: gcc-aarch64-linux-gnu
          - os: macos-latest
            artifact-name: stylua-macos-x86_64
            artifact-alias: stylua-macos
            cargo-target: x86_64-apple-darwin
          - os: macos-latest
            artifact-name: stylua-macos-aarch64
            cargo-target: aarch64-apple-darwin

    name: Build (${{ matrix.artifact-name }})
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          target: ${{ matrix.cargo-target }}

      - name: Install Linker packages
        if: ${{ matrix.linker != '' }}
        run: |
          sudo apt update
          sudo apt install ${{ matrix.linker }}

      - name: Build Binary (All features)
        run: cargo build --verbose --locked --release --features lua52,lua53,lua54,luau --target ${{ matrix.cargo-target }}
        env:
          CARGO_TARGET_DIR: output

      - name: Setup Archive + Extension
        shell: bash
        run: |
          mkdir -p staging

          if [ "${{ matrix.os }}" = "windows-latest" ]; then
            cp "output/${{ matrix.cargo-target }}/release/stylua.exe" staging/
            cd staging
            7z a ../release.zip *
          else
            cp "output/${{ matrix.cargo-target }}/release/stylua" staging/
            cd staging
            zip ../release.zip *
          fi

      - name: Upload Binary Artifact
        uses: actions/upload-artifact@v3
        with:
          name: ${{ matrix.artifact-name }}
          path: release.zip

      - name: Upload Binary to Release
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ needs.create-release.outputs.upload_url }}
          asset_path: release.zip
          asset_name: ${{ matrix.artifact-name }}.zip
          asset_content_type: application/zip

      # TODO: Remove this after deprecation notice
      - name: Upload Binary to Release aliases
        if: ${{ matrix.artifact-alias != '' }}
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ needs.create-release.outputs.upload_url }}
          asset_path: release.zip
          asset_name: ${{ matrix.artifact-alias }}.zip
          asset_content_type: application/zip

  release_cargo:
    name: Publish to cargo
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

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

      - name: Publish to cargo
        run: cargo publish --verbose --locked --token ${{ secrets.CARGO_TOKEN }}

  release_npm_wasm:
    name: Publish wasm to npm
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          target: wasm32-unknown-unknown

      - name: Setup Node
        uses: actions/setup-node@v3
        with:
          node-version: "16.x"
          registry-url: "https://registry.npmjs.org"

      - name: Build WASM
        run: |
          chmod u+x ./wasm/build-wasm.sh
          ./wasm/build-wasm.sh

      - name: Publish to npm
        working-directory: wasm
        run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

  release_npm_bin:
    name: Publish binary to npm
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node
        uses: actions/setup-node@v3
        with:
          node-version: "16.x"
          registry-url: "https://registry.npmjs.org"

      - name: Setup README and LICENSE
        run: |
          cp README.md stylua-npm-bin/
          cp LICENSE.md stylua-npm-bin/

      - name: Publish to npm
        working-directory: stylua-npm-bin
        run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

  release_docker:
    name: Publish image to container registry
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: docker/setup-buildx-action@v2
        id: buildx
        with:
          install: true

      - uses: docker/metadata-action@v4
        id: meta
        env:
          DOCKER_METADATA_PR_HEAD_SHA: "true"
        with:
          images: johnnymorganz/stylua
          tags: |
            type=semver,pattern={{version}}
            type=sha

      - uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - uses: docker/build-push-action@v4
        with:
          push: true
          context: .
          file: Dockerfile
          builder: ${{ steps.buildx.outputs.name }}
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha
