name: release

on:
  release:
    types: [published]
  workflow_dispatch:

jobs:
  wait:
    runs-on: ubuntu-latest
    steps:
      - name: Wait for checks to succeed
        uses: poseidon/wait-for-status-checks@v0.4.1
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          interval: 5

  dist:
    strategy:
      # don't cancel other jobs when one fails
      fail-fast: false
      matrix:
        include:
          - os: windows-latest
            target: x86_64-pc-windows-msvc
            code-target: win32-x64
          - os: windows-latest
            target: i686-pc-windows-msvc
            code-target: win32-x64
          - os: windows-latest
            target: aarch64-pc-windows-msvc
            code-target: win32-arm64
          - os: ubuntu-latest
            target: x86_64-unknown-linux-gnu
            code-target: linux-x64
          - os: ubuntu-latest
            target: x86_64-unknown-linux-musl
            code-target: linux-x64
          # - os: ubuntu-latest
          #   target: i686-unknown-linux-musl
          #   code-target: linux-x64
          - os: ubuntu-latest
            target: aarch64-unknown-linux-gnu
            code-target: linux-arm64
          - os: ubuntu-latest
            target: aarch64-unknown-linux-musl
            code-target: linux-arm64
          - os: ubuntu-latest
            target: arm-unknown-linux-gnueabihf
            code-target: linux-armhf
          - os: macos-latest
            target: x86_64-apple-darwin
            code-target: darwin-x64
          - os: macos-latest
            target: aarch64-apple-darwin
            code-target: darwin-arm64

    name: dist (${{ matrix.target }})
    runs-on: ${{ matrix.os }}
    needs: wait

    steps:
      - uses: actions/checkout@v4
      # needed for arm targets
      - name: Install Rust
        uses: dtolnay/rust-toolchain@v1
        with:
          toolchain: stable
          target: ${{ matrix.target }}
      - uses: Swatinem/rust-cache@v2
      - name: Install zlib-dev and openssl-dev (linux)
        if: contains(matrix.target, 'unknown-linux')
        run: sudo apt-get update && sudo apt-get install zlib1g-dev libssl-dev musl-tools
      - name: Install GCC arm64 (linux)
        if: startsWith(matrix.target, 'aarch64-unknown-linux')
        run: sudo apt-get update && sudo apt-get install gcc-aarch64-linux-gnu
      - name: Install GCC armhf (linux)
        if: matrix.target == 'arm-unknown-linux-gnueabihf'
        run: sudo apt-get update && sudo apt-get install gcc-arm-linux-gnueabihf
      - name: Install i686 glibc (linux)
        if: matrix.target == 'i686-unknown-linux-musl'
        run: sudo apt-get install gcc-multilib g++-multilib libc6-dev-i386
      - run: cargo build --target ${{ matrix.target }} --release
        env:
          PKG_CONFIG_ALLOW_CROSS: 1
          CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
          CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER: aarch64-linux-gnu-gcc
          CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER: arm-linux-gnueabihf-gcc
      - run: npm ci
      - name: vsce package
        # we can only publish a single linux-x64 and linux-arm64 package
        # so we skip the gnu target and package the musl target
        if: matrix.target != 'x86_64-unknown-linux-gnu' && matrix.target != 'aarch64-unknown-linux-gnu' && matrix.target != 'i686-unknown-linux-musl' && matrix.target != 'i686-pc-windows-msvc'
        # use bash on windows
        shell: bash
        run: |
          mkdir -p bundled dist
          cp target/${{ matrix.target }}/release/bacon-ls* bundled/
          npx vsce package -o dist/ --target ${{ matrix.code-target }}
      - name: vsce package for alpine
        # package the alpine-x64 target with the musl binary
        if: matrix.target == 'x86_64-unknown-linux-musl'
        shell: bash
        run: npx vsce package -o dist/ --target alpine-x64
      - name: Archive
        shell: bash
        run: |
          ver=${GITHUB_REF/refs\/*\//}
          archive="dist/bacon-ls-$ver-${{ matrix.target }}"
          mkdir -p dist

          if [ "${{ matrix.os }}" == "windows-latest" ]; then
            7z a "${archive}.zip" target/${{ matrix.target }}/release/bacon-ls.exe
          else
            tar czf "${archive}.tar.gz" -C target/${{ matrix.target }}/release bacon-ls
          fi

          ls -al dist/*
      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.target }}
          path: dist
      - name: Start sshx session on failed manual run or retry
        if: ${{ failure() && (github.event_name == 'workflow_dispatch' || github.run_attempt > 1) }}
        run: curl -sSf https://sshx.io/get | sh && sshx

  publish:
    runs-on: ubuntu-latest
    needs: dist
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version-file: package.json
      # download each artifact into its own self-named directory
      - uses: actions/download-artifact@v4
        with:
          path: dist
      - run: npm ci
      - name: Inspect dist
        run: |
          ls -al dist/*
          find dist -name "*.vsix" -type f
      - name: vsce publish
        run: npx vsce publish --packagePath $(find dist -name "*.vsix" -type f)
        env:
          VSCE_PAT: ${{ secrets.VSCE_PAT }}
      - name: ovsx publish
        run: npx ovsx publish --packagePath $(find dist -name "*.vsix" -type f)
        env:
          OVSX_PAT: ${{ secrets.OVSX_PAT }}
      - name: Upload to GH release
        uses: softprops/action-gh-release@v2
        with:
          # unset the prerelease flag and make it the latest release
          prerelease: false
          make_latest: true
          files: dist/**/*
      - name: Start sshx session on failed manual run or retry
        if: ${{ failure() && (github.event_name == 'workflow_dispatch' || github.run_attempt > 1) }}
        run: curl -sSf https://sshx.io/get | sh && sshx
