name: Crates, NPM & GitHub release

on:
  workflow_dispatch:
    inputs:
      ezno-version:
        description: "major/minor/patch or semver for Ezno (cli)"
        required: false
        default: "none"
      ezno-parser-version:
        description: "major/minor/patch or semver for parser"
        required: false
        default: "none"
      ezno-checker-version:
        description: "major/minor/patch or semver for type checker"
        required: false
        default: "none"
      other-versions:
        description: "comma seperated 'name=version_argument' pairs"
        required: false
        default: "none"

concurrency: release-crate

jobs:
  crates-publish:
    runs-on: ubuntu-latest
    outputs:
      new-ezno-version: ${{ steps.version.outputs.new-ezno-version }}
    steps:
      - uses: actions/checkout@v3

      - name: Set git credentials
        run: |
          git config user.name github-actions
          git config user.email github-actions@github.com

      - id: set-arguments
        run: |
          ARGS="ezno=${{ github.event.inputs.ezno-version }},ezno-parser=${{ github.event.inputs.ezno-parser-version }},ezno-checker=${{ github.event.inputs.ezno-checker-version }},${{ github.event.inputs.other-versions }}"
          echo "::debug::$ARGS"
          
          VALUE=$(echo $ARGS | jq --raw-input --compact-output 'split(",") | map(select(length > 0 and . != "none")) | map_values(split("=") | { (.[0]): .[1] }) | reduce .[] as $o ({}; . + $o)')
          echo "::debug::$VALUE"

          echo "publish-args=$VALUE" >> $GITHUB_OUTPUT
        shell: bash

      - name: Crates publish
        uses: kaleidawave/crates-release-gh-action@main
        id: release
        with:
          version: ${{ steps.set-arguments.outputs.publish-args }}
          crates-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}

      - name: Get new Ezno version
        id: version
        run: echo "new-ezno-version=$(echo '${{ steps.release.outputs.new-versions-json-object }}' | jq ".ezno" )" >> $GITHUB_OUTPUT

      - name: Install WASM build dependencies
        run: |
          rustup target add wasm32-unknown-unknown
          
          mkdir wasm-bindgen
          cd wasm-bindgen
          gh release download 0.2.84 -R rustwasm/wasm-bindgen -p '*x86_64-unknown-linux-musl.tar.gz' -O wasm-bindgen.tar.gz
          tar -xf wasm-bindgen.tar.gz
          mv wasm-bindgen-0.2.84-x86_64-unknown-linux-musl/wasm-bindgen wasm-bindgen
          pwd >> $GITHUB_PATH
        env:
          GH_TOKEN: ${{ github.token }}

      - name: Set NPM package version & build
        run: | 
          npm install
          npm version ${{ steps.version.outputs.new-ezno-version }}
          npm run build
        working-directory: src/js-cli-and-library

      - name: NPM publish (cli and library)
        uses: rxfork/npm-publish@v1
        with:
          token: ${{ secrets.NPM_REGISTRY_TOKEN }}
          package: src/js-cli-and-library/package.json
        
      - name: Node plugin build
        run: |
          # Hopefully propagated in 20 seconds
          sleep 20
          npm install ezno@${{ steps.version.outputs.new-ezno-version }}
          npm version ${{ steps.version.outputs.new-ezno-version }}
        working-directory: src/js-based-plugin

      - name: NPM publish (plugin)
        uses: rxfork/npm-publish@v1
        with:
          token: ${{ secrets.NPM_REGISTRY_TOKEN }}
          package: src/js-based-plugin/package.json

      - name: Push updated manifests
        run: |
          # Create tags
          echo '${{ steps.release.outputs.new-versions }}' | jq -r '.[]' | while read -r update; do
            git tag "release/$update"
          done
          git add .
          git commit -m "Release: ${{ steps.release.outputs.new-versions-description }}"
          git push --tags origin main

      - name: Discord
        uses: dusmartijngames/discord-webhook-notify@master
        with:
          severity: info
          text: "Released version ${{ steps.release.outputs.new-versions-description }}"
          webhookUrl: ${{ secrets.DISCORD_WEBHOOK_ENDPOINT }}
          
  build:
    if: ${{ github.event.inputs.ezno-version != 'none' }}
    needs: crates-publish

    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        include:
          - os: windows-latest
            executable-extension: .exe
            platform_name: x86_64-pc-windows
          - os: ubuntu-latest
            platform_name: x86_64-unknown-linux

    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v3

      - name: Build binary
        run: cargo build --release

      - name: Rename and move release assets
        run: |
          mkdir artifacts
          mv target/release/ezno${{ matrix.executable-extension }} artifacts/ezno-${{ needs.crates-publish.outputs.new-ezno-version }}-${{ matrix.platform_name }}${{ matrix.executable-extension }}

      - uses: actions/upload-artifact@v3
        with:
          name: build-artifacts
          path: artifacts/*
          if-no-files-found: error
          retention-days: 1

  github-release:
    if: ${{ github.event.inputs.ezno-version != 'none' }}
    needs: [crates-publish, build]
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2

    - uses: actions/download-artifact@v3
      with:
        name: build-artifacts
        path: build-artifacts
        
    - name: GitHub release
      uses: softprops/action-gh-release@v1
      with:
        body: "Release ${{ needs.crates-publish.outputs.new-ezno-version }}"
        tag_name: "release/${{ needs.crates-publish.outputs.new-ezno-version }}"
        files: |
          README.md
          build-artifacts/*