name: Build Extension
on:
  workflow_dispatch:
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
  push:
    branches:
      - main

jobs:
  build:
    name: Build
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
    steps:
      - name: Checkout
        uses: actions/checkout@v2
        with:
          fetch-depth: 1

      - uses: actions/setup-node@v1
        with:
          node-version: '16.14.0'

      - name: Install dependencies
        working-directory: extensions/ql-vscode
        run: |
          npm install
        shell: bash

      - name: Build
        working-directory: extensions/ql-vscode
        env:
          APP_INSIGHTS_KEY: '${{ secrets.APP_INSIGHTS_KEY }}'
        run: |
          npm run build
        shell: bash

      - name: Prepare artifacts
        if: matrix.os == 'ubuntu-latest'
        run: |
          mkdir artifacts
          cp dist/*.vsix artifacts

      - name: Upload artifacts
        uses: actions/upload-artifact@v2
        if: matrix.os == 'ubuntu-latest'
        with:
          name: vscode-codeql-extension
          path: artifacts

  find-nightly:
    name: Find Nightly Release
    runs-on: ubuntu-latest
    outputs:
      url: ${{ steps.get-url.outputs.nightly-url }}
    steps:
      - name: Get Nightly Release URL
        id: get-url
        env:
          GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
        shell: bash
        # This workflow step gets an unstable testing version of the CodeQL CLI. It should not be used outside of these tests.
        run: |
          LATEST=`gh api repos/dsp-testing/codeql-cli-nightlies/releases --jq '.[].tag_name' --method GET --raw-field 'per_page=1'`
          echo "::set-output name=nightly-url::https://github.com/dsp-testing/codeql-cli-nightlies/releases/download/$LATEST"

  test:
    name: Test
    runs-on: ${{ matrix.os }}
    needs: [find-nightly]
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
    steps:
      - name: Checkout
        uses: actions/checkout@v2
        with:
          fetch-depth: 1

      - uses: actions/setup-node@v1
        with:
          node-version: '16.14.0'

      - name: Install dependencies
        working-directory: extensions/ql-vscode
        run: |
          npm install
        shell: bash

      - name: Build
        working-directory: extensions/ql-vscode
        env:
          APP_INSIGHTS_KEY: '${{ secrets.APP_INSIGHTS_KEY }}'
        run: |
          npm run build
        shell: bash

      - name: Lint
        working-directory: extensions/ql-vscode
        run: |
          npm run lint

      - name: Run unit tests (Linux)
        working-directory: extensions/ql-vscode
        if: matrix.os == 'ubuntu-latest'
        run: |
          npm run test

      - name: Run unit tests (Windows)
        if: matrix.os == 'windows-latest'
        working-directory: extensions/ql-vscode
        run: |
          npm run test

      - name: Run integration tests (Linux)
        if: matrix.os == 'ubuntu-latest'
        working-directory: extensions/ql-vscode
        env:
          VSCODE_CODEQL_GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
        run: |
          sudo apt-get install xvfb
          /usr/bin/xvfb-run npm run integration

      - name: Run integration tests (Windows)
        if: matrix.os == 'windows-latest'
        working-directory: extensions/ql-vscode
        env:
          VSCODE_CODEQL_GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
        run: |
          npm run integration

  cli-test:
    name: CLI Test
    runs-on: ${{ matrix.os }}
    needs: [find-nightly]
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        version: ['v2.6.3', 'v2.7.6', 'v2.8.5', 'v2.9.4', 'v2.10.4', 'nightly']
    env:
      CLI_VERSION: ${{ matrix.version }}
      NIGHTLY_URL: ${{ needs.find-nightly.outputs.url }}
      TEST_CODEQL_PATH: '${{ github.workspace }}/codeql'

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - uses: actions/setup-node@v1
        with:
          node-version: '16.14.0'

      - name: Install dependencies
        working-directory: extensions/ql-vscode
        run: |
          npm install
        shell: bash

      - name: Build
        working-directory: extensions/ql-vscode
        run: |
          npm run build
        shell: bash

      - name: Decide on ref of CodeQL repo
        id: choose-ref
        shell: bash
        run: |
          if [[ "${{ matrix.version }}" == "nightly" ]]
          then
            REF="codeql-cli/latest"
          else
            REF="codeql-cli/${{ matrix.version }}"
          fi
          echo "::set-output name=ref::$REF"

      - name: Checkout QL
        uses: actions/checkout@v2
        with:
          repository: github/codeql
          ref: ${{ steps.choose-ref.outputs.ref }}
          path: codeql

      - name: Run CLI tests (Linux)
        working-directory: extensions/ql-vscode
        if: matrix.os == 'ubuntu-latest'
        run: |
          /usr/bin/xvfb-run npm run cli-integration

      - name: Run CLI tests (Windows)
        working-directory: extensions/ql-vscode
        if: matrix.os == 'windows-latest'
        run: |
          npm run cli-integration
