name: Draft release

on:
  workflow_dispatch:
    inputs:
      version:
        description: The version to publish (include "v", i.e. "v4.9.1").
        type: string
        required: true

permissions:
  contents: write # For creating releases.
  discussions: write #  For creating a discussion.

# Cancel in-progress runs for pull requests when developers push
# additional changes
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
  package-linux-cross:
    name: ${{ matrix.prefix }}
    runs-on: ubuntu-latest
    timeout-minutes: 15
    needs: npm-version
    container: "python:3.8-slim-buster"
    strategy:
      matrix:
        include:
          - prefix: x86_64-linux-gnu
            npm_arch: x64
            apt_arch: amd64
            package_arch: amd64
          - prefix: aarch64-linux-gnu
            npm_arch: arm64
            apt_arch: arm64
            package_arch: arm64
          - prefix: arm-linux-gnueabihf
            npm_arch: armv7l
            apt_arch: armhf
            package_arch: armv7l

    env:
      AR: ${{ format('{0}-ar', matrix.prefix) }}
      AS: ${{ format('{0}-as', matrix.prefix) }}
      CC: ${{ format('{0}-gcc', matrix.prefix) }}
      CPP: ${{ format('{0}-cpp', matrix.prefix) }}
      CXX: ${{ format('{0}-g++', matrix.prefix) }}
      FC: ${{ format('{0}-gfortran', matrix.prefix) }}
      LD: ${{ format('{0}-ld', matrix.prefix) }}
      STRIP: ${{ format('{0}-strip', matrix.prefix) }}
      PKG_CONFIG_PATH: ${{ format('/usr/lib/{0}/pkgconfig', matrix.prefix) }}
      TARGET_ARCH: ${{ matrix.apt_arch }}
      npm_config_arch: ${{ matrix.npm_arch }}
      PKG_ARCH: ${{ matrix.package_arch }}
      # Not building from source results in an x86_64 argon2, as if
      # npm_config_arch is being ignored.
      npm_config_build_from_source: true

    steps:
      - name: Checkout repo
        uses: actions/checkout@v4

      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version-file: .node-version
          cache: npm
          cache-dependency-path: |
            package-lock.json
            test/package-lock.json

      - name: Install cross-compiler and system dependencies
        run: |
          sed -i 's/deb\.debian\.org/archive.debian.org/g' /etc/apt/sources.list
          dpkg --add-architecture $TARGET_ARCH
          apt update && apt install -y --no-install-recommends \
            crossbuild-essential-$TARGET_ARCH \
            libx11-dev:$TARGET_ARCH \
            libx11-xcb-dev:$TARGET_ARCH \
            libxkbfile-dev:$TARGET_ARCH \
            libsecret-1-dev:$TARGET_ARCH \
            libkrb5-dev:$TARGET_ARCH \
            ca-certificates \
            curl wget rsync gettext-base

      - run: SKIP_SUBMODULE_DEPS=1 npm ci

      - name: Install nfpm
        run: |
          mkdir -p ~/.local/bin
          curl -sSfL https://github.com/goreleaser/nfpm/releases/download/v2.3.1/nfpm_2.3.1_`uname -s`_`uname -m`.tar.gz | tar -C ~/.local/bin -zxv nfpm
          echo "$HOME/.local/bin" >> $GITHUB_PATH

      - name: Download npm package
        uses: actions/download-artifact@v4
        with:
          name: npm-release-package

      - run: tar -xzf package.tar.gz
      - run: npm run release:standalone

      - name: Replace node with cross-compile equivalent
        run: |
          node_version=$(node --version)
          wget https://nodejs.org/dist/${node_version}/node-${node_version}-linux-${npm_config_arch}.tar.xz
          tar -xf node-${node_version}-linux-${npm_config_arch}.tar.xz node-${node_version}-linux-${npm_config_arch}/bin/node --strip-components=2
          mv ./node ./release-standalone/lib/node

      # Strip out the v (v4.9.1 -> 4.9.1).
      - name: Get and set VERSION
        run: |
          TAG="${{ inputs.version || github.ref_name }}"
          echo "VERSION=${TAG#v}" >> $GITHUB_ENV

      - env:
          VERSION: ${{ env.VERSION }}
        run: npm run package $PKG_ARCH

      - uses: softprops/action-gh-release@v1
        with:
          draft: true
          discussion_category_name: "📣 Announcements"
          files: ./release-packages/*

  package-macos-amd64:
    name: x86-64 macOS build
    runs-on: macos-13
    timeout-minutes: 15
    needs: npm-version
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    steps:
      - name: Checkout repo
        uses: actions/checkout@v4

      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version-file: .node-version
          cache: npm
          cache-dependency-path: |
            package-lock.json
            test/package-lock.json

      - run: SKIP_SUBMODULE_DEPS=1 npm ci

      - name: Install nfpm
        run: |
          mkdir -p ~/.local/bin
          curl -sSfL https://github.com/goreleaser/nfpm/releases/download/v2.3.1/nfpm_2.3.1_`uname -s`_`uname -m`.tar.gz | tar -C ~/.local/bin -zxv nfpm
          echo "$HOME/.local/bin" >> $GITHUB_PATH

      # The version of node-gyp we use depends on distutils but it was removed
      # in Python 3.12.  It seems to be fixed in the latest node-gyp so when we
      # next update Node we can probably remove this.  For now, install
      # setuptools since it contains distutils.
      - run: brew install python-setuptools

      - name: Download npm package
        uses: actions/download-artifact@v4
        with:
          name: npm-release-package

      - run: tar -xzf package.tar.gz
      - run: npm run release:standalone
      - run: npm run test:native

      # Strip out the v (v4.9.1 -> 4.9.1).
      - name: Get and set VERSION
        run: |
          TAG="${{ inputs.version || github.ref_name }}"
          echo "VERSION=${TAG#v}" >> $GITHUB_ENV

      - name: Build packages with nfpm
        env:
          VERSION: ${{ env.VERSION }}
        run: npm run package

      - uses: softprops/action-gh-release@v1
        with:
          draft: true
          discussion_category_name: "📣 Announcements"
          files: ./release-packages/*

  package-macos-arm64:
    name: arm64 macOS build
    runs-on: macos-latest
    timeout-minutes: 15
    needs: npm-version
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

    steps:
      - name: Checkout repo
        uses: actions/checkout@v4

      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version-file: .node-version
          cache: npm
          cache-dependency-path: |
            package-lock.json
            test/package-lock.json

      - run: SKIP_SUBMODULE_DEPS=1 npm ci

      - name: Install nfpm
        run: |
          mkdir -p ~/.local/bin
          curl -sSfL https://github.com/goreleaser/nfpm/releases/download/v2.3.1/nfpm_2.3.1_`uname -s`_`uname -m`.tar.gz | tar -C ~/.local/bin -zxv nfpm
          echo "$HOME/.local/bin" >> $GITHUB_PATH

      # The version of node-gyp we use depends on distutils but it was removed
      # in Python 3.12.  It seems to be fixed in the latest node-gyp so when we
      # next update Node we can probably remove this.  For now, install
      # setuptools since it contains distutils.
      - run: brew install python-setuptools

      - name: Download npm package
        uses: actions/download-artifact@v4
        with:
          name: npm-release-package

      - run: tar -xzf package.tar.gz
      - run: npm run release:standalone
      - run: npm run test:native

      # Strip out the v (v4.9.1 -> 4.9.1).
      - name: Get and set VERSION
        run: |
          TAG="${{ inputs.version || github.ref_name }}"
          echo "VERSION=${TAG#v}" >> $GITHUB_ENV

      - name: Build packages with nfpm
        env:
          VERSION: ${{ env.VERSION }}
        run: npm run package

      - uses: softprops/action-gh-release@v1
        with:
          draft: true
          discussion_category_name: "📣 Announcements"
          files: ./release-packages/*

  npm-package:
    name: Upload npm package
    runs-on: ubuntu-latest
    timeout-minutes: 15
    needs: npm-version
    steps:
      - name: Download npm package
        uses: actions/download-artifact@v4
        with:
          name: npm-release-package

      - uses: softprops/action-gh-release@v1
        with:
          draft: true
          discussion_category_name: "📣 Announcements"
          files: ./package.tar.gz

  npm-version:
    name: Modify package.json version
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - name: Download artifacts
        uses: dawidd6/action-download-artifact@v11
        id: download
        with:
          branch: ${{ github.ref }}
          workflow: build.yaml
          workflow_conclusion: completed
          name: npm-package
          check_artifacts: false
          if_no_artifact_found: fail

      - run: tar -xzf package.tar.gz

      # Strip out the v (v4.9.1 -> 4.9.1).
      - name: Get and set VERSION
        run: |
          TAG="${{ inputs.version || github.ref_name }}"
          echo "VERSION=${TAG#v}" >> $GITHUB_ENV

      - name: Modify version
        env:
          VERSION: ${{ env.VERSION }}
        run: |
          echo "Updating version in root package.json"
          npm version --prefix release "$VERSION"

          echo "Updating version in lib/vscode/product.json"
          tmp=$(mktemp)
          jq ".codeServerVersion = \"$VERSION\"" release/lib/vscode/product.json > "$tmp" && mv "$tmp" release/lib/vscode/product.json
          # Ensure it has the same permissions as before
          chmod 644 release/lib/vscode/product.json

      - run: tar -czf package.tar.gz release

      - name: Upload npm package artifact
        uses: actions/upload-artifact@v4
        with:
          name: npm-release-package
          path: ./package.tar.gz
