trigger:
  branches:
    include:
    - main
    - main-vs-deps
    - release/dev16.*-vs-deps
    - release/dev17.*
    - release/dev18.*
    - features/lsp_tools_host
    exclude:
    - release/dev17.0
pr: none

resources:
  repositories:
  - repository: 1ESPipelineTemplates
    type: git
    name: 1ESPipelineTemplates/1ESPipelineTemplates
    ref: refs/tags/release
  pipelines:
    - pipeline: profilingInputs
      source: dotnet-vscode-csharp-profiling
      branch: main
      trigger: none

parameters:
- name: IbcDrop
  type: string
  default: default

- name: SignType
  default: real
  type: string
  values:
  - real
  - test

- name: SkipApplyOptimizationData
  type: boolean
  default: false

- name: SkipTests
  type: boolean
  default: true

schedules:
  - cron: "0 8 23-29 * 0"
    displayName: "Monthly smoke test"
    branches:
      include: 
        - main
        - release/*
      exclude: 
        - ""
    always: true # Run even if there have been no source code changes since the last successful scheduled run
    batch: false # Do not run the pipeline if the previously scheduled run is in-progress

variables:
  - group: DotNet-Roslyn-SDLValidation-Params
  - name: Codeql.Enabled
    value: true

  # To retrieve OptProf data we need to authenticate to the VS drop storage.
  # Get access token with $dn-bot-devdiv-drop-rw-code-rw and dn-bot-dnceng-build-rw-code-rw from DotNet-VSTS-Infra-Access
  # Get $AccessToken-dotnet-build-bot-public-repo from DotNet-Versions-Publish
  - group: DotNet-Versions-Publish
  - group: DotNet-VSTS-Infra-Access
  - group: DotNet-DevDiv-Insertion-Workflow-Variables
  - group: AzureDevOps-Artifact-Feeds-Pats
  - name: _DevDivDropAccessToken
    value: $(dn-bot-devdiv-drop-rw-code-rw)
  - name: ArtifactServices.Drop.PAT
    value: $(dn-bot-devdiv-drop-rw-code-rw)
  - group: DotNet-Roslyn-Insertion-Variables
  - group: AzureDevOps-Artifact-Feeds-Pats

  - name: BuildConfiguration
    value: release
  - name: Roslyn.GitHubEmail
    value: dotnet-build-bot@microsoft.com
  - name: Roslyn.GitHubToken
    value: $(AccessToken-dotnet-build-bot-public-repo)
  - name: Roslyn.GitHubUserName
    value: dotnet-build-bot

  - name: Insertion.InsertToolset
    value: true
  - name: Insertion.CreateDraftPR
    value: true
  - name: Insertion.TitlePrefix
    value: '[Auto Insertion]'
  - name: Insertion.TitleSuffix
    value: ''

  - ${{ if and(notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.SourceBranch'], 'refs/heads/main')) }}:
    - name: enableSourceIndex
      value: true
  - name: VSCodeOptimizationDataRoot
    value: $(Pipeline.Workspace)/profilingInputs/merged mibc


extends:
  template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates
  parameters:
    featureFlags:
      autoBaseline: true
    sdl:
      sourceAnalysisPool:
        name: NetCore1ESPool-Svc-Internal
        image: 1es-windows-2022
        os: windows
      sbom:
        enabled: false
      suppression:
        suppressionFile: $(Build.SourcesDirectory)\eng\config\guardian\.gdnsuppres
      policheck:
          enabled: true
      tsa:
        enabled: true
        configFile: '$(Build.SourcesDirectory)/eng/TSAConfig.gdntsa'
    pool:
      name: NetCore1ESPool-Svc-Internal
      image: windows.vs2022preview.amd64
      os: windows
    customBuildTags:
    - ES365AIMigrationTooling
    stages:

    - stage: build
      displayName: Build and Test

      jobs:
      - ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/release/dev17.13') }}:
        - template: /eng/common/templates-official/job/onelocbuild.yml@self
          parameters:
            MirrorRepo: roslyn
            MirrorBranch: release/dev17.13
            LclSource: lclFilesfromPackage
            LclPackageId: 'LCL-JUNO-PROD-ROSLYN'

      - template: /eng/common/templates-official/jobs/source-build.yml@self

      - job: OfficialBuild
        displayName: Official Build
        timeoutInMinutes: 360
        templateContext:
          outputs:

          # Publish OptProf generated JSON files as a pipeline artifact. This allows for easy inspection from
          # a build execution.
          - output: pipelineArtifact
            displayName: 'Publish OptProf Data Files'
            condition: succeeded()
            targetPath: '$(Build.SourcesDirectory)\artifacts\OptProf\$(BuildConfiguration)\Data'
            artifactName: 'OptProf Data Files'

          - output: pipelineArtifact
            displayName: 'Publish Logs'
            condition: succeededOrFailed()
            targetPath: '$(Build.SourcesDirectory)\artifacts\log\$(BuildConfiguration)'
            artifactName: 'Build Diagnostic Files'
            publishLocation: Container

          - output: pipelineArtifact
            displayName: 'Publish Ngen Logs'
            condition: succeeded()
            targetPath: '$(Build.SourcesDirectory)\artifacts\log\$(BuildConfiguration)\ngen'
            artifactName: 'NGen Logs'
            publishLocation: Container

          # Publishes setup VSIXes to a drop.
          # Note: The insertion tool looks for the display name of this task in the logs.
          - output: microBuildVstsDrop
            displayName: Upload VSTS Drop
            condition: succeeded()
            dropFolder: 'artifacts\VSSetup\$(BuildConfiguration)\Insertion'
            dropName: $(VisualStudio.DropName)
            accessToken: $(_DevDivDropAccessToken)
            dropRetentionDays: 90

          # Publish insertion packages to CoreXT store.
          - output: nuget
            displayName: 'Publish CoreXT Packages'
            condition: succeeded()
            packageParentPath: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(BuildConfiguration)\DevDivPackages'
            packagesToPush: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(BuildConfiguration)\DevDivPackages\**\*.nupkg'
            allowPackageConflicts: true
            nuGetFeedType: external
            publishFeedCredentials: 'DevDiv - VS package feed'

          # Publish an artifact that the RoslynInsertionTool is able to find by its name.
          - output: pipelineArtifact
            displayName: 'Publish Artifact VSSetup'
            condition: succeeded()
            targetPath: 'artifacts\VSSetup\$(BuildConfiguration)'
            artifactName: 'VSSetup'

          # Publish our NuPkgs as an artifact. The name of this artifact must be PackageArtifacts as the
          # arcade templates depend on the name.
          - output: buildArtifacts
            displayName: 'Publish Artifact Packages'
            condition: succeeded()
            PathtoPublish: 'artifacts\packages\$(BuildConfiguration)'
            ArtifactName: 'PackageArtifacts'

          # Publish Asset Manifests for Build Asset Registry job
          - output: buildArtifacts
            displayName: 'Publish Asset Manifests'
            condition: succeeded()
            PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(BuildConfiguration)/AssetManifest'
            ArtifactName: AssetManifests

        steps:
        - pwsh: Set-MpPreference -DisableRealtimeMonitoring $true
          displayName: Disable Real-time Monitoring
          
        - powershell: Write-Host "##vso[task.setvariable variable=SourceBranchName]$('$(Build.SourceBranch)'.Substring('refs/heads/'.Length))"
          displayName: Setting SourceBranchName variable
          condition: succeeded()

        - task: Powershell@2
          displayName: Tag official build
          inputs:
            targetType: inline
            script: |
              Write-Host "##vso[build.addBuildTag]OfficialBuild"
          condition: succeeded()

        # Don't run this while we don't have a main-vs-deps to merge. Should be uncommented when the branch comes back. Also need to change the condition of the tagging task above.
        #
        # - task: Powershell@2
        #  displayName: Tag main validation build
        #  inputs:
        #    targetType: inline
        #    script: |
        #      Write-Host "##vso[build.addBuildTag]MainValidationBuild"
        #  condition: and(succeeded(), eq(variables['SourceBranchName'], 'main'))

        # Don't run this while we don't have a main-vs-deps to merge. Should be uncommented when the branch comes back.
        #
        # - task: PowerShell@2
        #  displayName: Merge main-vs-deps into source branch
        #  inputs:
        #    filePath: 'scripts\merge-vs-deps.ps1'
        #    arguments: '-accessToken $(dn-bot-dnceng-build-rw-code-rw)'
        #  condition: and(succeeded(), eq(variables['SourceBranchName'], 'main'))

        - powershell: Write-Host "##vso[task.setvariable variable=VisualStudio.DropName]Products/$(System.TeamProject)/$(Build.Repository.Name)/$(SourceBranchName)/$(Build.BuildNumber)"
          displayName: Setting VisualStudio.DropName variable

        - task: NodeTool@0
          inputs:
            versionSpec: '16.x'
          displayName: 'Install Node.js'

        - task: NuGetToolInstaller@0
          inputs:
            versionSpec: '4.9.2'

        # Authenticate with service connections to be able to publish packages to external nuget feeds.
        - task: NuGetAuthenticate@1
          inputs:
            nuGetServiceConnections: azure-public/vs-impl, azure-public/vssdk, devdiv/engineering, devdiv/dotnet-core-internal-tooling

        # Needed for SBOM tool
        - task: UseDotNet@2
          displayName: 'Use .NET Core 3.1 runtime'
          inputs:
            packageType: runtime
            version: 3.1.28
            installationPath: '$(Build.SourcesDirectory)\.dotnet'

        # Needed because the build fails the NuGet Tools restore without it
        - task: UseDotNet@2
          displayName: 'Use .NET Core sdk'
          inputs:
            packageType: sdk
            useGlobalJson: true
            workingDirectory: '$(Build.SourcesDirectory)'

        - task: MicroBuildSigningPlugin@4
          inputs:
            signType: $(SignType)
            zipSources: false
            feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json
          condition: and(succeeded(), in(variables['SignType'], 'test', 'real'))

        - download: profilingInputs
          artifact: merged mibc
          displayName: Download VSCode optimization inputs

        - task: PowerShell@2
          displayName: Build
          inputs:
            filePath: eng/build.ps1
            arguments: -ci
                       -prepareMachine
                       -restore
                       -build
                       -pack
                       -sign
                       -publish
                       -binaryLog
                       -configuration $(BuildConfiguration)
                       -officialBuildId $(Build.BuildNumber)
                       -officialSkipTests $(SkipTests)
                       -officialSkipApplyOptimizationData $(SkipApplyOptimizationData)
                       -officialSourceBranchName $(SourceBranchName)
                       -officialIbcDrop $(IbcDrop)
                       -officialVisualStudioDropAccessToken $(_DevDivDropAccessToken)
                       /p:RepositoryName=$(Build.Repository.Name)
                       /p:VisualStudioDropName=$(VisualStudio.DropName)
                       /p:VSCodeOptimizationDataRoot="$(VSCodeOptimizationDataRoot)"
                       /p:DotNetSignType=$(SignType)
                       /p:DotnetPublishUsingPipelines=true
                       /p:IgnoreIbcMergeErrors=true
                       /p:GenerateSbom=true
          condition: succeeded()

        - template: /eng/common/templates-official/steps/generate-sbom.yml@self

        - task: PowerShell@2
          displayName: Publish Assets
          inputs:
            filePath: 'eng\publish-assets.ps1'
            arguments: '-configuration $(BuildConfiguration) -branchName "$(SourceBranchName)"'
          condition: succeeded()

        # Publish OptProf configuration files to the artifact service
        # This uses the ArtifactServices.Drop.PAT build variable which is required to enable cross account access using PAT (dnceng -> devdiv)
        - task: 1ES.PublishArtifactsDrop@1
          inputs:
            dropServiceURI: 'https://devdiv.artifacts.visualstudio.com'
            buildNumber: 'ProfilingInputs/$(System.TeamProject)/$(Build.Repository.Name)/$(SourceBranchName)/$(Build.BuildNumber)'
            sourcePath: '$(Build.SourcesDirectory)\artifacts\OptProf\$(BuildConfiguration)\Data'
            toLowerCase: false
            usePat: false
            retentionDays: 90
          displayName: 'OptProf - Publish to Artifact Services - ProfilingInputs'
          condition: succeeded()

        - task: PublishTestResults@2
          displayName: Publish xUnit Test Results
          inputs:
            testRunner: XUnit
            testResultsFiles: '$(Build.SourcesDirectory)\artifacts\TestResults\$(BuildConfiguration)\*.xml'
            mergeTestResults: true
            testRunTitle: 'Unit Tests'
          condition: and(succeededOrFailed(), ne(variables['SkipTests'], 'true'))

      # Publish to Build Asset Registry
      - template: /eng/common/templates-official/job/publish-build-assets.yml@self
        parameters:
          publishUsingPipelines: true
          dependsOn:
          - OfficialBuild
          pool:
            name: NetCore1ESPool-Svc-Internal
            demands: ImageOverride -equals windows.vs2022.amd64

      - ${{ if eq(variables.enableSourceIndex, 'true') }}:
        - template: /eng/common/templates-official/job/source-index-stage1.yml@self
          parameters:
            sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng\build.ps1 -configuration Release -prepareMachine -ci -restore -build -binaryLogName Build.binlog -skipDocumentation -msbuildEngine dotnet /p:UsingToolVSSDK=false /p:GenerateSatelliteAssemblies=false /p:PublishReadyToRun=false"
            binlogPath: artifacts/log/$(BuildConfiguration)/Build.binlog
            pool:
              name: $(DncEngInternalBuildPool)
              demands: ImageOverride -equals 1es-windows-2022

    - stage: insert
      dependsOn:
      - publish_using_darc
      displayName: Insert to VS

      jobs:
      - job: insert
        displayName: Insert to VS
        steps:
        - download: current
          artifact: VSSetup
        - powershell: |
            $branchName = "$(Build.SourceBranch)".Substring("refs/heads/".Length)
            Write-Host "##vso[task.setvariable variable=ComponentBranchName]$branchName"
          displayName: Get Branch Name
        - template: /eng/pipelines/insert.yml@self
          parameters:
            buildUserName: "dn-bot@microsoft.com"
            buildPassword: $(dn-bot-devdiv-build-e-code-full-release-e-packaging-r)
            componentUserName: "dn-bot@microsoft.com"
            componentPassword: $(dn-bot-dnceng-build-e-code-full-release-e-packaging-r)
            componentBuildProjectName: internal
            sourceBranch: "$(ComponentBranchName)"
            publishDataURI: "https://dev.azure.com/dnceng/internal/_apis/git/repositories/dotnet-roslyn/items?path=eng/config/PublishData.json&api-version=6.0"
            publishDataAccessToken: "$(System.AccessToken)"
            dropPath: '$(Pipeline.Workspace)\VSSetup'

    - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
      - template: /eng/common/templates-official/post-build/post-build.yml@self
        parameters:
          publishingInfraVersion: 3
          # Symbol validation is not entirely reliable as of yet, so should be turned off until
          # https://github.com/dotnet/arcade/issues/2871 is resolved.
          enableSymbolValidation: false
          enableSourceLinkValidation: false
          # Enable SDL validation, passing through values from the 'DotNet-Roslyn-SDLValidation-Params' group.
          SDLValidationParameters:
            enable: true
            params: >-
              -SourceToolsList @("policheck","credscan")
              -ArtifactToolsList @("binskim")
              -BinskimAdditionalRunConfigParams @("IgnorePdbLoadError < True","Recurse < True","SymbolsPath < SRV*https://msdl.microsoft.com/download/symbols")
              -TsaInstanceURL $(_TsaInstanceURL)
              -TsaProjectName $(_TsaProjectName)
              -TsaNotificationEmail $(_TsaNotificationEmail)
              -TsaCodebaseAdmin $(_TsaCodebaseAdmin)
              -TsaBugAreaPath $(_TsaBugAreaPath)
              -TsaIterationPath $(_TsaIterationPath)
              -TsaRepositoryName $(_TsaRepositoryName)
              -TsaCodebaseName $(_TsaCodebaseName)
              -TsaPublish $True