diff --git a/.github/instructions/onebranch-pipeline-design.instructions.md b/.github/instructions/onebranch-pipeline-design.instructions.md index 0860d5db52..f1520fa0e0 100644 --- a/.github/instructions/onebranch-pipeline-design.instructions.md +++ b/.github/instructions/onebranch-pipeline-design.instructions.md @@ -70,6 +70,8 @@ When adding a new csproj-based package: - The `publish-symbols-step.yml` accepts a `symbolsFolder` parameter to point at the downloaded PDB location - The publish step calls an extracted `publish-symbols.ps1` script with structured error handling and diagnostic logging - Symbols publishing credentials come from the `Symbols Publishing` variable group +- In the official pipeline, symbol server destination follows `releaseToProduction`: Production when true, PPE when false +- Non-official pipeline always targets the PPE symbol server ## Release Stage @@ -99,7 +101,9 @@ Release parameters (all boolean, default `false`): - `releaseSqlServerServer`, `releaseLogging`, `releaseAbstractions`, `releaseSqlClient`, `releaseAzure`, `releaseAKVProvider` Official-only parameter: -- `releaseToProduction` — push to NuGet Production feed (default `false`) +- `releaseToProduction` — controls both NuGet target feed and symbol server destination (default `false`): + - `true` → NuGet Production feed + Production symbol server + - `false` → NuGet Test feed + PPE symbol server When `isPreview` is true, pipeline resolves `effective*Version` variables to preview versions; otherwise GA versions. All versions defined in `variables/common-variables.yml`. diff --git a/eng/pipelines/onebranch/jobs/publish-symbols-job.yml b/eng/pipelines/onebranch/jobs/publish-symbols-job.yml index 21b20476cd..de2d7e4634 100644 --- a/eng/pipelines/onebranch/jobs/publish-symbols-job.yml +++ b/eng/pipelines/onebranch/jobs/publish-symbols-job.yml @@ -54,11 +54,13 @@ jobs: - job: publish_symbols_${{ parameters.packageName }} displayName: 'Publish Symbols: ${{ parameters.packageFullName }}' pool: - type: windows + type: linux variables: - # OneBranch requires ob_outputDirectory to be set, even if this job produces no artifacts. - ob_outputDirectory: $(JOB_OUTPUT) + # OneBranch requires ob_outputDirectory to be set. Pipeline Artifacts are always on and + # cannot be disabled. To prevent this job from publishing artifacts, a .artifactignore + # that excludes all files is written into ob_outputDirectory before the auto-publish step. + ob_outputDirectory: $(Build.SourcesDirectory)/no_publish # Disable SDL scanning — this job only uploads/publishes PDBs and produces no # assemblies to scan. APIScan and BinSkim are handled by the build jobs. @@ -72,7 +74,24 @@ jobs: # Path to the PDB files within the downloaded artifact. symbolsPath: $(Pipeline.Workspace)/${{ parameters.artifactName }}/symbols + # PublishSymbols@2 runs on the OneBranch host agent (outside the build container) due to 1ES + # Pipeline Template credential isolation. On Linux, the host resolves to the Microsoft org by + # default. Setting this variable at job level ensures the task sees it and connects to the + # correct org's symbol store. + # + # Reference: + # https://www.osgwiki.com/wiki/Symbols_Publishing_Pipeline_to_SymWeb_and_MSDL#Option_B:_OneBranch + # + ArtifactServices.Symbol.AccountName: ${{ parameters.symbolsUploadAccount }} + steps: + # Create ob_outputDirectory with a .artifactignore that excludes everything, + # so OneBranch's auto-publish uploads an empty artifact. + - pwsh: | + New-Item -Path "$(ob_outputDirectory)" -ItemType Directory -Force + "**" | Out-File -FilePath "$(ob_outputDirectory)/.artifactignore" -Encoding ascii + displayName: 'Suppress artifact publishing' + - task: DownloadPipelineArtifact@2 displayName: 'Download ${{ parameters.packageFullName }} Artifact' inputs: diff --git a/eng/pipelines/onebranch/sqlclient-official.yml b/eng/pipelines/onebranch/sqlclient-official.yml index a2902f1e21..96fb0dc5f5 100644 --- a/eng/pipelines/onebranch/sqlclient-official.yml +++ b/eng/pipelines/onebranch/sqlclient-official.yml @@ -33,9 +33,10 @@ parameters: type: boolean default: false - # Push packages to NuGet Production (otherwise pushes to NuGet Test). + # When true, publish symbols and push NuGet packages to Production environments. When false, + # symbols use PPE and NuGet packages use QA/Test. - name: releaseToProduction - displayName: Release to NuGet Production + displayName: Publish Symbols and NuGet Packages to Production type: boolean default: false @@ -254,9 +255,14 @@ extends: symbolsAzureSubscription: '$(SymbolsAzureSubscription)' symbolsPublishProjectName: '$(SymbolsPublishProjectNameSqlClient)' - # Official pipelines must publish to the Production symbol server. - symbolsPublishServer: '$(SymbolsPublishServerProd)' - symbolsPublishTokenUri: '$(SymbolsPublishTokenUriProd)' + # Symbol server target follows releaseToProduction: Production for + # real releases, PPE for test/QA releases. + ${{ if eq(parameters.releaseToProduction, true) }}: + symbolsPublishServer: '$(SymbolsPublishServerProd)' + symbolsPublishTokenUri: '$(SymbolsPublishTokenUriProd)' + ${{ else }}: + symbolsPublishServer: '$(SymbolsPublishServerPPE)' + symbolsPublishTokenUri: '$(SymbolsPublishTokenUriPPE)' symbolsUploadAccount: '$(SymbolsUploadAccount)' - template: /eng/pipelines/onebranch/stages/release-stages.yml@self diff --git a/eng/pipelines/onebranch/steps/publish-symbols-step.yml b/eng/pipelines/onebranch/steps/publish-symbols-step.yml index d06b3c73e5..dc794f480d 100644 --- a/eng/pipelines/onebranch/steps/publish-symbols-step.yml +++ b/eng/pipelines/onebranch/steps/publish-symbols-step.yml @@ -75,16 +75,16 @@ parameters: type: string steps: - # Set variable for downstream tasks (allegedly). + # NOTE: ArtifactServices.Symbol.AccountName is set as a job-level variable in + # publish-symbols-job.yml. On OneBranch Linux agents, PublishSymbols@2 runs on the host (outside + # the build container) due to 1ES PT credential isolation. A ##vso[task.setvariable] inside the + # container is not visible to host-level tasks, so the variable must be declared at job scope. # - # Note: Because variables cannot be set in top-level of template, this has to be done during - # runtime. - # - - script: 'echo ##vso[task.setvariable variable=ArtifactServices.Symbol.AccountName;]${{ parameters.uploadAccount }}' - displayName: 'Set ArtifactServices.Symbol.AccountName to ${{ parameters.uploadAccount }}' + # Reference: + # https://www.osgwiki.com/wiki/Symbols_Publishing_Pipeline_to_SymWeb_and_MSDL#Option_B:_OneBranch - # Log the PDB files that match the search pattern so we can verify no - # unexpected files are included in the upload. + # Log the PDB files that match the search pattern so we can verify no unexpected files are + # included in the upload. - pwsh: | $folder = '${{ parameters.symbolsFolder }}' $glob = '${{ parameters.searchPattern }}' diff --git a/eng/pipelines/onebranch/variables/onebranch-variables.yml b/eng/pipelines/onebranch/variables/onebranch-variables.yml index b3bebb0a64..d5fa784885 100644 --- a/eng/pipelines/onebranch/variables/onebranch-variables.yml +++ b/eng/pipelines/onebranch/variables/onebranch-variables.yml @@ -39,6 +39,12 @@ variables: - name: Packaging.EnableSBOMSigning value: true - # Docker image which is used to build the project https://aka.ms/obpipelines/containers + # OneBranch supplies a variety of container images we must use for our jobs. + # + # Windows jobs use this image. - name: WindowsContainerImage - value: "onebranch.azurecr.io/windows/ltsc2022/vse2022:latest" + value: onebranch.azurecr.io/windows/ltsc2022/vse2022:latest + + # Linux jobs use this image. + - name: LinuxContainerImage + value: mcr.microsoft.com/onebranch/azurelinux/build:3.0