jobs:
  - job: Quality
    displayName: Quality Checks
    timeoutInMinutes: 20
    variables:
      - name: skipComponentGovernanceDetection
        value: true
      - name: Codeql.SkipTaskAutoInjection
        value: true
    steps:
      - template: ./common/checkout.yml@self

      - task: NodeTool@0
        inputs:
          versionSource: fromFile
          versionFilePath: .nvmrc

      - template: ./distro/download-distro.yml@self

      - task: AzureKeyVault@2
        displayName: "Azure Key Vault: Get Secrets"
        inputs:
          azureSubscription: vscode
          KeyVaultName: vscode-build-secrets
          SecretsFilter: "github-distro-mixin-password"

      - script: node build/setup-npm-registry.ts $NPM_REGISTRY
        condition: and(succeeded(), ne(variables['NPM_REGISTRY'], 'none'))
        displayName: Setup NPM Registry

      - script: mkdir -p .build && node build/azure-pipelines/common/computeNodeModulesCacheKey.ts quality $(node -p process.arch) > .build/packagelockhash
        displayName: Prepare node_modules cache key

      - task: Cache@2
        inputs:
          key: '"node_modules" | .build/packagelockhash'
          path: .build/node_modules_cache
          cacheHitVar: NODE_MODULES_RESTORED
        displayName: Restore node_modules cache

      - script: tar -xzf .build/node_modules_cache/cache.tgz
        condition: and(succeeded(), eq(variables.NODE_MODULES_RESTORED, 'true'))
        displayName: Extract node_modules cache

      - script: |
          set -e
          npm config set registry "$NPM_REGISTRY"
          echo "##vso[task.setvariable variable=NPMRC_PATH]$(npm config get userconfig)"
        condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none'))
        displayName: Setup NPM

      - task: npmAuthenticate@0
        inputs:
          workingFile: $(NPMRC_PATH)
        condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'), ne(variables['NPM_REGISTRY'], 'none'))
        displayName: Setup NPM Authentication

      - script: |
          set -e

          for i in {1..5}; do # try 5 times
            npm ci && break
            if [ $i -eq 5 ]; then
              echo "Npm install failed too many times" >&2
              exit 1
            fi
            echo "Npm install failed $i, trying again..."
          done
        workingDirectory: build
        env:
          GITHUB_TOKEN: "$(github-distro-mixin-password)"
        displayName: Install build dependencies
        condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))

      - script: |
          set -e
          export VSCODE_SYSROOT_DIR=$(Build.SourcesDirectory)/.build/sysroots/glibc-2.28-gcc-8.5.0
          SYSROOT_ARCH="amd64" VSCODE_SYSROOT_PREFIX="-glibc-2.28-gcc-8.5.0" node -e 'import { getVSCodeSysroot } from "./build/linux/debian/install-sysroot.ts"; (async () => { await getVSCodeSysroot(process.env["SYSROOT_ARCH"]); })()'
        env:
          VSCODE_ARCH: x64
          GITHUB_TOKEN: "$(github-distro-mixin-password)"
        displayName: Download vscode sysroots

      - script: |
          set -e

          source ./build/azure-pipelines/linux/setup-env.sh
          node build/npm/preinstall.ts

          for i in {1..5}; do # try 5 times
            npm ci && break
            if [ $i -eq 5 ]; then
              echo "Npm install failed too many times" >&2
              exit 1
            fi
            echo "Npm install failed $i, trying again..."
          done
        env:
          npm_config_arch: x64
          VSCODE_ARCH: x64
          ELECTRON_SKIP_BINARY_DOWNLOAD: 1
          PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
          GITHUB_TOKEN: "$(github-distro-mixin-password)"
        displayName: Install dependencies
        condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))

      - script: node build/azure-pipelines/distro/mixin-npm.ts
        condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
        displayName: Mixin distro node modules

      - script: |
          set -e
          node build/azure-pipelines/common/listNodeModules.ts .build/node_modules_list.txt
          mkdir -p .build/node_modules_cache
          tar -czf .build/node_modules_cache/cache.tgz --files-from .build/node_modules_list.txt
        condition: and(succeeded(), ne(variables.NODE_MODULES_RESTORED, 'true'))
        displayName: Create node_modules archive

      - script: node build/azure-pipelines/distro/mixin-quality.ts
        displayName: Mixin distro quality

      - script: node build/azure-pipelines/common/checkDistroCommit.ts
        displayName: Check distro commit
        env:
          GITHUB_TOKEN: "$(github-distro-mixin-password)"
          BUILD_SOURCEBRANCH: "$(Build.SourceBranch)"
        continueOnError: true
        condition: and(succeeded(), eq(lower(variables['VSCODE_PUBLISH']), 'true'))

      - script: node build/azure-pipelines/common/checkCopilotChatCompatibility.ts --warn-only
        displayName: Check Copilot Chat compatibility
        continueOnError: true
        condition: and(succeeded(), eq(lower(variables['VSCODE_PUBLISH']), 'true'))

      - script: npm exec -- npm-run-all2 -lp core-ci hygiene eslint valid-layers-check define-class-fields-check vscode-dts-compile-check tsec-compile-check test-build-scripts
        env:
          GITHUB_TOKEN: "$(github-distro-mixin-password)"
        displayName: Compile & Hygiene

      - script: npm run download-builtin-extensions-cg
        env:
          GITHUB_TOKEN: "$(github-distro-mixin-password)"
        displayName: Download component details of built-in extensions
        condition: and(succeeded(), eq(lower(variables['VSCODE_PUBLISH']), 'true'))

      - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
        displayName: "Component Detection"
        inputs:
          sourceScanPath: $(Build.SourcesDirectory)
          alertWarningLevel: Medium
        continueOnError: true
        condition: and(succeeded(), eq(lower(variables['VSCODE_PUBLISH']), 'true'))

      - task: AzureCLI@2
        displayName: Fetch secrets
        inputs:
          azureSubscription: vscode
          scriptType: pscore
          scriptLocation: inlineScript
          addSpnToEnvironment: true
          inlineScript: |
            Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID]$env:tenantId"
            Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID]$env:servicePrincipalId"
            Write-Host "##vso[task.setvariable variable=AZURE_ID_TOKEN;issecret=true]$env:idToken"
        condition: and(succeeded(), eq(lower(variables['VSCODE_PUBLISH']), 'true'))

      - script: |
          set -e
          AZURE_STORAGE_ACCOUNT="vscodeweb" \
          AZURE_TENANT_ID="$(AZURE_TENANT_ID)" \
          AZURE_CLIENT_ID="$(AZURE_CLIENT_ID)" \
          AZURE_ID_TOKEN="$(AZURE_ID_TOKEN)" \
            node build/azure-pipelines/upload-sourcemaps.ts
        displayName: Upload sourcemaps to Azure
        condition: and(succeeded(), eq(lower(variables['VSCODE_PUBLISH']), 'true'))
