diff --git a/eng/Version.Details.props b/eng/Version.Details.props index 32c2cafd7a2..961b73629d3 100644 --- a/eng/Version.Details.props +++ b/eng/Version.Details.props @@ -6,7 +6,7 @@ This file should be imported by eng/Versions.props - 12.0.0-beta.26469.3 + 12.0.0-beta.26502.2 18.12.0-1.26468.2 18.12.0-1.26468.2 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b4f61fc08b9..5108ae5b67d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -82,9 +82,9 @@ - + https://github.com/dotnet/arcade - 63c79a28ca6e086d59c5553e7ed69cacb1d52fbd + 967466cae9ae41a6b61431f772d1de23aff20f43 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/common/core-templates/job/helix-job-monitor.yml b/eng/common/core-templates/job/helix-job-monitor.yml index 7417afdf3ea..ef8ee08fbd2 100644 --- a/eng/common/core-templates/job/helix-job-monitor.yml +++ b/eng/common/core-templates/job/helix-job-monitor.yml @@ -63,7 +63,7 @@ parameters: type: boolean default: false -# Azure service connection ID authorized for Helix. Required when +# Workload identity federation service connection name authorized for Helix. Required when # useEntraAuthentication is true. - name: azureSubscription type: string @@ -94,13 +94,12 @@ parameters: type: boolean default: false -# When true, test results are reported to Azure DevOps using the fully qualified test name -# (Namespace.Type.Method) as the stable automatedTestName and the visible title is qualified as -# well (--use-fully-qualified-test-name). Opt-in because it changes AzDO test identity and display; -# primarily useful for frameworks like MSTest whose display name is only the method name. +# When true (the default), test results are reported to Azure DevOps using the fully qualified test +# name (Namespace.Type.Method) as the stable automatedTestName and the visible title is qualified as +# well (--use-fully-qualified-test-name). Set to false to preserve framework-provided display names. - name: useFullyQualifiedTestName type: boolean - default: false + default: true # Controls per-test output attachments. Defaults to Failed. - name: testResultAttachmentMode @@ -136,6 +135,20 @@ jobs: displayName: Monitor Helix Jobs timeoutInMinutes: ${{ parameters.timeoutInMinutes }} continueOnError: ${{ parameters.continueOnError }} + variables: + HELIX_MONITOR_BASE_URI: ${{ parameters.helixBaseUri }} + HELIX_MONITOR_USE_ENTRA_AUTHENTICATION: ${{ parameters.useEntraAuthentication }} + HELIX_MONITOR_POLLING_INTERVAL_SECONDS: ${{ parameters.pollingIntervalSeconds }} + HELIX_MONITOR_FAIL_ON_FAILED_TESTS: ${{ parameters.failWorkItemsWithFailedTests }} + HELIX_MONITOR_ALLOW_NO_HELIX_JOBS: ${{ parameters.allowNoHelixJobs }} + HELIX_MONITOR_USE_FULLY_QUALIFIED_TEST_NAME: ${{ parameters.useFullyQualifiedTestName }} + HELIX_MONITOR_TIMEOUT_IN_MINUTES: ${{ parameters.timeoutInMinutes }} + HELIX_MONITOR_TEST_RESULT_UPLOAD_PARALLELISM: ${{ parameters.testResultUploadParallelism }} + HELIX_MONITOR_ORGANIZATION: ${{ parameters.organization }} + HELIX_MONITOR_REPOSITORY: ${{ parameters.repository }} + HELIX_MONITOR_TEST_RESULT_ATTACHMENT_MODE: ${{ parameters.testResultAttachmentMode }} + HELIX_MONITOR_TOOL_NUPKG_ARTIFACT_NAME: ${{ parameters.toolNupkgArtifactName }} + HELIX_MONITOR_TOOL_COMMAND: ${{ parameters.toolCommand }} ${{ if ne(length(parameters.dependsOn), 0) }}: dependsOn: ${{ parameters.dependsOn }} ${{ if ne(parameters.condition, '') }}: @@ -157,22 +170,6 @@ jobs: - pwsh: throw "azureSubscription must be set when useEntraAuthentication is true." displayName: Validate Helix Entra authentication - - ${{ if eq(parameters.useEntraAuthentication, true) }}: - - task: AzureCLI@2 - displayName: Initialize Helix Entra authentication - inputs: - azureSubscription: ${{ parameters.azureSubscription }} - addSpnToEnvironment: true - scriptType: pscore - scriptLocation: inlineScript - inlineScript: | - if ([string]::IsNullOrWhiteSpace($env:servicePrincipalId) -or [string]::IsNullOrWhiteSpace($env:tenantId)) { - throw "The Helix Azure service connection did not provide a service principal or tenant ID." - } - - Write-Host "##vso[task.setvariable variable=HelixEntraClientId]$env:servicePrincipalId" - Write-Host "##vso[task.setvariable variable=HelixEntraTenantId]$env:tenantId" - - ${{ if ne(parameters.toolNupkgArtifactName, '') }}: - task: DownloadPipelineArtifact@2 displayName: Download Helix Job Monitor artifact @@ -241,76 +238,26 @@ jobs: - bash: ./eng/common/dotnet.sh tool restore displayName: Restore Helix Job Monitor - - bash: | - set -euo pipefail - - toolArgs=( - --helix-base-uri '${{ parameters.helixBaseUri }}' - --use-entra-authentication '${{ parameters.useEntraAuthentication }}' - --polling-interval-seconds '${{ parameters.pollingIntervalSeconds }}' - --fail-on-failed-tests '${{ parameters.failWorkItemsWithFailedTests }}' - --allow-no-helix-jobs '${{ parameters.allowNoHelixJobs }}' - --use-fully-qualified-test-name '${{ parameters.useFullyQualifiedTestName }}' - --max-wait-minutes "$((${{ parameters.timeoutInMinutes }} - 5))" # Set the tool's timeout slightly lower than the Azure DevOps job timeout to allow it to exit gracefully. - --stage-name '$(System.StageName)' - --stage-attempt '$(System.StageAttempt)' - --job-attempt '$(System.JobAttempt)' - --test-result-upload-parallelism '${{ parameters.testResultUploadParallelism }}' - ) - - organization='${{ parameters.organization }}' - repository='${{ parameters.repository }}' - testResultAttachmentMode='${{ parameters.testResultAttachmentMode }}' - - # Fall back to Azure DevOps-provided environment variables when the caller did not - # supply organization / repository explicitly. BUILD_REPOSITORY_NAME is typically - # 'owner/repo' for GitHub-backed builds and 'owner-repo' for internal builds. - if [ -z "$organization" ] || [ -z "$repository" ]; then - buildRepoName="${BUILD_REPOSITORY_NAME:-}" - if [ -n "$buildRepoName" ] && [[ "$buildRepoName" == */* ]]; then - repoOwner="${buildRepoName%%/*}" - repoName="${buildRepoName#*/}" - elif [ -n "$buildRepoName" ] && [[ "$buildRepoName" == *-* ]]; then - repoOwner="${buildRepoName%%-*}" - repoName="${buildRepoName#*-}" - fi - - if [ -n "${repoOwner:-}" ] && [ -n "${repoName:-}" ]; then - if [ -z "$organization" ]; then organization="$repoOwner"; fi - if [ -z "$repository" ]; then repository="$repoName"; fi - fi - fi - - if [ -n "$organization" ]; then toolArgs+=( --organization "$organization" ); fi - if [ -n "$repository" ]; then toolArgs+=( --repository "$repository" ); fi - if [ -n "$testResultAttachmentMode" ]; then - toolArgs+=( --test-result-attachment-mode "$testResultAttachmentMode" ) - fi - - # Build.Reason and Build.SourceBranch are required to derive the Helix source filter - # the same way the Helix SDK submitter does (PR -> 'pr', internal -> 'official', - # otherwise -> 'ci'). Without these, manually-queued / scheduled / CI builds would - # be looked up under the wrong source prefix and find zero jobs. - toolArgs+=( --build-reason "$(Build.Reason)" ) - toolArgs+=( --source-branch "$(Build.SourceBranch)" ) - - if [ -n '${{ parameters.toolNupkgArtifactName }}' ]; then - # Tool was installed from a local nupkg; run the DLL via the repo-local dotnet. - export DOTNET_ROOT="$(Build.SourcesDirectory)/.dotnet" - ./eng/common/dotnet.sh exec "$(HelixJobMonitorDll)" "${toolArgs[@]}" - else - # Tool was restored from the local .config/dotnet-tools.json manifest; invoke it - # through the manifest from the repo root. - pushd "$BUILD_SOURCESDIRECTORY" > /dev/null - trap 'popd > /dev/null' EXIT - ./eng/common/dotnet.sh tool run '${{ parameters.toolCommand }}' -- "${toolArgs[@]}" - fi - displayName: Monitor Helix Jobs - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - ${{ if eq(parameters.useEntraAuthentication, false) }}: + - ${{ if eq(parameters.useEntraAuthentication, true) }}: + - task: AzureCLI@2 + displayName: Monitor Helix Jobs + inputs: + azureSubscription: ${{ parameters.azureSubscription }} + keepAzSessionActive: true + scriptType: bash + scriptLocation: inlineScript + inlineScript: | + set -euo pipefail + + # AzureCLI@2 replaces SYSTEM_ACCESSTOKEN with the service connection token. + export SYSTEM_ACCESSTOKEN="$HELIX_AZDO_ACCESSTOKEN" + bash "$BUILD_SOURCESDIRECTORY/eng/common/run-helix-job-monitor.sh" + env: + HELIX_AZDO_ACCESSTOKEN: $(System.AccessToken) + + - ${{ if eq(parameters.useEntraAuthentication, false) }}: + - bash: bash "$BUILD_SOURCESDIRECTORY/eng/common/run-helix-job-monitor.sh" + displayName: Monitor Helix Jobs + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) HELIX_ACCESSTOKEN: ${{ parameters.helixAccessToken }} - ${{ if eq(parameters.useEntraAuthentication, true) }}: - AZURESUBSCRIPTION_CLIENT_ID: $(HelixEntraClientId) - AZURESUBSCRIPTION_TENANT_ID: $(HelixEntraTenantId) - AZURESUBSCRIPTION_SERVICE_CONNECTION_ID: ${{ parameters.azureSubscription }} diff --git a/eng/common/core-templates/stages/renovate.yml b/eng/common/core-templates/stages/renovate.yml index cfa9683794a..e046d1be030 100644 --- a/eng/common/core-templates/stages/renovate.yml +++ b/eng/common/core-templates/stages/renovate.yml @@ -60,7 +60,7 @@ parameters: # Renovate version used in the container image tag. - name: renovateVersion - default: 43 + default: 44 type: number # Pool configuration for SDL analysis. diff --git a/eng/common/core-templates/steps/send-to-helix.yml b/eng/common/core-templates/steps/send-to-helix.yml index 62cce4d4ea2..dba2f1b0afa 100644 --- a/eng/common/core-templates/steps/send-to-helix.yml +++ b/eng/common/core-templates/steps/send-to-helix.yml @@ -6,7 +6,7 @@ parameters: HelixTargetQueues: '' # required -- semicolon-delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues HelixAccessToken: '' # optional -- legacy access token; not forwarded when HelixUseEntraAuthentication is true HelixUseEntraAuthentication: false # optional -- use refreshable Entra authentication instead of a PAT or anonymous access - HelixAzureSubscription: '' # required when HelixUseEntraAuthentication is true -- Azure service connection ID authorized for Helix + HelixAzureSubscription: '' # required when HelixUseEntraAuthentication is true -- workload identity federation service connection name authorized for Helix HelixProjectPath: 'eng/common/helixpublish.proj' # optional -- path to the project file to build relative to BUILD_SOURCESDIRECTORY HelixProjectArguments: '' # optional -- arguments passed to the build command HelixConfiguration: '' # optional -- additional property attached to a job @@ -41,106 +41,176 @@ steps: - ${{ if eq(parameters.HelixUseEntraAuthentication, true) }}: - task: AzureCLI@2 - displayName: Initialize Helix Entra authentication + displayName: ${{ parameters.DisplayNamePrefix }} (Windows) inputs: azureSubscription: ${{ parameters.HelixAzureSubscription }} - addSpnToEnvironment: true + keepAzSessionActive: true scriptType: pscore scriptLocation: inlineScript inlineScript: | - if ([string]::IsNullOrWhiteSpace($env:servicePrincipalId) -or [string]::IsNullOrWhiteSpace($env:tenantId)) { - throw "The Helix Azure service connection did not provide a service principal or tenant ID." - } + # AzureCLI@2 replaces SYSTEM_ACCESSTOKEN with the service connection token. + $env:SYSTEM_ACCESSTOKEN = $env:HELIX_AZDO_ACCESSTOKEN - Write-Host "##vso[task.setvariable variable=HelixEntraClientId]$env:servicePrincipalId" - Write-Host "##vso[task.setvariable variable=HelixEntraTenantId]$env:tenantId" - condition: ${{ parameters.condition }} + $(Build.SourcesDirectory)\eng\common\msbuild.ps1 ` + $(Build.SourcesDirectory)/${{ parameters.HelixProjectPath }} ` + /restore ` + /p:TreatWarningsAsErrors=false ` + /p:EnableHelixJobMonitor=${{ parameters.UseHelixMonitor }} ` + /p:HelixUseEntraAuthentication=${{ parameters.HelixUseEntraAuthentication }} ` + ${{ parameters.HelixProjectArguments }} ` + /t:Test ` + /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog + env: + BuildConfig: $(_BuildConfig) + HelixSource: ${{ parameters.HelixSource }} + HelixType: ${{ parameters.HelixType }} + HelixBuild: ${{ parameters.HelixBuild }} + HelixConfiguration: ${{ parameters.HelixConfiguration }} + HelixTargetQueues: ${{ parameters.HelixTargetQueues }} + HelixPreCommands: ${{ parameters.HelixPreCommands }} + HelixPostCommands: ${{ parameters.HelixPostCommands }} + WorkItemDirectory: ${{ parameters.WorkItemDirectory }} + WorkItemCommand: ${{ parameters.WorkItemCommand }} + WorkItemTimeout: ${{ parameters.WorkItemTimeout }} + CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} + XUnitProjects: ${{ parameters.XUnitProjects }} + XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} + XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} + XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} + XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} + IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} + DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} + DotNetCliVersion: ${{ parameters.DotNetCliVersion }} + WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + HelixBaseUri: ${{ parameters.HelixBaseUri }} + Creator: ${{ parameters.Creator }} + HELIX_AZDO_ACCESSTOKEN: $(System.AccessToken) + condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} + - task: AzureCLI@2 + displayName: ${{ parameters.DisplayNamePrefix }} (Unix) + inputs: + azureSubscription: ${{ parameters.HelixAzureSubscription }} + keepAzSessionActive: true + scriptType: bash + scriptLocation: inlineScript + inlineScript: | + # AzureCLI@2 replaces SYSTEM_ACCESSTOKEN with the service connection token. + export SYSTEM_ACCESSTOKEN="$HELIX_AZDO_ACCESSTOKEN" + + $(Build.SourcesDirectory)/eng/common/msbuild.sh \ + $(Build.SourcesDirectory)/${{ parameters.HelixProjectPath }} \ + /restore \ + /p:TreatWarningsAsErrors=false \ + /p:EnableHelixJobMonitor=${{ parameters.UseHelixMonitor }} \ + /p:HelixUseEntraAuthentication=${{ parameters.HelixUseEntraAuthentication }} \ + ${{ parameters.HelixProjectArguments }} \ + /t:Test \ + /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog + env: + BuildConfig: $(_BuildConfig) + HelixSource: ${{ parameters.HelixSource }} + HelixType: ${{ parameters.HelixType }} + HelixBuild: ${{ parameters.HelixBuild }} + HelixConfiguration: ${{ parameters.HelixConfiguration }} + HelixTargetQueues: ${{ parameters.HelixTargetQueues }} + HelixPreCommands: ${{ parameters.HelixPreCommands }} + HelixPostCommands: ${{ parameters.HelixPostCommands }} + WorkItemDirectory: ${{ parameters.WorkItemDirectory }} + WorkItemCommand: ${{ parameters.WorkItemCommand }} + WorkItemTimeout: ${{ parameters.WorkItemTimeout }} + CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} + XUnitProjects: ${{ parameters.XUnitProjects }} + XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} + XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} + XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} + XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} + IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} + DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} + DotNetCliVersion: ${{ parameters.DotNetCliVersion }} + WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + HelixBaseUri: ${{ parameters.HelixBaseUri }} + Creator: ${{ parameters.Creator }} + HELIX_AZDO_ACCESSTOKEN: $(System.AccessToken) + condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} - - powershell: > - $(Build.SourcesDirectory)\eng\common\msbuild.ps1 - $(Build.SourcesDirectory)/${{ parameters.HelixProjectPath }} - /restore - /p:TreatWarningsAsErrors=false - /p:EnableHelixJobMonitor=${{ parameters.UseHelixMonitor }} - /p:HelixUseEntraAuthentication=${{ parameters.HelixUseEntraAuthentication }} - ${{ parameters.HelixProjectArguments }} - /t:Test - /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog - displayName: ${{ parameters.DisplayNamePrefix }} (Windows) - env: - BuildConfig: $(_BuildConfig) - HelixSource: ${{ parameters.HelixSource }} - HelixType: ${{ parameters.HelixType }} - HelixBuild: ${{ parameters.HelixBuild }} - HelixConfiguration: ${{ parameters.HelixConfiguration }} - HelixTargetQueues: ${{ parameters.HelixTargetQueues }} - ${{ if eq(parameters.HelixUseEntraAuthentication, false) }}: + - ${{ if eq(parameters.HelixUseEntraAuthentication, false) }}: + - powershell: > + $(Build.SourcesDirectory)\eng\common\msbuild.ps1 + $(Build.SourcesDirectory)/${{ parameters.HelixProjectPath }} + /restore + /p:TreatWarningsAsErrors=false + /p:EnableHelixJobMonitor=${{ parameters.UseHelixMonitor }} + /p:HelixUseEntraAuthentication=${{ parameters.HelixUseEntraAuthentication }} + ${{ parameters.HelixProjectArguments }} + /t:Test + /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog + displayName: ${{ parameters.DisplayNamePrefix }} (Windows) + env: + BuildConfig: $(_BuildConfig) + HelixSource: ${{ parameters.HelixSource }} + HelixType: ${{ parameters.HelixType }} + HelixBuild: ${{ parameters.HelixBuild }} + HelixConfiguration: ${{ parameters.HelixConfiguration }} + HelixTargetQueues: ${{ parameters.HelixTargetQueues }} HelixAccessToken: ${{ parameters.HelixAccessToken }} - ${{ if eq(parameters.HelixUseEntraAuthentication, true) }}: - AZURESUBSCRIPTION_CLIENT_ID: $(HelixEntraClientId) - AZURESUBSCRIPTION_TENANT_ID: $(HelixEntraTenantId) - AZURESUBSCRIPTION_SERVICE_CONNECTION_ID: ${{ parameters.HelixAzureSubscription }} - HelixPreCommands: ${{ parameters.HelixPreCommands }} - HelixPostCommands: ${{ parameters.HelixPostCommands }} - WorkItemDirectory: ${{ parameters.WorkItemDirectory }} - WorkItemCommand: ${{ parameters.WorkItemCommand }} - WorkItemTimeout: ${{ parameters.WorkItemTimeout }} - CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} - XUnitProjects: ${{ parameters.XUnitProjects }} - XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} - XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} - XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} - XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} - IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} - DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} - DotNetCliVersion: ${{ parameters.DotNetCliVersion }} - WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} - HelixBaseUri: ${{ parameters.HelixBaseUri }} - Creator: ${{ parameters.Creator }} - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT')) - continueOnError: ${{ parameters.continueOnError }} - - script: > - $(Build.SourcesDirectory)/eng/common/msbuild.sh - $(Build.SourcesDirectory)/${{ parameters.HelixProjectPath }} - /restore - /p:TreatWarningsAsErrors=false - /p:EnableHelixJobMonitor=${{ parameters.UseHelixMonitor }} - /p:HelixUseEntraAuthentication=${{ parameters.HelixUseEntraAuthentication }} - ${{ parameters.HelixProjectArguments }} - /t:Test - /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog - displayName: ${{ parameters.DisplayNamePrefix }} (Unix) - env: - BuildConfig: $(_BuildConfig) - HelixSource: ${{ parameters.HelixSource }} - HelixType: ${{ parameters.HelixType }} - HelixBuild: ${{ parameters.HelixBuild }} - HelixConfiguration: ${{ parameters.HelixConfiguration }} - HelixTargetQueues: ${{ parameters.HelixTargetQueues }} - ${{ if eq(parameters.HelixUseEntraAuthentication, false) }}: + HelixPreCommands: ${{ parameters.HelixPreCommands }} + HelixPostCommands: ${{ parameters.HelixPostCommands }} + WorkItemDirectory: ${{ parameters.WorkItemDirectory }} + WorkItemCommand: ${{ parameters.WorkItemCommand }} + WorkItemTimeout: ${{ parameters.WorkItemTimeout }} + CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} + XUnitProjects: ${{ parameters.XUnitProjects }} + XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} + XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} + XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} + XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} + IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} + DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} + DotNetCliVersion: ${{ parameters.DotNetCliVersion }} + WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + HelixBaseUri: ${{ parameters.HelixBaseUri }} + Creator: ${{ parameters.Creator }} + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} + - script: > + $(Build.SourcesDirectory)/eng/common/msbuild.sh + $(Build.SourcesDirectory)/${{ parameters.HelixProjectPath }} + /restore + /p:TreatWarningsAsErrors=false + /p:EnableHelixJobMonitor=${{ parameters.UseHelixMonitor }} + /p:HelixUseEntraAuthentication=${{ parameters.HelixUseEntraAuthentication }} + ${{ parameters.HelixProjectArguments }} + /t:Test + /bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/SendToHelix.binlog + displayName: ${{ parameters.DisplayNamePrefix }} (Unix) + env: + BuildConfig: $(_BuildConfig) + HelixSource: ${{ parameters.HelixSource }} + HelixType: ${{ parameters.HelixType }} + HelixBuild: ${{ parameters.HelixBuild }} + HelixConfiguration: ${{ parameters.HelixConfiguration }} + HelixTargetQueues: ${{ parameters.HelixTargetQueues }} HelixAccessToken: ${{ parameters.HelixAccessToken }} - ${{ if eq(parameters.HelixUseEntraAuthentication, true) }}: - AZURESUBSCRIPTION_CLIENT_ID: $(HelixEntraClientId) - AZURESUBSCRIPTION_TENANT_ID: $(HelixEntraTenantId) - AZURESUBSCRIPTION_SERVICE_CONNECTION_ID: ${{ parameters.HelixAzureSubscription }} - HelixPreCommands: ${{ parameters.HelixPreCommands }} - HelixPostCommands: ${{ parameters.HelixPostCommands }} - WorkItemDirectory: ${{ parameters.WorkItemDirectory }} - WorkItemCommand: ${{ parameters.WorkItemCommand }} - WorkItemTimeout: ${{ parameters.WorkItemTimeout }} - CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} - XUnitProjects: ${{ parameters.XUnitProjects }} - XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} - XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} - XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} - XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} - IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} - DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} - DotNetCliVersion: ${{ parameters.DotNetCliVersion }} - WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} - HelixBaseUri: ${{ parameters.HelixBaseUri }} - Creator: ${{ parameters.Creator }} - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT')) - continueOnError: ${{ parameters.continueOnError }} + HelixPreCommands: ${{ parameters.HelixPreCommands }} + HelixPostCommands: ${{ parameters.HelixPostCommands }} + WorkItemDirectory: ${{ parameters.WorkItemDirectory }} + WorkItemCommand: ${{ parameters.WorkItemCommand }} + WorkItemTimeout: ${{ parameters.WorkItemTimeout }} + CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} + XUnitProjects: ${{ parameters.XUnitProjects }} + XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} + XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} + XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} + XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} + IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} + DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} + DotNetCliVersion: ${{ parameters.DotNetCliVersion }} + WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + HelixBaseUri: ${{ parameters.HelixBaseUri }} + Creator: ${{ parameters.Creator }} + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh index 3fea306bc2a..3ce35ed12fd 100755 --- a/eng/common/cross/build-rootfs.sh +++ b/eng/common/cross/build-rootfs.sh @@ -532,7 +532,7 @@ ensureDownloadTool() } if [[ "$__CodeName" == "alpine" ]]; then - __ApkToolsVersion=2.14.4-r1 + __ApkToolsVersion=3.0.8-r0 __ApkToolsDir="$(mktemp -d)" __ApkKeysDir="$(mktemp -d)" arch="$(uname -m)" @@ -540,7 +540,7 @@ if [[ "$__CodeName" == "alpine" ]]; then ensureDownloadTool __ApkToolsPackage="$__ApkToolsDir/apk-tools-static.apk" - __ApkToolsUrl="$__AlpineRepo/v3.20/main/$arch/apk-tools-static-$__ApkToolsVersion.apk" + __ApkToolsUrl="$__AlpineRepo/v3.24/main/$arch/apk-tools-static-$__ApkToolsVersion.apk" if [[ "$__hasWget" == 1 ]]; then wget -O "$__ApkToolsPackage" "$__ApkToolsUrl" @@ -549,9 +549,9 @@ if [[ "$__CodeName" == "alpine" ]]; then fi if [[ "$arch" == "x86_64" ]]; then - __ApkToolsSHA512SUM="b1b3cc382aa0ec26a2c24b742701a1f9885d0678365f9aea15d3d005926b06ecc802659cec8a7deba2717af99c19c708a17c23e1f0f07742268ee5be5400eb9e" + __ApkToolsSHA512SUM="6ab4f5e521efbfff75a4b0ecc6a028b4df0c22eadc46c18a30fa03faca0f6efd6c546b3682a856e66865f0152993a9cc843c15633a7d01b6e0f9d225b1e31ef8" elif [[ "$arch" == "aarch64" ]]; then - __ApkToolsSHA512SUM="61f9a636c5ac4e96e7a3f69fd65e60fc57b3ec8b23619c4df86f59b89e71d1309b3e406388945bdf0dd9168dac22df376943a70ff3efa179e5687e586f825fb0" + __ApkToolsSHA512SUM="c592bfefe3b3bc73d56fef5293a2c5c27a71d0555df7ca7db638a70c7ac81be6509f6348f28fe7474ae9adbda6f21c00a8c20d8a6ba6d5579f2ffa78d55184d2" else >&2 echo "ERROR: Unsupported apk-tools-static host architecture '$arch'." exit 1 diff --git a/eng/common/cross/toolchain.cmake b/eng/common/cross/toolchain.cmake index 70b71395e3b..ba770710900 100644 --- a/eng/common/cross/toolchain.cmake +++ b/eng/common/cross/toolchain.cmake @@ -6,6 +6,7 @@ unset(FREEBSD) unset(OPENBSD) unset(ILLUMOS) unset(ANDROID) +unset(OPENHARMONY) unset(TIZEN) unset(HAIKU) @@ -35,6 +36,8 @@ if(EXISTS ${CROSS_ROOTFS}/etc/tizen-release) set(TIZEN 1) elseif(EXISTS ${CROSS_ROOTFS}/android_platform) set(ANDROID 1) +elseif(EXISTS ${CROSS_ROOTFS}/../build/cmake/ohos.toolchain.cmake) + set(OPENHARMONY 1) endif() if(TARGET_ARCH_NAME STREQUAL "arm") @@ -204,6 +207,17 @@ if(ANDROID) # include official NDK toolchain script include(${CROSS_ROOTFS}/../build/cmake/android.toolchain.cmake) +elseif(OPENHARMONY) + if(TARGET_ARCH_NAME STREQUAL "arm") + set(OHOS_ARCH armeabi-v7a) + elseif(TARGET_ARCH_NAME STREQUAL "arm64") + set(OHOS_ARCH arm64-v8a) + elseif(TARGET_ARCH_NAME STREQUAL "x64") + set(OHOS_ARCH x86_64) + endif() + + # include official OHOS NDK toolchain script + include(${CROSS_ROOTFS}/../build/cmake/ohos.toolchain.cmake) elseif(FREEBSD OR OPENBSD) # we cross-compile by instructing clang set(CMAKE_C_COMPILER_TARGET ${TOOLCHAIN}) @@ -308,7 +322,7 @@ endif() # Specify compile options -if((TARGET_ARCH_NAME MATCHES "^(arm|arm64|armel|armv6|loongarch64|ppc64le|riscv64|s390x|x64|x86)$" AND NOT ANDROID AND NOT FREEBSD AND NOT OPENBSD) OR ILLUMOS OR HAIKU) +if((TARGET_ARCH_NAME MATCHES "^(arm|arm64|armel|armv6|loongarch64|ppc64le|riscv64|s390x|x64|x86)$" AND NOT ANDROID AND NOT OPENHARMONY AND NOT FREEBSD AND NOT OPENBSD) OR ILLUMOS OR HAIKU) set(CMAKE_C_COMPILER_TARGET ${TOOLCHAIN}) set(CMAKE_CXX_COMPILER_TARGET ${TOOLCHAIN}) set(CMAKE_ASM_COMPILER_TARGET ${TOOLCHAIN}) diff --git a/eng/common/native/init-distro-rid.sh b/eng/common/native/init-distro-rid.sh index 8fc6d2fec78..abb3e231173 100644 --- a/eng/common/native/init-distro-rid.sh +++ b/eng/common/native/init-distro-rid.sh @@ -41,6 +41,9 @@ getNonPortableDistroRid() nonPortableRid="freebsd.$__freebsd_major_version-${targetArch}" elif [ "$targetOs" = "openbsd" ]; then nonPortableRid="openbsd.$(uname -r)-${targetArch}" + elif [ "$targetOs" = "openharmony" ] && command -v param >/dev/null && param get const.ohos.fullname 2>/dev/null | grep -qi '^openharmony'; then + __openharmony_api_version=$(param get const.ohos.apiversion | tr -d '[:space:]') + nonPortableRid="openharmony.$__openharmony_api_version-${targetArch}" elif command -v getprop >/dev/null && getprop ro.product.system.model | grep -qi android; then __android_sdk_version=$(getprop ro.build.version.sdk) nonPortableRid="android.$__android_sdk_version-${targetArch}" @@ -101,10 +104,14 @@ initDistroRidGlobal() STRINGS="$(command -v llvm-strings || true)" fi - # Check for musl-based distros (e.g. Alpine Linux, Void Linux). - if "${rootfsDir}/usr/bin/ldd" --version 2>&1 | grep -q musl || - ( [ -n "$STRINGS" ] && "$STRINGS" "${rootfsDir}/usr/bin/ldd" 2>&1 | grep -q musl ); then - __PortableTargetOS="linux-musl" + # Check for musl-based distros (e.g. Alpine Linux, Void Linux). Only linux targets + # have a musl/glibc portable flavor; skip the check for other targets so that a + # musl-based build host does not clobber their portable OS (e.g. openharmony). + if [ "$targetOs" = "linux" ]; then + if "${rootfsDir}/usr/bin/ldd" --version 2>&1 | grep -q musl || + ( [ -n "$STRINGS" ] && "$STRINGS" "${rootfsDir}/usr/bin/ldd" 2>&1 | grep -q musl ); then + __PortableTargetOS="linux-musl" + fi fi fi diff --git a/eng/common/native/init-os-and-arch.sh b/eng/common/native/init-os-and-arch.sh index 62d62fed522..c3e21228436 100644 --- a/eng/common/native/init-os-and-arch.sh +++ b/eng/common/native/init-os-and-arch.sh @@ -7,9 +7,17 @@ if command -v getprop && getprop ro.product.system.model 2>&1 | grep -qi android OSName="android" fi +# OpenHarmony/HarmonyOS hosts report `HarmonyOS` (or `Linux` on some devices) +# from uname, so query the OHOS parameter service as well. +if command -v param >/dev/null 2>&1 && param get const.ohos.fullname 2>/dev/null | grep -qi '^openharmony'; then + OSName="openharmony" +fi + case "$OSName" in freebsd|linux|netbsd|openbsd|sunos|android|haiku) os="$OSName" ;; +harmonyos|openharmony) + os=openharmony ;; darwin) os=osx ;; *) diff --git a/eng/common/run-helix-job-monitor.sh b/eng/common/run-helix-job-monitor.sh new file mode 100644 index 00000000000..dda140bc9a4 --- /dev/null +++ b/eng/common/run-helix-job-monitor.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +set -euo pipefail + +scriptroot="$(cd -P "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +. "$scriptroot/pipeline-logging-functions.sh" + +toolArgs=( + --helix-base-uri "$HELIX_MONITOR_BASE_URI" + --use-entra-authentication "$HELIX_MONITOR_USE_ENTRA_AUTHENTICATION" + --polling-interval-seconds "$HELIX_MONITOR_POLLING_INTERVAL_SECONDS" + --fail-on-failed-tests "$HELIX_MONITOR_FAIL_ON_FAILED_TESTS" + --allow-no-helix-jobs "$HELIX_MONITOR_ALLOW_NO_HELIX_JOBS" + --use-fully-qualified-test-name "$HELIX_MONITOR_USE_FULLY_QUALIFIED_TEST_NAME" + --max-wait-minutes "$((HELIX_MONITOR_TIMEOUT_IN_MINUTES - 5))" + --stage-name "$SYSTEM_STAGENAME" + --stage-attempt "$SYSTEM_STAGEATTEMPT" + --job-attempt "$SYSTEM_JOBATTEMPT" + --test-result-upload-parallelism "$HELIX_MONITOR_TEST_RESULT_UPLOAD_PARALLELISM" +) + +organization="${HELIX_MONITOR_ORGANIZATION:-}" +repository="${HELIX_MONITOR_REPOSITORY:-}" + +# Fall back to Azure DevOps-provided environment variables when the caller did not +# supply organization or repository explicitly. +if [ -z "$organization" ] || [ -z "$repository" ]; then + buildRepoName="${BUILD_REPOSITORY_NAME:-}" + if [ -n "$buildRepoName" ] && [[ "$buildRepoName" == */* ]]; then + repoOwner="${buildRepoName%%/*}" + repoName="${buildRepoName#*/}" + elif [ -n "$buildRepoName" ] && [[ "$buildRepoName" == *-* ]]; then + repoOwner="${buildRepoName%%-*}" + repoName="${buildRepoName#*-}" + fi + + if [ -n "${repoOwner:-}" ] && [ -n "${repoName:-}" ]; then + if [ -z "$organization" ]; then organization="$repoOwner"; fi + if [ -z "$repository" ]; then repository="$repoName"; fi + fi +fi + +if [ -n "$organization" ]; then toolArgs+=( --organization "$organization" ); fi +if [ -n "$repository" ]; then toolArgs+=( --repository "$repository" ); fi +if [ -n "${HELIX_MONITOR_TEST_RESULT_ATTACHMENT_MODE:-}" ]; then + toolArgs+=( --test-result-attachment-mode "$HELIX_MONITOR_TEST_RESULT_ATTACHMENT_MODE" ) +fi + +# These values let the monitor derive the same Helix source filter as the SDK submitter. +toolArgs+=( --build-reason "$BUILD_REASON" ) +toolArgs+=( --source-branch "$BUILD_SOURCEBRANCH" ) + +cd "$BUILD_SOURCESDIRECTORY" +exitCode=0 +if [ -n "${HELIX_MONITOR_TOOL_NUPKG_ARTIFACT_NAME:-}" ]; then + export DOTNET_ROOT="$BUILD_SOURCESDIRECTORY/.dotnet" + ./eng/common/dotnet.sh exec "$HELIXJOBMONITORDLL" "${toolArgs[@]}" || exitCode=$? +else + ./eng/common/dotnet.sh tool run "$HELIX_MONITOR_TOOL_COMMAND" -- "${toolArgs[@]}" || exitCode=$? +fi + +if [ "$exitCode" -ne 0 ]; then + Write-PipelineTelemetryError -force -category 'Helix' "Helix job monitor failed (exit code '$exitCode')." + exit "$exitCode" +fi diff --git a/global.json b/global.json index be37a7e7f87..7d02fc0be9f 100644 --- a/global.json +++ b/global.json @@ -23,7 +23,7 @@ "xcopy-msbuild": "18.0.0" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "12.0.0-beta.26469.3", + "Microsoft.DotNet.Arcade.Sdk": "12.0.0-beta.26502.2", "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23255.2" } }