From e1ac42faa2cf0e797348742c5b4427fd04125677 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 12:42:03 +0000 Subject: [PATCH 1/7] Reset files to feature/net11-scouting Reset patterns: - global.json - eng/Version.Details.xml - eng/Version.Details.props - eng/Versions.props - eng/common/** - eng/TargetFrameworks.props --- eng/TargetFrameworks.props | 2 +- eng/Version.Details.props | 36 +- eng/Version.Details.xml | 72 +-- eng/Versions.props | 7 +- eng/common/SetupNugetSources.ps1 | 17 +- eng/common/SetupNugetSources.sh | 17 +- eng/common/build.ps1 | 2 + eng/common/build.sh | 8 +- eng/common/core-templates/job/job.yml | 8 + .../job/publish-build-assets.yml | 16 +- eng/common/core-templates/job/renovate.yml | 196 +++++++ .../job/source-index-stage1.yml | 4 +- .../core-templates/post-build/post-build.yml | 477 +++++++++--------- eng/common/core-templates/stages/renovate.yml | 111 ++++ .../core-templates/steps/generate-sbom.yml | 2 +- .../steps/install-microbuild-impl.yml | 34 ++ .../steps/install-microbuild.yml | 64 ++- .../core-templates/steps/source-build.yml | 2 +- .../steps/source-index-stage1-publish.yml | 8 +- eng/common/cross/build-rootfs.sh | 81 ++- eng/common/cross/toolchain.cmake | 15 +- eng/common/darc-init.sh | 2 +- eng/common/dotnet-install.sh | 2 +- eng/common/dotnet.sh | 2 +- eng/common/internal-feed-operations.sh | 2 +- eng/common/native/init-distro-rid.sh | 2 + eng/common/native/install-dependencies.sh | 11 +- eng/common/post-build/redact-logs.ps1 | 3 +- eng/common/renovate.env | 42 ++ eng/common/template-guidance.md | 3 - eng/common/tools.ps1 | 18 +- eng/common/tools.sh | 16 +- global.json | 6 +- 33 files changed, 882 insertions(+), 406 deletions(-) create mode 100644 eng/common/core-templates/job/renovate.yml create mode 100644 eng/common/core-templates/stages/renovate.yml create mode 100644 eng/common/core-templates/steps/install-microbuild-impl.yml create mode 100644 eng/common/renovate.env diff --git a/eng/TargetFrameworks.props b/eng/TargetFrameworks.props index d384e5fbca..e3938d0f73 100644 --- a/eng/TargetFrameworks.props +++ b/eng/TargetFrameworks.props @@ -11,7 +11,7 @@ - net10.0 + net11.0 $([System.Text.RegularExpressions.Regex]::Replace('$(FSharpNetCoreProductTargetFramework)', '^net(\d+)\.0$', '$1')) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index 1ce7e0379f..6107e867f9 100644 --- a/eng/Version.Details.props +++ b/eng/Version.Details.props @@ -6,27 +6,27 @@ This file should be imported by eng/Versions.props - 10.0.0-beta.26177.7 + 11.0.0-beta.26171.1 - 18.6.0-preview-26180-08 - 18.6.0-preview-26180-08 - 18.6.0-preview-26180-08 - 18.6.0-preview-26180-08 + 18.6.0-preview-26170-03 + 18.6.0-preview-26170-03 + 18.6.0-preview-26170-03 + 18.6.0-preview-26170-03 - 1.0.0-prerelease.26180.1 - 1.0.0-prerelease.26180.1 - 1.0.0-prerelease.26180.1 - 1.0.0-prerelease.26180.1 - 1.0.0-prerelease.26180.1 + 1.0.0-prerelease.26153.1 + 1.0.0-prerelease.26153.1 + 1.0.0-prerelease.26153.1 + 1.0.0-prerelease.26153.1 + 1.0.0-prerelease.26153.1 - 5.7.0-1.26181.7 - 5.7.0-1.26181.7 - 5.7.0-1.26181.7 - 5.7.0-1.26181.7 - 5.7.0-1.26181.7 - 5.7.0-1.26181.7 - 5.7.0-1.26181.7 - 5.7.0-1.26181.7 + 5.6.0-2.26172.2 + 5.6.0-2.26172.2 + 5.6.0-2.26172.2 + 5.6.0-2.26172.2 + 5.6.0-2.26172.2 + 5.6.0-2.26172.2 + 5.6.0-2.26172.2 + 5.6.0-2.26172.2 10.0.2 10.0.2 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a90f0ac3cc..86e31351e2 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -2,53 +2,53 @@ - + https://github.com/dotnet/msbuild - 8a330c4406f03bafa3006d1e1213ec5c62252640 + 5071b11439964a74583693723fc0db70405e30a1 - + https://github.com/dotnet/msbuild - 8a330c4406f03bafa3006d1e1213ec5c62252640 + 5071b11439964a74583693723fc0db70405e30a1 - + https://github.com/dotnet/msbuild - 8a330c4406f03bafa3006d1e1213ec5c62252640 + 5071b11439964a74583693723fc0db70405e30a1 - + https://github.com/dotnet/msbuild - 8a330c4406f03bafa3006d1e1213ec5c62252640 + 5071b11439964a74583693723fc0db70405e30a1 - + https://github.com/dotnet/roslyn - ebe25bbad4e01d716f724d9bf8e21be94d3bbc3f + 6e85e46dc82d3eefb46eca37e213c5d32093a8ff - + https://github.com/dotnet/roslyn - ebe25bbad4e01d716f724d9bf8e21be94d3bbc3f + 6e85e46dc82d3eefb46eca37e213c5d32093a8ff - + https://github.com/dotnet/roslyn - ebe25bbad4e01d716f724d9bf8e21be94d3bbc3f + 6e85e46dc82d3eefb46eca37e213c5d32093a8ff - + https://github.com/dotnet/roslyn - ebe25bbad4e01d716f724d9bf8e21be94d3bbc3f + 6e85e46dc82d3eefb46eca37e213c5d32093a8ff - + https://github.com/dotnet/roslyn - ebe25bbad4e01d716f724d9bf8e21be94d3bbc3f + 6e85e46dc82d3eefb46eca37e213c5d32093a8ff - + https://github.com/dotnet/roslyn - ebe25bbad4e01d716f724d9bf8e21be94d3bbc3f + 6e85e46dc82d3eefb46eca37e213c5d32093a8ff - + https://github.com/dotnet/roslyn - ebe25bbad4e01d716f724d9bf8e21be94d3bbc3f + 6e85e46dc82d3eefb46eca37e213c5d32093a8ff - + https://github.com/dotnet/roslyn - ebe25bbad4e01d716f724d9bf8e21be94d3bbc3f + 6e85e46dc82d3eefb46eca37e213c5d32093a8ff @@ -76,29 +76,29 @@ - + https://github.com/dotnet/arcade - 62dc2defffeadabf6761a9ed7e142692107330c0 + e385506c3dcbeea64fa1aae811e0ff9232815666 - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 9f55ee44f6d99b78f3e80f77e2ed73fb73b8f63b + b194351e54adc9538bb2a0b6a188f8f897fa223c - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 9f55ee44f6d99b78f3e80f77e2ed73fb73b8f63b + b194351e54adc9538bb2a0b6a188f8f897fa223c - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 9f55ee44f6d99b78f3e80f77e2ed73fb73b8f63b + b194351e54adc9538bb2a0b6a188f8f897fa223c - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 9f55ee44f6d99b78f3e80f77e2ed73fb73b8f63b + b194351e54adc9538bb2a0b6a188f8f897fa223c - + https://dev.azure.com/dnceng/internal/_git/dotnet-optimization - 9f55ee44f6d99b78f3e80f77e2ed73fb73b8f63b + b194351e54adc9538bb2a0b6a188f8f897fa223c diff --git a/eng/Versions.props b/eng/Versions.props index b96d89e5c0..3acd42b675 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -89,7 +89,12 @@ 4.6.1 4.6.3 6.1.2 - + + 10.0.2 + $(SystemPackagesVersion) + $(SystemPackagesVersion) + $(SystemPackagesVersion) + $(SystemPackagesVersion) diff --git a/eng/common/SetupNugetSources.ps1 b/eng/common/SetupNugetSources.ps1 index 65ed3a8ade..fc8d618014 100644 --- a/eng/common/SetupNugetSources.ps1 +++ b/eng/common/SetupNugetSources.ps1 @@ -1,7 +1,6 @@ # This script adds internal feeds required to build commits that depend on internal package sources. For instance, -# dotnet6-internal would be added automatically if dotnet6 was found in the nuget.config file. Similarly, -# dotnet-eng-internal and dotnet-tools-internal are added if dotnet-eng and dotnet-tools are present. -# In addition, this script also enables disabled internal Maestro (darc-int*) feeds. +# dotnet6-internal would be added automatically if dotnet6 was found in the nuget.config file. In addition also enables +# disabled internal Maestro (darc-int*) feeds. # # Optionally, this script also adds a credential entry for each of the internal feeds if supplied. # @@ -174,16 +173,4 @@ foreach ($dotnetVersion in $dotnetVersions) { } } -# Check for dotnet-eng and add dotnet-eng-internal if present -$dotnetEngSource = $sources.SelectSingleNode("add[@key='dotnet-eng']") -if ($dotnetEngSource -ne $null) { - AddOrEnablePackageSource -Sources $sources -DisabledPackageSources $disabledSources -SourceName "dotnet-eng-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet-eng-internal/nuget/$feedSuffix" -Creds $creds -Username $userName -pwd $Password -} - -# Check for dotnet-tools and add dotnet-tools-internal if present -$dotnetToolsSource = $sources.SelectSingleNode("add[@key='dotnet-tools']") -if ($dotnetToolsSource -ne $null) { - AddOrEnablePackageSource -Sources $sources -DisabledPackageSources $disabledSources -SourceName "dotnet-tools-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet-tools-internal/nuget/$feedSuffix" -Creds $creds -Username $userName -pwd $Password -} - $doc.Save($filename) diff --git a/eng/common/SetupNugetSources.sh b/eng/common/SetupNugetSources.sh index b2163abbe7..b97cc53637 100755 --- a/eng/common/SetupNugetSources.sh +++ b/eng/common/SetupNugetSources.sh @@ -1,9 +1,8 @@ #!/usr/bin/env bash # This script adds internal feeds required to build commits that depend on internal package sources. For instance, -# dotnet6-internal would be added automatically if dotnet6 was found in the nuget.config file. Similarly, -# dotnet-eng-internal and dotnet-tools-internal are added if dotnet-eng and dotnet-tools are present. -# In addition, this script also enables disabled internal Maestro (darc-int*) feeds. +# dotnet6-internal would be added automatically if dotnet6 was found in the nuget.config file. In addition also enables +# disabled internal Maestro (darc-int*) feeds. # # Optionally, this script also adds a credential entry for each of the internal feeds if supplied. # @@ -174,18 +173,6 @@ for DotNetVersion in ${DotNetVersions[@]} ; do fi done -# Check for dotnet-eng and add dotnet-eng-internal if present -grep -i " /dev/null -if [ "$?" == "0" ]; then - AddOrEnablePackageSource "dotnet-eng-internal" "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet-eng-internal/nuget/$FeedSuffix" -fi - -# Check for dotnet-tools and add dotnet-tools-internal if present -grep -i " /dev/null -if [ "$?" == "0" ]; then - AddOrEnablePackageSource "dotnet-tools-internal" "https://pkgs.dev.azure.com/dnceng/internal/_packaging/dotnet-tools-internal/nuget/$FeedSuffix" -fi - # I want things split line by line PrevIFS=$IFS IFS=$'\n' diff --git a/eng/common/build.ps1 b/eng/common/build.ps1 index 8cfee107e7..18397a60eb 100644 --- a/eng/common/build.ps1 +++ b/eng/common/build.ps1 @@ -6,6 +6,7 @@ Param( [string][Alias('v')]$verbosity = "minimal", [string] $msbuildEngine = $null, [bool] $warnAsError = $true, + [string] $warnNotAsError = '', [bool] $nodeReuse = $true, [switch] $buildCheck = $false, [switch][Alias('r')]$restore, @@ -70,6 +71,7 @@ function Print-Usage() { Write-Host " -excludeCIBinarylog Don't output binary log (short: -nobl)" Write-Host " -prepareMachine Prepare machine for CI run, clean up processes after build" Write-Host " -warnAsError Sets warnaserror msbuild parameter ('true' or 'false')" + Write-Host " -warnNotAsError Sets a semi-colon delimited list of warning codes that should not be treated as errors" Write-Host " -msbuildEngine Msbuild engine to use to run build ('dotnet', 'vs', or unspecified)." Write-Host " -excludePrereleaseVS Set to exclude build engines in prerelease versions of Visual Studio" Write-Host " -nativeToolsOnMachine Sets the native tools on machine environment variable (indicating that the script should use native tools on machine)" diff --git a/eng/common/build.sh b/eng/common/build.sh index 9767bb411a..5883e53bcf 100755 --- a/eng/common/build.sh +++ b/eng/common/build.sh @@ -42,6 +42,7 @@ usage() echo " --prepareMachine Prepare machine for CI run, clean up processes after build" echo " --nodeReuse Sets nodereuse msbuild parameter ('true' or 'false')" echo " --warnAsError Sets warnaserror msbuild parameter ('true' or 'false')" + echo " --warnNotAsError Sets a semi-colon delimited list of warning codes that should not be treated as errors" echo " --buildCheck Sets /check msbuild parameter" echo " --fromVMR Set when building from within the VMR" echo "" @@ -78,6 +79,7 @@ ci=false clean=false warn_as_error=true +warn_not_as_error='' node_reuse=true build_check=false binary_log=false @@ -92,7 +94,7 @@ runtime_source_feed='' runtime_source_feed_key='' properties=() -while [[ $# > 0 ]]; do +while [[ $# -gt 0 ]]; do opt="$(echo "${1/#--/-}" | tr "[:upper:]" "[:lower:]")" case "$opt" in -help|-h) @@ -176,6 +178,10 @@ while [[ $# > 0 ]]; do warn_as_error=$2 shift ;; + -warnnotaserror) + warn_not_as_error=$2 + shift + ;; -nodereuse) node_reuse=$2 shift diff --git a/eng/common/core-templates/job/job.yml b/eng/common/core-templates/job/job.yml index 5ce5184061..748c4f07a6 100644 --- a/eng/common/core-templates/job/job.yml +++ b/eng/common/core-templates/job/job.yml @@ -19,6 +19,8 @@ parameters: # publishing defaults artifacts: '' enableMicrobuild: false + enablePreviewMicrobuild: false + microbuildPluginVersion: 'latest' enableMicrobuildForMacAndLinux: false microbuildUseESRP: true enablePublishBuildArtifacts: false @@ -71,6 +73,8 @@ jobs: templateContext: ${{ parameters.templateContext }} variables: + - name: AllowPtrToDetectTestRunRetryFiles + value: true - ${{ if ne(parameters.enableTelemetry, 'false') }}: - name: DOTNET_CLI_TELEMETRY_PROFILE value: '$(Build.Repository.Uri)' @@ -128,6 +132,8 @@ jobs: - template: /eng/common/core-templates/steps/install-microbuild.yml parameters: enableMicrobuild: ${{ parameters.enableMicrobuild }} + enablePreviewMicrobuild: ${{ parameters.enablePreviewMicrobuild }} + microbuildPluginVersion: ${{ parameters.microbuildPluginVersion }} enableMicrobuildForMacAndLinux: ${{ parameters.enableMicrobuildForMacAndLinux }} microbuildUseESRP: ${{ parameters.microbuildUseESRP }} continueOnError: ${{ parameters.continueOnError }} @@ -153,6 +159,8 @@ jobs: - template: /eng/common/core-templates/steps/cleanup-microbuild.yml parameters: enableMicrobuild: ${{ parameters.enableMicrobuild }} + enablePreviewMicrobuild: ${{ parameters.enablePreviewMicrobuild }} + microbuildPluginVersion: ${{ parameters.microbuildPluginVersion }} enableMicrobuildForMacAndLinux: ${{ parameters.enableMicrobuildForMacAndLinux }} continueOnError: ${{ parameters.continueOnError }} diff --git a/eng/common/core-templates/job/publish-build-assets.yml b/eng/common/core-templates/job/publish-build-assets.yml index 9afcb8ae15..9d7490518c 100644 --- a/eng/common/core-templates/job/publish-build-assets.yml +++ b/eng/common/core-templates/job/publish-build-assets.yml @@ -91,8 +91,8 @@ jobs: fetchDepth: 3 clean: true - - ${{ if eq(parameters.isAssetlessBuild, 'false') }}: - - ${{ if eq(parameters.publishingVersion, 3) }}: + - ${{ if eq(parameters.isAssetlessBuild, 'false') }}: + - ${{ if eq(parameters.publishingVersion, 3) }}: - task: DownloadPipelineArtifact@2 displayName: Download Asset Manifests inputs: @@ -117,7 +117,7 @@ jobs: flattenFolders: true condition: ${{ parameters.condition }} continueOnError: ${{ parameters.continueOnError }} - + - task: NuGetAuthenticate@1 # Populate internal runtime variables. @@ -125,7 +125,7 @@ jobs: ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: parameters: legacyCredential: $(dn-bot-dnceng-artifact-feeds-rw) - + - template: /eng/common/templates/steps/enable-internal-runtimes.yml - task: AzureCLI@2 @@ -145,7 +145,7 @@ jobs: condition: ${{ parameters.condition }} continueOnError: ${{ parameters.continueOnError }} - + - task: powershell@2 displayName: Create ReleaseConfigs Artifact inputs: @@ -173,7 +173,7 @@ jobs: artifactName: AssetManifests displayName: 'Publish Merged Manifest' retryCountOnTaskFailure: 10 # for any logs being locked - sbomEnabled: false # we don't need SBOM for logs + sbomEnabled: false # we don't need SBOM for logs - template: /eng/common/core-templates/steps/publish-build-artifacts.yml parameters: @@ -190,7 +190,7 @@ jobs: BARBuildId: ${{ parameters.BARBuildId }} PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} is1ESPipeline: ${{ parameters.is1ESPipeline }} - + # Darc is targeting 8.0, so make sure it's installed - task: UseDotNet@2 inputs: @@ -218,4 +218,4 @@ jobs: - template: /eng/common/core-templates/steps/publish-logs.yml parameters: is1ESPipeline: ${{ parameters.is1ESPipeline }} - JobLabel: 'Publish_Artifacts_Logs' + JobLabel: 'Publish_Artifacts_Logs' diff --git a/eng/common/core-templates/job/renovate.yml b/eng/common/core-templates/job/renovate.yml new file mode 100644 index 0000000000..ab233539b5 --- /dev/null +++ b/eng/common/core-templates/job/renovate.yml @@ -0,0 +1,196 @@ +# -------------------------------------------------------------------------------------- +# Renovate Bot Job Template +# -------------------------------------------------------------------------------------- +# This Azure DevOps pipeline job template runs Renovate (https://docs.renovatebot.com/) +# to automatically update dependencies in a GitHub repository. +# +# Renovate scans the repository for dependency files and creates pull requests to update +# outdated dependencies based on the configuration specified in the renovateConfigPath +# parameter. +# +# Usage: +# For each product repo wanting to make use of Renovate, this template is called from +# an internal Azure DevOps pipeline, typically with a schedule trigger, to check for +# and propose dependency updates. +# +# For more info, see https://github.com/dotnet/arcade/blob/main/Documentation/Renovate.md +# -------------------------------------------------------------------------------------- + +parameters: + +# Path to the Renovate configuration file within the repository. +- name: renovateConfigPath + type: string + default: 'eng/renovate.json' + +# GitHub repository to run Renovate against, in the format 'owner/repo'. +# This could technically be any repo but convention is to target the same +# repo that contains the calling pipeline. The Renovate config file would +# be co-located with the pipeline's repo and, in most cases, the config +# file is specific to the repo being targeted. +- name: gitHubRepo + type: string + +# List of base branches to target for Renovate PRs. +# NOTE: The Renovate configuration file is always read from the branch where the +# pipeline is run, NOT from the target branches specified here. If you need different +# configurations for different branches, run the pipeline from each branch separately. +- name: baseBranches + type: object + default: + - main + +# When true, Renovate will run in dry run mode, which previews changes without creating PRs. +# See the 'Run Renovate' step log output for details of what would have been changed. +- name: dryRun + type: boolean + default: false + +# By default, Renovate will not recreate a PR for a given dependency/version pair that was +# previously closed. This allows opting in to always recreating PRs even if they were +# previously closed. +- name: forceRecreatePR + type: boolean + default: false + +# Name of the arcade repository resource in the pipeline. +# This allows repos which haven't been onboarded to Arcade to still use this +# template by checking out the repo as a resource with a custom name and pointing +# this parameter to it. +- name: arcadeRepoResource + type: string + default: self + +# Directory name for the self repo under $(Build.SourcesDirectory) in multi-checkout. +# In multi-checkout (when arcadeRepoResource != 'self'), Azure DevOps checks out the +# self repo to $(Build.SourcesDirectory)/. Set this to match the auto-generated +# directory name. Using the auto-generated name is necessary rather than explicitly +# defining a checkout path because container jobs expect repos to live under the agent's +# workspace ($(Pipeline.Workspace)). On some self-hosted setups the host path +# (e.g., /mnt/vss/_work) differs from the container path (e.g., /__w), and a custom checkout +# path can fail validation. Using the default checkout location keeps the paths consistent +# and avoids this issue. +- name: selfRepoName + type: string + default: '' +- name: arcadeRepoName + type: string + default: '' + +# Pool configuration for the job. +- name: pool + type: object + default: + name: NetCore1ESPool-Internal + image: build.azurelinux.3.amd64 + os: linux + +jobs: +- job: Renovate + displayName: Run Renovate + container: RenovateContainer + variables: + - group: dotnet-renovate-bot + # The Renovate version is automatically updated by https://github.com/dotnet/arcade/blob/main/azure-pipelines-renovate.yml. + # Changing the variable name here would require updating the name in https://github.com/dotnet/arcade/blob/main/eng/renovate.json as well. + - name: renovateVersion + value: '42' + readonly: true + - name: renovateLogFilePath + value: '$(Build.ArtifactStagingDirectory)/renovate.json' + readonly: true + - name: dryRunArg + readonly: true + ${{ if eq(parameters.dryRun, true) }}: + value: 'full' + ${{ else }}: + value: '' + - name: recreateWhenArg + readonly: true + ${{ if eq(parameters.forceRecreatePR, true) }}: + value: 'always' + ${{ else }}: + value: '' + # In multi-checkout (without custom paths), Azure DevOps places each repo under + # $(Build.SourcesDirectory)/. selfRepoName must be provided in that case. + - name: selfRepoPath + readonly: true + ${{ if eq(parameters.arcadeRepoResource, 'self') }}: + value: '$(Build.SourcesDirectory)' + ${{ else }}: + value: '$(Build.SourcesDirectory)/${{ parameters.selfRepoName }}' + - name: arcadeRepoPath + readonly: true + ${{ if eq(parameters.arcadeRepoResource, 'self') }}: + value: '$(Build.SourcesDirectory)' + ${{ else }}: + value: '$(Build.SourcesDirectory)/${{ parameters.arcadeRepoName }}' + pool: ${{ parameters.pool }} + + templateContext: + outputParentDirectory: $(Build.ArtifactStagingDirectory) + outputs: + - output: pipelineArtifact + displayName: Publish Renovate Log + condition: succeededOrFailed() + targetPath: $(Build.ArtifactStagingDirectory) + artifactName: $(Agent.JobName)_Logs_Attempt$(System.JobAttempt) + sbomEnabled: false + + steps: + - checkout: self + fetchDepth: 1 + + - ${{ if ne(parameters.arcadeRepoResource, 'self') }}: + - checkout: ${{ parameters.arcadeRepoResource }} + fetchDepth: 1 + + - script: | + renovate-config-validator $(selfRepoPath)/${{parameters.renovateConfigPath}} 2>&1 | tee /tmp/renovate-config-validator.out + validatorExit=${PIPESTATUS[0]} + if grep -q '^ WARN:' /tmp/renovate-config-validator.out; then + echo "##vso[task.logissue type=warning]Renovate config validator produced warnings." + echo "##vso[task.complete result=SucceededWithIssues]" + fi + exit $validatorExit + displayName: Validate Renovate config + env: + LOG_LEVEL: info + LOG_FILE_LEVEL: debug + LOG_FILE: $(Build.ArtifactStagingDirectory)/renovate-config-validator.json + + - script: | + . $(arcadeRepoPath)/eng/common/renovate.env + renovate 2>&1 | tee /tmp/renovate.out + renovateExit=${PIPESTATUS[0]} + if grep -q '^ WARN:' /tmp/renovate.out; then + echo "##vso[task.logissue type=warning]Renovate produced warnings." + echo "##vso[task.complete result=SucceededWithIssues]" + fi + exit $renovateExit + displayName: Run Renovate + env: + RENOVATE_FORK_TOKEN: $(BotAccount-dotnet-renovate-bot-PAT) + RENOVATE_TOKEN: $(BotAccount-dotnet-renovate-bot-PAT) + RENOVATE_REPOSITORIES: ${{parameters.gitHubRepo}} + RENOVATE_BASE_BRANCHES: ${{ convertToJson(parameters.baseBranches) }} + RENOVATE_DRY_RUN: $(dryRunArg) + RENOVATE_RECREATE_WHEN: $(recreateWhenArg) + LOG_LEVEL: info + LOG_FILE_LEVEL: debug + LOG_FILE: $(renovateLogFilePath) + RENOVATE_CONFIG_FILE: $(selfRepoPath)/${{parameters.renovateConfigPath}} + + - script: | + echo "PRs created by Renovate:" + if [ -s "$(renovateLogFilePath)" ]; then + if ! jq -r 'select(.msg == "PR created" and .pr != null) | "https://github.com/\(.repository)/pull/\(.pr)"' "$(renovateLogFilePath)" | sort -u; then + echo "##vso[task.logissue type=warning]Failed to parse Renovate log file with jq." + echo "##vso[task.complete result=SucceededWithIssues]" + fi + else + echo "##vso[task.logissue type=warning]No Renovate log file found or file is empty." + echo "##vso[task.complete result=SucceededWithIssues]" + fi + displayName: List created PRs + condition: and(succeededOrFailed(), eq('${{ parameters.dryRun }}', false)) diff --git a/eng/common/core-templates/job/source-index-stage1.yml b/eng/common/core-templates/job/source-index-stage1.yml index 76baf5c272..cf02b82d4e 100644 --- a/eng/common/core-templates/job/source-index-stage1.yml +++ b/eng/common/core-templates/job/source-index-stage1.yml @@ -25,10 +25,10 @@ jobs: pool: ${{ if eq(variables['System.TeamProject'], 'public') }}: name: $(DncEngPublicBuildPool) - image: windows.vs2026preview.scout.amd64.open + image: windows.vs2026.amd64.open ${{ if eq(variables['System.TeamProject'], 'internal') }}: name: $(DncEngInternalBuildPool) - image: windows.vs2026preview.scout.amd64 + image: windows.vs2026.amd64 steps: - ${{ if eq(parameters.is1ESPipeline, '') }}: diff --git a/eng/common/core-templates/post-build/post-build.yml b/eng/common/core-templates/post-build/post-build.yml index 2df4acb768..c5ece18500 100644 --- a/eng/common/core-templates/post-build/post-build.yml +++ b/eng/common/core-templates/post-build/post-build.yml @@ -1,117 +1,107 @@ parameters: - # Which publishing infra should be used. THIS SHOULD MATCH THE VERSION ON THE BUILD MANIFEST. - # Publishing V1 is no longer supported - # Publishing V2 is no longer supported - # Publishing V3 is the default - - name: publishingInfraVersion - displayName: Which version of publishing should be used to promote the build definition? - type: number - default: 3 - values: - - 3 - - - name: BARBuildId - displayName: BAR Build Id - type: number - default: 0 - - - name: PromoteToChannelIds - displayName: Channel to promote BARBuildId to - type: string - default: '' - - - name: enableSourceLinkValidation - displayName: Enable SourceLink validation - type: boolean - default: false - - - name: enableSigningValidation - displayName: Enable signing validation - type: boolean - default: true - - - name: enableSymbolValidation - displayName: Enable symbol validation - type: boolean - default: false - - - name: enableNugetValidation - displayName: Enable NuGet validation - type: boolean - default: true - - - name: publishInstallersAndChecksums - displayName: Publish installers and checksums - type: boolean - default: true - - - name: requireDefaultChannels - displayName: Fail the build if there are no default channel(s) registrations for the current build - type: boolean - default: false - - - name: SDLValidationParameters - type: object - default: - enable: false - publishGdn: false - continueOnError: false - params: '' - artifactNames: '' - downloadArtifacts: true - - - name: isAssetlessBuild - type: boolean - displayName: Is Assetless Build - default: false - - # These parameters let the user customize the call to sdk-task.ps1 for publishing - # symbols & general artifacts as well as for signing validation - - name: symbolPublishingAdditionalParameters - displayName: Symbol publishing additional parameters - type: string - default: '' - - - name: artifactsPublishingAdditionalParameters - displayName: Artifact publishing additional parameters - type: string - default: '' - - - name: signingValidationAdditionalParameters - displayName: Signing validation additional parameters - type: string - default: '' - - # Which stages should finish execution before post-build stages start - - name: validateDependsOn - type: object - default: - - build - - - name: publishDependsOn - type: object - default: - - Validate - - # Optional: Call asset publishing rather than running in a separate stage - - name: publishAssetsImmediately - type: boolean - default: false - - - name: is1ESPipeline - type: boolean - default: false +# Which publishing infra should be used. THIS SHOULD MATCH THE VERSION ON THE BUILD MANIFEST. +# Publishing V1 is no longer supported +# Publishing V2 is no longer supported +# Publishing V3 is the default +- name: publishingInfraVersion + displayName: Which version of publishing should be used to promote the build definition? + type: number + default: 3 + values: + - 3 + +- name: BARBuildId + displayName: BAR Build Id + type: number + default: 0 + +- name: PromoteToChannelIds + displayName: Channel to promote BARBuildId to + type: string + default: '' + +- name: enableSourceLinkValidation + displayName: Enable SourceLink validation + type: boolean + default: false + +- name: enableSigningValidation + displayName: Enable signing validation + type: boolean + default: true + +- name: enableSymbolValidation + displayName: Enable symbol validation + type: boolean + default: false + +- name: enableNugetValidation + displayName: Enable NuGet validation + type: boolean + default: true + +- name: publishInstallersAndChecksums + displayName: Publish installers and checksums + type: boolean + default: true + +- name: requireDefaultChannels + displayName: Fail the build if there are no default channel(s) registrations for the current build + type: boolean + default: false + +- name: isAssetlessBuild + type: boolean + displayName: Is Assetless Build + default: false + +# These parameters let the user customize the call to sdk-task.ps1 for publishing +# symbols & general artifacts as well as for signing validation +- name: symbolPublishingAdditionalParameters + displayName: Symbol publishing additional parameters + type: string + default: '' + +- name: artifactsPublishingAdditionalParameters + displayName: Artifact publishing additional parameters + type: string + default: '' + +- name: signingValidationAdditionalParameters + displayName: Signing validation additional parameters + type: string + default: '' + +# Which stages should finish execution before post-build stages start +- name: validateDependsOn + type: object + default: + - build + +- name: publishDependsOn + type: object + default: + - Validate + +# Optional: Call asset publishing rather than running in a separate stage +- name: publishAssetsImmediately + type: boolean + default: false + +- name: is1ESPipeline + type: boolean + default: false stages: -- ${{ if or(eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: +- ${{ if or(eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true')) }}: - stage: Validate dependsOn: ${{ parameters.validateDependsOn }} displayName: Validate Build Assets variables: - - template: /eng/common/core-templates/post-build/common-variables.yml - - template: /eng/common/core-templates/variables/pool-providers.yml - parameters: - is1ESPipeline: ${{ parameters.is1ESPipeline }} + - template: /eng/common/core-templates/post-build/common-variables.yml + - template: /eng/common/core-templates/variables/pool-providers.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} jobs: - job: displayName: NuGet Validation @@ -120,42 +110,42 @@ stages: # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: name: AzurePipelines-EO - image: 1ESPT-Windows2025 + image: 1ESPT-Windows2022 demands: Cmd os: windows # If it's not devdiv, it's dnceng ${{ else }}: ${{ if eq(parameters.is1ESPipeline, true) }}: name: $(DncEngInternalBuildPool) - image: windows.vs2026preview.scout.amd64 + image: windows.vs2026.amd64 os: windows ${{ else }}: name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals windows.vs2026preview.scout.amd64 + demands: ImageOverride -equals windows.vs2026.amd64 steps: - - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - is1ESPipeline: ${{ parameters.is1ESPipeline }} - - - task: DownloadBuildArtifacts@0 - displayName: Download Package Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - artifactName: PackageArtifacts - checkDownloadedFiles: true - - - task: PowerShell@2 - displayName: Validate - inputs: - filePath: $(System.DefaultWorkingDirectory)/eng/common/post-build/nuget-validation.ps1 - arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ + - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + is1ESPipeline: ${{ parameters.is1ESPipeline }} + + - task: DownloadBuildArtifacts@0 + displayName: Download Package Artifacts + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + artifactName: PackageArtifacts + checkDownloadedFiles: true + + - task: PowerShell@2 + displayName: Validate + inputs: + filePath: $(System.DefaultWorkingDirectory)/eng/common/post-build/nuget-validation.ps1 + arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ - job: displayName: Signing Validation @@ -164,59 +154,59 @@ stages: # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: name: AzurePipelines-EO - image: 1ESPT-Windows2025 + image: 1ESPT-Windows2022 demands: Cmd os: windows # If it's not devdiv, it's dnceng ${{ else }}: - ${{ if eq(parameters.is1ESPipeline, true) }}: + ${{ if eq(parameters.is1ESPipeline, true) }}: name: $(DncEngInternalBuildPool) - image: windows.vs2026.amd64 + image: 1es-windows-2022 os: windows ${{ else }}: name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals windows.vs2026preview.scout.amd64 + demands: ImageOverride -equals windows.vs2026.amd64 steps: - - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - is1ESPipeline: ${{ parameters.is1ESPipeline }} - - - task: DownloadBuildArtifacts@0 - displayName: Download Package Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - artifactName: PackageArtifacts - checkDownloadedFiles: true - - # This is necessary whenever we want to publish/restore to an AzDO private feed - # Since sdk-task.ps1 tries to restore packages we need to do this authentication here - # otherwise it'll complain about accessing a private feed. - - task: NuGetAuthenticate@1 - displayName: 'Authenticate to AzDO Feeds' - - # Signing validation will optionally work with the buildmanifest file which is downloaded from - # Azure DevOps above. - - task: PowerShell@2 - displayName: Validate - inputs: - filePath: eng\common\sdk-task.ps1 - arguments: -task SigningValidation -restore -msbuildEngine vs - /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts' - /p:SignCheckExclusionsFile='$(System.DefaultWorkingDirectory)/eng/SignCheckExclusionsFile.txt' - ${{ parameters.signingValidationAdditionalParameters }} - - - template: /eng/common/core-templates/steps/publish-logs.yml - parameters: - is1ESPipeline: ${{ parameters.is1ESPipeline }} - StageLabel: 'Validation' - JobLabel: 'Signing' - BinlogToolVersion: $(BinlogToolVersion) + - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + is1ESPipeline: ${{ parameters.is1ESPipeline }} + + - task: DownloadBuildArtifacts@0 + displayName: Download Package Artifacts + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + artifactName: PackageArtifacts + checkDownloadedFiles: true + + # This is necessary whenever we want to publish/restore to an AzDO private feed + # Since sdk-task.ps1 tries to restore packages we need to do this authentication here + # otherwise it'll complain about accessing a private feed. + - task: NuGetAuthenticate@1 + displayName: 'Authenticate to AzDO Feeds' + + # Signing validation will optionally work with the buildmanifest file which is downloaded from + # Azure DevOps above. + - task: PowerShell@2 + displayName: Validate + inputs: + filePath: eng\common\sdk-task.ps1 + arguments: -task SigningValidation -restore + /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts' + /p:SignCheckExclusionsFile='$(System.DefaultWorkingDirectory)/eng/SignCheckExclusionsFile.txt' + ${{ parameters.signingValidationAdditionalParameters }} + + - template: /eng/common/core-templates/steps/publish-logs.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} + StageLabel: 'Validation' + JobLabel: 'Signing' + BinlogToolVersion: $(BinlogToolVersion) - job: displayName: SourceLink Validation @@ -225,59 +215,59 @@ stages: # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: name: AzurePipelines-EO - image: 1ESPT-Windows2025 + image: 1ESPT-Windows2022 demands: Cmd os: windows # If it's not devdiv, it's dnceng ${{ else }}: - ${{ if eq(parameters.is1ESPipeline, true) }}: + ${{ if eq(parameters.is1ESPipeline, true) }}: name: $(DncEngInternalBuildPool) - image: windows.vs2026.amd64 + image: 1es-windows-2022 os: windows ${{ else }}: name: $(DncEngInternalBuildPool) - demands: ImageOverride -equals windows.vs2026preview.scout.amd64 + demands: ImageOverride -equals windows.vs2026.amd64 steps: - - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - is1ESPipeline: ${{ parameters.is1ESPipeline }} - - - task: DownloadBuildArtifacts@0 - displayName: Download Blob Artifacts - inputs: - buildType: specific - buildVersionToDownload: specific - project: $(AzDOProjectName) - pipeline: $(AzDOPipelineId) - buildId: $(AzDOBuildId) - artifactName: BlobArtifacts - checkDownloadedFiles: true - - - task: PowerShell@2 - displayName: Validate - inputs: - filePath: $(System.DefaultWorkingDirectory)/eng/common/post-build/sourcelink-validation.ps1 - arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/ - -ExtractPath $(Agent.BuildDirectory)/Extract/ - -GHRepoName $(Build.Repository.Name) - -GHCommit $(Build.SourceVersion) - -SourcelinkCliVersion $(SourceLinkCLIVersion) - continueOnError: true + - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + is1ESPipeline: ${{ parameters.is1ESPipeline }} + + - task: DownloadBuildArtifacts@0 + displayName: Download Blob Artifacts + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + artifactName: BlobArtifacts + checkDownloadedFiles: true + + - task: PowerShell@2 + displayName: Validate + inputs: + filePath: $(System.DefaultWorkingDirectory)/eng/common/post-build/sourcelink-validation.ps1 + arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/ + -ExtractPath $(Agent.BuildDirectory)/Extract/ + -GHRepoName $(Build.Repository.Name) + -GHCommit $(Build.SourceVersion) + -SourcelinkCliVersion $(SourceLinkCLIVersion) + continueOnError: true - ${{ if ne(parameters.publishAssetsImmediately, 'true') }}: - stage: publish_using_darc - ${{ if or(eq(parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: + ${{ if or(eq(parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true')) }}: dependsOn: ${{ parameters.publishDependsOn }} ${{ else }}: dependsOn: ${{ parameters.validateDependsOn }} displayName: Publish using Darc variables: - - template: /eng/common/core-templates/post-build/common-variables.yml - - template: /eng/common/core-templates/variables/pool-providers.yml - parameters: - is1ESPipeline: ${{ parameters.is1ESPipeline }} + - template: /eng/common/core-templates/post-build/common-variables.yml + - template: /eng/common/core-templates/variables/pool-providers.yml + parameters: + is1ESPipeline: ${{ parameters.is1ESPipeline }} jobs: - job: displayName: Publish Using Darc @@ -286,47 +276,46 @@ stages: # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: name: AzurePipelines-EO - image: 1ESPT-Windows2025 + image: 1ESPT-Windows2022 demands: Cmd os: windows # If it's not devdiv, it's dnceng ${{ else }}: - ${{ if eq(parameters.is1ESPipeline, true) }}: + ${{ if eq(parameters.is1ESPipeline, true) }}: name: NetCore1ESPool-Publishing-Internal - image: windows.vs2026.amd64 + image: windows.vs2022.amd64 os: windows ${{ else }}: name: NetCore1ESPool-Publishing-Internal - demands: ImageOverride -equals windows.vs2026.amd64 + demands: ImageOverride -equals windows.vs2022.amd64 steps: - - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml - parameters: - BARBuildId: ${{ parameters.BARBuildId }} - PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} - is1ESPipeline: ${{ parameters.is1ESPipeline }} - - - task: NuGetAuthenticate@1 - - # Populate internal runtime variables. - - template: /eng/common/templates/steps/enable-internal-sources.yml - parameters: - legacyCredential: $(dn-bot-dnceng-artifact-feeds-rw) - - - template: /eng/common/templates/steps/enable-internal-runtimes.yml - - # Darc is targeting 8.0, so make sure it's installed - - task: UseDotNet@2 - inputs: - version: 8.0.x - - - task: AzureCLI@2 - displayName: Publish Using Darc - inputs: - azureSubscription: "Darc: Maestro Production" - scriptType: ps - scriptLocation: scriptPath - scriptPath: $(System.DefaultWorkingDirectory)/eng/common/post-build/publish-using-darc.ps1 - arguments: > + - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + is1ESPipeline: ${{ parameters.is1ESPipeline }} + + - task: NuGetAuthenticate@1 + + # Populate internal runtime variables. + - template: /eng/common/templates/steps/enable-internal-sources.yml + parameters: + legacyCredential: $(dn-bot-dnceng-artifact-feeds-rw) + + - template: /eng/common/templates/steps/enable-internal-runtimes.yml + + - task: UseDotNet@2 + inputs: + version: 8.0.x + + - task: AzureCLI@2 + displayName: Publish Using Darc + inputs: + azureSubscription: "Darc: Maestro Production" + scriptType: ps + scriptLocation: scriptPath + scriptPath: $(System.DefaultWorkingDirectory)/eng/common/post-build/publish-using-darc.ps1 + arguments: > -BuildId $(BARBuildId) -PublishingInfraVersion ${{ parameters.publishingInfraVersion }} -AzdoToken '$(System.AccessToken)' diff --git a/eng/common/core-templates/stages/renovate.yml b/eng/common/core-templates/stages/renovate.yml new file mode 100644 index 0000000000..41f3b6cc85 --- /dev/null +++ b/eng/common/core-templates/stages/renovate.yml @@ -0,0 +1,111 @@ +# -------------------------------------------------------------------------------------- +# Renovate Pipeline Template +# -------------------------------------------------------------------------------------- +# This template provides a complete reusable pipeline definition for running Renovate +# in a 1ES Official pipeline. Pipelines can extend from this template and only need +# to pass the Renovate job parameters. +# +# For more info, see https://github.com/dotnet/arcade/blob/main/Documentation/Renovate.md +# -------------------------------------------------------------------------------------- + +parameters: + +# Path to the Renovate configuration file within the repository. +- name: renovateConfigPath + type: string + default: 'eng/renovate.json' + +# GitHub repository to run Renovate against, in the format 'owner/repo'. +- name: gitHubRepo + type: string + +# List of base branches to target for Renovate PRs. +- name: baseBranches + type: object + default: + - main + +# When true, Renovate will run in dry run mode. +- name: dryRun + type: boolean + default: false + +# When true, Renovate will recreate PRs even if they were previously closed. +- name: forceRecreatePR + type: boolean + default: false + +# Name of the arcade repository resource in the pipeline. +# This allows repos which haven't been onboarded to Arcade to still use this +# template by checking out the repo as a resource with a custom name and pointing +# this parameter to it. +- name: arcadeRepoResource + type: string + default: 'self' + +- name: selfRepoName + type: string + default: '' +- name: arcadeRepoName + type: string + default: '' + +# Pool configuration for the pipeline. +- name: pool + type: object + default: + name: NetCore1ESPool-Internal + image: build.azurelinux.3.amd64 + os: linux + +# Renovate version used in the container image tag. +- name: renovateVersion + default: 43 + type: number + +# Pool configuration for SDL analysis. +- name: sdlPool + type: object + default: + name: NetCore1ESPool-Internal + image: 1es-windows-2022 + os: windows + +resources: + repositories: + - repository: 1ESPipelineTemplates + type: git + name: 1ESPipelineTemplates/1ESPipelineTemplates + ref: refs/tags/release + +extends: + template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates + parameters: + pool: ${{ parameters.pool }} + sdl: + sourceAnalysisPool: ${{ parameters.sdlPool }} + # When repos that aren't onboarded to Arcade use this template, they set the + # arcadeRepoResource parameter to point to their Arcade repo resource. In that case, + # Aracde will be excluded from SDL analysis. + ${{ if ne(parameters.arcadeRepoResource, 'self') }}: + sourceRepositoriesToScan: + exclude: + - repository: ${{ parameters.arcadeRepoResource }} + containers: + RenovateContainer: + image: mcr.microsoft.com/dotnet-buildtools/prereqs:azurelinux-3.0-renovate-${{ parameters.renovateVersion }}-amd64 + stages: + - stage: Renovate + displayName: Run Renovate + jobs: + - template: /eng/common/core-templates/job/renovate.yml@${{ parameters.arcadeRepoResource }} + parameters: + renovateConfigPath: ${{ parameters.renovateConfigPath }} + gitHubRepo: ${{ parameters.gitHubRepo }} + baseBranches: ${{ parameters.baseBranches }} + dryRun: ${{ parameters.dryRun }} + forceRecreatePR: ${{ parameters.forceRecreatePR }} + pool: ${{ parameters.pool }} + arcadeRepoResource: ${{ parameters.arcadeRepoResource }} + selfRepoName: ${{ parameters.selfRepoName }} + arcadeRepoName: ${{ parameters.arcadeRepoName }} diff --git a/eng/common/core-templates/steps/generate-sbom.yml b/eng/common/core-templates/steps/generate-sbom.yml index c05f650279..003f7eae0f 100644 --- a/eng/common/core-templates/steps/generate-sbom.yml +++ b/eng/common/core-templates/steps/generate-sbom.yml @@ -5,7 +5,7 @@ # IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector. parameters: - PackageVersion: 10.0.0 + PackageVersion: 11.0.0 BuildDropPath: '$(System.DefaultWorkingDirectory)/artifacts' PackageName: '.NET' ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom diff --git a/eng/common/core-templates/steps/install-microbuild-impl.yml b/eng/common/core-templates/steps/install-microbuild-impl.yml new file mode 100644 index 0000000000..da22beb3f6 --- /dev/null +++ b/eng/common/core-templates/steps/install-microbuild-impl.yml @@ -0,0 +1,34 @@ +parameters: + - name: microbuildTaskInputs + type: object + default: {} + + - name: microbuildEnv + type: object + default: {} + + - name: enablePreviewMicrobuild + type: boolean + default: false + + - name: condition + type: string + + - name: continueOnError + type: boolean + +steps: +- ${{ if eq(parameters.enablePreviewMicrobuild, true) }}: + - task: MicroBuildSigningPluginPreview@4 + displayName: Install Preview MicroBuild plugin + inputs: ${{ parameters.microbuildTaskInputs }} + env: ${{ parameters.microbuildEnv }} + continueOnError: ${{ parameters.continueOnError }} + condition: ${{ parameters.condition }} +- ${{ else }}: + - task: MicroBuildSigningPlugin@4 + displayName: Install MicroBuild plugin + inputs: ${{ parameters.microbuildTaskInputs }} + env: ${{ parameters.microbuildEnv }} + continueOnError: ${{ parameters.continueOnError }} + condition: ${{ parameters.condition }} diff --git a/eng/common/core-templates/steps/install-microbuild.yml b/eng/common/core-templates/steps/install-microbuild.yml index 553fce66b9..76a54e157f 100644 --- a/eng/common/core-templates/steps/install-microbuild.yml +++ b/eng/common/core-templates/steps/install-microbuild.yml @@ -4,6 +4,8 @@ parameters: # Enable install tasks for MicroBuild on Mac and Linux # Will be ignored if 'enableMicrobuild' is false or 'Agent.Os' is 'Windows_NT' enableMicrobuildForMacAndLinux: false + # Enable preview version of MB signing plugin + enablePreviewMicrobuild: false # Determines whether the ESRP service connection information should be passed to the signing plugin. # This overlaps with _SignType to some degree. We only need the service connection for real signing. # It's important that the service connection not be passed to the MicroBuildSigningPlugin task in this place. @@ -13,6 +15,8 @@ parameters: microbuildUseESRP: true # Microbuild installation directory microBuildOutputFolder: $(Agent.TempDirectory)/MicroBuild + # Microbuild version + microbuildPluginVersion: 'latest' continueOnError: false @@ -69,42 +73,46 @@ steps: # YAML expansion, and Windows vs. Linux/Mac uses different service connections. However, # we can avoid including the MB install step if not enabled at all. This avoids a bunch of # extra pipeline authorizations, since most pipelines do not sign on non-Windows. - - task: MicroBuildSigningPlugin@4 - displayName: Install MicroBuild plugin (Windows) - inputs: - signType: $(_SignType) - zipSources: false - feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json - ${{ if eq(parameters.microbuildUseESRP, true) }}: - ConnectedServiceName: 'MicroBuild Signing Task (DevDiv)' - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - ConnectedPMEServiceName: 6cc74545-d7b9-4050-9dfa-ebefcc8961ea - ${{ else }}: - ConnectedPMEServiceName: 248d384a-b39b-46e3-8ad5-c2c210d5e7ca - env: - TeamName: $(_TeamName) - MicroBuildOutputFolderOverride: ${{ parameters.microBuildOutputFolder }} - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - continueOnError: ${{ parameters.continueOnError }} - condition: and(succeeded(), eq(variables['Agent.Os'], 'Windows_NT'), in(variables['_SignType'], 'real', 'test')) - - - ${{ if eq(parameters.enableMicrobuildForMacAndLinux, true) }}: - - task: MicroBuildSigningPlugin@4 - displayName: Install MicroBuild plugin (non-Windows) - inputs: + - template: /eng/common/core-templates/steps/install-microbuild-impl.yml + parameters: + enablePreviewMicrobuild: ${{ parameters.enablePreviewMicrobuild }} + microbuildTaskInputs: signType: $(_SignType) zipSources: false feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json - workingDirectory: ${{ parameters.microBuildOutputFolder }} + version: ${{ parameters.microbuildPluginVersion }} ${{ if eq(parameters.microbuildUseESRP, true) }}: ConnectedServiceName: 'MicroBuild Signing Task (DevDiv)' ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: - ConnectedPMEServiceName: beb8cb23-b303-4c95-ab26-9e44bc958d39 + ConnectedPMEServiceName: 6cc74545-d7b9-4050-9dfa-ebefcc8961ea ${{ else }}: - ConnectedPMEServiceName: c24de2a5-cc7a-493d-95e4-8e5ff5cad2bc - env: + ConnectedPMEServiceName: 248d384a-b39b-46e3-8ad5-c2c210d5e7ca + microbuildEnv: TeamName: $(_TeamName) MicroBuildOutputFolderOverride: ${{ parameters.microBuildOutputFolder }} SYSTEM_ACCESSTOKEN: $(System.AccessToken) continueOnError: ${{ parameters.continueOnError }} - condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT'), eq(variables['_SignType'], 'real')) + condition: and(succeeded(), eq(variables['Agent.Os'], 'Windows_NT'), in(variables['_SignType'], 'real', 'test')) + + - ${{ if eq(parameters.enableMicrobuildForMacAndLinux, true) }}: + - template: /eng/common/core-templates/steps/install-microbuild-impl.yml + parameters: + enablePreviewMicrobuild: ${{ parameters.enablePreviewMicrobuild }} + microbuildTaskInputs: + signType: $(_SignType) + zipSources: false + feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json + version: ${{ parameters.microbuildPluginVersion }} + workingDirectory: ${{ parameters.microBuildOutputFolder }} + ${{ if eq(parameters.microbuildUseESRP, true) }}: + ConnectedServiceName: 'MicroBuild Signing Task (DevDiv)' + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + ConnectedPMEServiceName: beb8cb23-b303-4c95-ab26-9e44bc958d39 + ${{ else }}: + ConnectedPMEServiceName: c24de2a5-cc7a-493d-95e4-8e5ff5cad2bc + microbuildEnv: + TeamName: $(_TeamName) + MicroBuildOutputFolderOverride: ${{ parameters.microBuildOutputFolder }} + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + continueOnError: ${{ parameters.continueOnError }} + condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT'), eq(variables['_SignType'], 'real')) diff --git a/eng/common/core-templates/steps/source-build.yml b/eng/common/core-templates/steps/source-build.yml index b9c86c18ae..acf16ed349 100644 --- a/eng/common/core-templates/steps/source-build.yml +++ b/eng/common/core-templates/steps/source-build.yml @@ -24,7 +24,7 @@ steps: # in the default public locations. internalRuntimeDownloadArgs= if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then - internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://ci.dot.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://ci.dot.net/internal --runtimesourcefeedkey '$(dotnetbuilds-internal-container-read-token-base64)'' + internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://ci.dot.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://ci.dot.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)' fi buildConfig=Release diff --git a/eng/common/core-templates/steps/source-index-stage1-publish.yml b/eng/common/core-templates/steps/source-index-stage1-publish.yml index e9a694afa5..3ad83b8c30 100644 --- a/eng/common/core-templates/steps/source-index-stage1-publish.yml +++ b/eng/common/core-templates/steps/source-index-stage1-publish.yml @@ -1,6 +1,6 @@ parameters: - sourceIndexUploadPackageVersion: 2.0.0-20250818.1 - sourceIndexProcessBinlogPackageVersion: 1.0.1-20250818.1 + sourceIndexUploadPackageVersion: 2.0.0-20250906.1 + sourceIndexProcessBinlogPackageVersion: 1.0.1-20250906.1 sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json binlogPath: artifacts/log/Debug/Build.binlog @@ -14,8 +14,8 @@ steps: workingDirectory: $(Agent.TempDirectory) - script: | - $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version ${{parameters.sourceIndexProcessBinlogPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools - $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version ${{parameters.sourceIndexUploadPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools + $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version ${{parameters.sourceIndexProcessBinlogPackageVersion}} --source ${{parameters.sourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools + $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version ${{parameters.sourceIndexUploadPackageVersion}} --source ${{parameters.sourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools displayName: "Source Index: Download netsourceindex Tools" # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk. workingDirectory: $(Agent.TempDirectory) diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh index 8abfb71f72..314c93c575 100755 --- a/eng/common/cross/build-rootfs.sh +++ b/eng/common/cross/build-rootfs.sh @@ -9,6 +9,7 @@ usage() echo "CodeName - optional, Code name for Linux, can be: xenial(default), zesty, bionic, alpine" echo " for alpine can be specified with version: alpineX.YY or alpineedge" echo " for FreeBSD can be: freebsd13, freebsd14" + echo " for OpenBSD can be: openbsd" echo " for illumos can be: illumos" echo " for Haiku can be: haiku." echo "lldbx.y - optional, LLDB version, can be: lldb3.9(default), lldb4.0, lldb5.0, lldb6.0 no-lldb. Ignored for alpine and FreeBSD" @@ -27,6 +28,8 @@ __BuildArch=arm __AlpineArch=armv7 __FreeBSDArch=arm __FreeBSDMachineArch=armv7 +__OpenBSDArch=arm +__OpenBSDMachineArch=armv7 __IllumosArch=arm7 __HaikuArch=arm __QEMUArch=arm @@ -72,7 +75,7 @@ __AlpinePackages+=" krb5-dev" __AlpinePackages+=" openssl-dev" __AlpinePackages+=" zlib-dev" -__FreeBSDBase="13.4-RELEASE" +__FreeBSDBase="13.5-RELEASE" __FreeBSDPkg="1.21.3" __FreeBSDABI="13" __FreeBSDPackages="libunwind" @@ -82,6 +85,12 @@ __FreeBSDPackages+=" openssl" __FreeBSDPackages+=" krb5" __FreeBSDPackages+=" terminfo-db" +__OpenBSDVersion="7.8" +__OpenBSDPackages="heimdal-libs" +__OpenBSDPackages+=" icu4c" +__OpenBSDPackages+=" inotify-tools" +__OpenBSDPackages+=" openssl" + __IllumosPackages="icu" __IllumosPackages+=" mit-krb5" __IllumosPackages+=" openssl" @@ -160,6 +169,8 @@ while :; do __QEMUArch=aarch64 __FreeBSDArch=arm64 __FreeBSDMachineArch=aarch64 + __OpenBSDArch=arm64 + __OpenBSDMachineArch=aarch64 ;; armel) __BuildArch=armel @@ -235,6 +246,8 @@ while :; do __UbuntuArch=amd64 __FreeBSDArch=amd64 __FreeBSDMachineArch=amd64 + __OpenBSDArch=amd64 + __OpenBSDMachineArch=amd64 __illumosArch=x86_64 __HaikuArch=x86_64 __UbuntuRepo="http://archive.ubuntu.com/ubuntu/" @@ -295,9 +308,7 @@ while :; do ;; noble) # Ubuntu 24.04 __CodeName=noble - if [[ -z "$__LLDB_Package" ]]; then - __LLDB_Package="liblldb-19-dev" - fi + __LLDB_Package="liblldb-19-dev" ;; stretch) # Debian 9 __CodeName=stretch @@ -383,10 +394,14 @@ while :; do ;; freebsd14) __CodeName=freebsd - __FreeBSDBase="14.2-RELEASE" + __FreeBSDBase="14.3-RELEASE" __FreeBSDABI="14" __SkipUnmount=1 ;; + openbsd) + __CodeName=openbsd + __SkipUnmount=1 + ;; illumos) __CodeName=illumos __SkipUnmount=1 @@ -595,6 +610,62 @@ elif [[ "$__CodeName" == "freebsd" ]]; then INSTALL_AS_USER=$(whoami) "$__RootfsDir"/host/sbin/pkg -r "$__RootfsDir" -C "$__RootfsDir"/usr/local/etc/pkg.conf update # shellcheck disable=SC2086 INSTALL_AS_USER=$(whoami) "$__RootfsDir"/host/sbin/pkg -r "$__RootfsDir" -C "$__RootfsDir"/usr/local/etc/pkg.conf install --yes $__FreeBSDPackages +elif [[ "$__CodeName" == "openbsd" ]]; then + # determine mirrors + OPENBSD_MIRROR="https://cdn.openbsd.org/pub/OpenBSD/$__OpenBSDVersion/$__OpenBSDMachineArch" + + # download base system sets + ensureDownloadTool + + BASE_SETS=(base comp) + for set in "${BASE_SETS[@]}"; do + FILE="${set}${__OpenBSDVersion//./}.tgz" + echo "Downloading $FILE..." + if [[ "$__hasWget" == 1 ]]; then + wget -O- "$OPENBSD_MIRROR/$FILE" | tar -C "$__RootfsDir" -xzpf - + else + curl -SL "$OPENBSD_MIRROR/$FILE" | tar -C "$__RootfsDir" -xzpf - + fi + done + + PKG_MIRROR="https://cdn.openbsd.org/pub/OpenBSD/${__OpenBSDVersion}/packages/${__OpenBSDMachineArch}" + + echo "Installing packages into sysroot..." + + # Fetch package index once + if [[ "$__hasWget" == 1 ]]; then + PKG_INDEX=$(wget -qO- "$PKG_MIRROR/") + else + PKG_INDEX=$(curl -s "$PKG_MIRROR/") + fi + + for pkg in $__OpenBSDPackages; do + PKG_FILE=$(echo "$PKG_INDEX" | grep -Po ">\K${pkg}-[0-9][^\" ]*\.tgz" \ + | sort -V | tail -n1) + + echo "Resolved package filename for $pkg: $PKG_FILE" + + [[ -z "$PKG_FILE" ]] && { echo "ERROR: Package $pkg not found"; exit 1; } + + if [[ "$__hasWget" == 1 ]]; then + wget -O- "$PKG_MIRROR/$PKG_FILE" | tar -C "$__RootfsDir" -xzpf - + else + curl -SL "$PKG_MIRROR/$PKG_FILE" | tar -C "$__RootfsDir" -xzpf - + fi + done + + echo "Creating versionless symlinks for shared libraries..." + # Find all versioned .so files and create the base .so symlink + for lib in "$__RootfsDir/usr/lib/libc++.so."* "$__RootfsDir/usr/lib/libc++abi.so."* "$__RootfsDir/usr/lib/libpthread.so."*; do + if [ -f "$lib" ]; then + # Extract the filename (e.g., libc++.so.12.0) + VERSIONED_NAME=$(basename "$lib") + # Remove the trailing version numbers (e.g., libc++.so) + BASE_NAME=${VERSIONED_NAME%.so.*}.so + # Create the symlink in the same directory + ln -sf "$VERSIONED_NAME" "$__RootfsDir/usr/lib/$BASE_NAME" + fi + done elif [[ "$__CodeName" == "illumos" ]]; then mkdir "$__RootfsDir/tmp" pushd "$__RootfsDir/tmp" diff --git a/eng/common/cross/toolchain.cmake b/eng/common/cross/toolchain.cmake index 0ff85cf036..ff2dfdb4a5 100644 --- a/eng/common/cross/toolchain.cmake +++ b/eng/common/cross/toolchain.cmake @@ -3,15 +3,22 @@ set(CROSS_ROOTFS $ENV{ROOTFS_DIR}) # reset platform variables (e.g. cmake 3.25 sets LINUX=1) unset(LINUX) unset(FREEBSD) +unset(OPENBSD) unset(ILLUMOS) unset(ANDROID) unset(TIZEN) unset(HAIKU) set(TARGET_ARCH_NAME $ENV{TARGET_BUILD_ARCH}) + +file(GLOB OPENBSD_PROBE "${CROSS_ROOTFS}/etc/signify/openbsd-*.pub") + if(EXISTS ${CROSS_ROOTFS}/bin/freebsd-version) set(CMAKE_SYSTEM_NAME FreeBSD) set(FREEBSD 1) +elseif(OPENBSD_PROBE) + set(CMAKE_SYSTEM_NAME OpenBSD) + set(OPENBSD 1) elseif(EXISTS ${CROSS_ROOTFS}/usr/platform/i86pc) set(CMAKE_SYSTEM_NAME SunOS) set(ILLUMOS 1) @@ -53,6 +60,8 @@ elseif(TARGET_ARCH_NAME STREQUAL "arm64") endif() elseif(FREEBSD) set(triple "aarch64-unknown-freebsd12") + elseif(OPENBSD) + set(triple "aarch64-unknown-openbsd") endif() elseif(TARGET_ARCH_NAME STREQUAL "armel") set(CMAKE_SYSTEM_PROCESSOR armv7l) @@ -109,6 +118,8 @@ elseif(TARGET_ARCH_NAME STREQUAL "x64") endif() elseif(FREEBSD) set(triple "x86_64-unknown-freebsd12") + elseif(OPENBSD) + set(triple "x86_64-unknown-openbsd") elseif(ILLUMOS) set(TOOLCHAIN "x86_64-illumos") elseif(HAIKU) @@ -193,7 +204,7 @@ if(ANDROID) # include official NDK toolchain script include(${CROSS_ROOTFS}/../build/cmake/android.toolchain.cmake) -elseif(FREEBSD) +elseif(FREEBSD OR OPENBSD) # we cross-compile by instructing clang set(CMAKE_C_COMPILER_TARGET ${triple}) set(CMAKE_CXX_COMPILER_TARGET ${triple}) @@ -291,7 +302,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) OR ILLUMOS OR HAIKU) +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) set(CMAKE_C_COMPILER_TARGET ${TOOLCHAIN}) set(CMAKE_CXX_COMPILER_TARGET ${TOOLCHAIN}) set(CMAKE_ASM_COMPILER_TARGET ${TOOLCHAIN}) diff --git a/eng/common/darc-init.sh b/eng/common/darc-init.sh index e889f439b8..9f5ad6b763 100755 --- a/eng/common/darc-init.sh +++ b/eng/common/darc-init.sh @@ -5,7 +5,7 @@ darcVersion='' versionEndpoint='https://maestro.dot.net/api/assets/darc-version?api-version=2020-02-20' verbosity='minimal' -while [[ $# > 0 ]]; do +while [[ $# -gt 0 ]]; do opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")" case "$opt" in --darcversion) diff --git a/eng/common/dotnet-install.sh b/eng/common/dotnet-install.sh index 7b9d97e3bd..61f302bb67 100755 --- a/eng/common/dotnet-install.sh +++ b/eng/common/dotnet-install.sh @@ -18,7 +18,7 @@ architecture='' runtime='dotnet' runtimeSourceFeed='' runtimeSourceFeedKey='' -while [[ $# > 0 ]]; do +while [[ $# -gt 0 ]]; do opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")" case "$opt" in -version|-v) diff --git a/eng/common/dotnet.sh b/eng/common/dotnet.sh index 2ef6823567..f6d24871c1 100755 --- a/eng/common/dotnet.sh +++ b/eng/common/dotnet.sh @@ -19,7 +19,7 @@ source $scriptroot/tools.sh InitializeDotNetCli true # install # Invoke acquired SDK with args if they are provided -if [[ $# > 0 ]]; then +if [[ $# -gt 0 ]]; then __dotnetDir=${_InitializeDotNetCli} dotnetPath=${__dotnetDir}/dotnet ${dotnetPath} "$@" diff --git a/eng/common/internal-feed-operations.sh b/eng/common/internal-feed-operations.sh index 9378223ba0..6299e7effd 100755 --- a/eng/common/internal-feed-operations.sh +++ b/eng/common/internal-feed-operations.sh @@ -100,7 +100,7 @@ operation='' authToken='' repoName='' -while [[ $# > 0 ]]; do +while [[ $# -gt 0 ]]; do opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")" case "$opt" in --operation) diff --git a/eng/common/native/init-distro-rid.sh b/eng/common/native/init-distro-rid.sh index 83ea7aab0e..8fc6d2fec7 100644 --- a/eng/common/native/init-distro-rid.sh +++ b/eng/common/native/init-distro-rid.sh @@ -39,6 +39,8 @@ getNonPortableDistroRid() # $rootfsDir can be empty. freebsd-version is a shell script and should always work. __freebsd_major_version=$("$rootfsDir"/bin/freebsd-version | cut -d'.' -f1) nonPortableRid="freebsd.$__freebsd_major_version-${targetArch}" + elif [ "$targetOs" = "openbsd" ]; then + nonPortableRid="openbsd.$(uname -r)-${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}" diff --git a/eng/common/native/install-dependencies.sh b/eng/common/native/install-dependencies.sh index 477a44f335..4742177a76 100644 --- a/eng/common/native/install-dependencies.sh +++ b/eng/common/native/install-dependencies.sh @@ -24,14 +24,16 @@ case "$os" in apt update apt install -y build-essential gettext locales cmake llvm clang lld lldb liblldb-dev libunwind8-dev libicu-dev liblttng-ust-dev \ - libssl-dev libkrb5-dev pigz cpio + libssl-dev libkrb5-dev pigz cpio ninja-build localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 - elif [ "$ID" = "fedora" ] || [ "$ID" = "rhel" ] || [ "$ID" = "azurelinux" ]; then + elif [ "$ID" = "fedora" ] || [ "$ID" = "rhel" ] || [ "$ID" = "azurelinux" ] || [ "$ID" = "centos" ]; then pkg_mgr="$(command -v tdnf 2>/dev/null || command -v dnf)" - $pkg_mgr install -y cmake llvm lld lldb clang python curl libicu-devel openssl-devel krb5-devel lttng-ust-devel pigz cpio + $pkg_mgr install -y cmake llvm lld lldb clang python curl libicu-devel openssl-devel krb5-devel lttng-ust-devel pigz cpio ninja-build + elif [ "$ID" = "amzn" ]; then + dnf install -y cmake llvm lld lldb clang python libicu-devel openssl-devel krb5-devel lttng-ust-devel pigz cpio ninja-build elif [ "$ID" = "alpine" ]; then - apk add build-base cmake bash curl clang llvm-dev lld lldb krb5-dev lttng-ust-dev icu-dev openssl-dev pigz cpio + apk add build-base cmake bash curl clang llvm llvm-dev lld lldb-dev krb5-dev lttng-ust-dev icu-dev openssl-dev pigz cpio ninja else echo "Unsupported distro. distro: $ID" exit 1 @@ -52,6 +54,7 @@ brew "openssl@3" brew "pkgconf" brew "python3" brew "pigz" +brew "ninja" EOF ;; diff --git a/eng/common/post-build/redact-logs.ps1 b/eng/common/post-build/redact-logs.ps1 index 472d5bb562..fc0218a013 100644 --- a/eng/common/post-build/redact-logs.ps1 +++ b/eng/common/post-build/redact-logs.ps1 @@ -9,7 +9,8 @@ param( [Parameter(Mandatory=$false)][string] $TokensFilePath, [Parameter(ValueFromRemainingArguments=$true)][String[]]$TokensToRedact, [Parameter(Mandatory=$false)][string] $runtimeSourceFeed, - [Parameter(Mandatory=$false)][string] $runtimeSourceFeedKey) + [Parameter(Mandatory=$false)][string] $runtimeSourceFeedKey +) try { $ErrorActionPreference = 'Stop' diff --git a/eng/common/renovate.env b/eng/common/renovate.env new file mode 100644 index 0000000000..17ecc05d9b --- /dev/null +++ b/eng/common/renovate.env @@ -0,0 +1,42 @@ +# Renovate Global Configuration +# https://docs.renovatebot.com/self-hosted-configuration/ +# +# NOTE: This file uses bash/shell format and is sourced via `. renovate.env`. +# Values containing spaces or special characters must be quoted. + +# Author to use for git commits made by Renovate +# https://docs.renovatebot.com/configuration-options/#gitauthor +export RENOVATE_GIT_AUTHOR='.NET Renovate ' + +# Disable rate limiting for PR creation (0 = unlimited) +# https://docs.renovatebot.com/presets-default/#prhourlylimitnone +# https://docs.renovatebot.com/presets-default/#prconcurrentlimitnone +export RENOVATE_PR_HOURLY_LIMIT=0 +export RENOVATE_PR_CONCURRENT_LIMIT=0 + +# Skip the onboarding PR that Renovate normally creates for new repos +# https://docs.renovatebot.com/config-overview/#onboarding +export RENOVATE_ONBOARDING=false + +# Any Renovate config file in the cloned repository is ignored. Only +# the Renovate config file from the repo where the pipeline is running +# is used (yes, those are the same repo but the sources may be different). +# https://docs.renovatebot.com/self-hosted-configuration/#requireconfig +export RENOVATE_REQUIRE_CONFIG=ignored + +# Customize the PR body content. This removes some of the default +# sections that aren't relevant in a self-hosted config. +# https://docs.renovatebot.com/configuration-options/#prheader +# https://docs.renovatebot.com/configuration-options/#prbodynotes +# https://docs.renovatebot.com/configuration-options/#prbodytemplate +export RENOVATE_PR_HEADER='## Automated Dependency Update' +export RENOVATE_PR_BODY_NOTES='["This PR has been created automatically by the [.NET Renovate Bot](https://github.com/dotnet/arcade/blob/main/Documentation/Renovate.md) to update one or more dependencies in your repo. Please review the changes and merge the PR if everything looks good."]' +export RENOVATE_PR_BODY_TEMPLATE='{{{header}}}{{{table}}}{{{warnings}}}{{{notes}}}{{{changelogs}}}' + +# Extend the global config with additional presets +# https://docs.renovatebot.com/self-hosted-configuration/#globalextends +# Disable the Dependency Dashboard issue that tracks all updates +export RENOVATE_GLOBAL_EXTENDS='[":disableDependencyDashboard"]' + +# Allow all commands for post-upgrade commands. +export RENOVATE_ALLOWED_COMMANDS='[".*"]' diff --git a/eng/common/template-guidance.md b/eng/common/template-guidance.md index 4bf4cf41bd..cdc62e72b0 100644 --- a/eng/common/template-guidance.md +++ b/eng/common/template-guidance.md @@ -71,7 +71,6 @@ eng\common\ source-build.yml (shim) source-index-stage1.yml (shim) jobs\ - codeql-build.yml (shim) jobs.yml (shim) source-build.yml (shim) post-build\ @@ -89,7 +88,6 @@ eng\common\ source-build.yml (shim) variables\ pool-providers.yml (logic + redirect) # templates/variables/pool-providers.yml will redirect to templates-official/variables/pool-providers.yml if you are running in the internal project - sdl-variables.yml (logic) core-templates\ job\ job.yml (logic) @@ -98,7 +96,6 @@ eng\common\ source-build.yml (logic) source-index-stage1.yml (logic) jobs\ - codeql-build.yml (logic) jobs.yml (logic) source-build.yml (logic) post-build\ diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 977a2d4b10..c96f5018fe 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -34,6 +34,9 @@ # Configures warning treatment in msbuild. [bool]$warnAsError = if (Test-Path variable:warnAsError) { $warnAsError } else { $true } +# Specifies semi-colon delimited list of warning codes that should not be treated as errors. +[string]$warnNotAsError = if (Test-Path variable:warnNotAsError) { $warnNotAsError } else { '' } + # Specifies which msbuild engine to use for build: 'vs', 'dotnet' or unspecified (determined based on presence of tools.vs in global.json). [string]$msbuildEngine = if (Test-Path variable:msbuildEngine) { $msbuildEngine } else { $null } @@ -157,9 +160,6 @@ function InitializeDotNetCli([bool]$install, [bool]$createSdkLocationFile) { return $global:_DotNetInstallDir } - # Don't resolve runtime, shared framework, or SDK from other locations to ensure build determinism - $env:DOTNET_MULTILEVEL_LOOKUP=0 - # Disable first run since we do not need all ASP.NET packages restored. $env:DOTNET_NOLOGO=1 @@ -225,7 +225,6 @@ function InitializeDotNetCli([bool]$install, [bool]$createSdkLocationFile) { # Make Sure that our bootstrapped dotnet cli is available in future steps of the Azure Pipelines build Write-PipelinePrependPath -Path $dotnetRoot - Write-PipelineSetVariable -Name 'DOTNET_MULTILEVEL_LOOKUP' -Value '0' Write-PipelineSetVariable -Name 'DOTNET_NOLOGO' -Value '1' return $global:_DotNetInstallDir = $dotnetRoot @@ -299,6 +298,8 @@ function InstallDotNet([string] $dotnetRoot, $dotnetVersionLabel = "'sdk v$version'" + # For performance this check is duplicated in src/Microsoft.DotNet.Arcade.Sdk/src/InstallDotNetCore.cs + # if you are making changes here, consider if you need to make changes there as well. if ($runtime -ne '' -and $runtime -ne 'sdk') { $runtimePath = $dotnetRoot $runtimePath = $runtimePath + "\shared" @@ -592,6 +593,11 @@ function LocateVisualStudio([object]$vsRequirements = $null){ return $null } + if ($null -eq $vsInfo -or $vsInfo.Count -eq 0) { + throw "No instance of Visual Studio meeting the requirements specified was found. Requirements: $($args -join ' ')" + return $null + } + # use first matching instance return $vsInfo[0] } @@ -836,6 +842,10 @@ function MSBuild-Core() { $cmdArgs += ' /p:TreatWarningsAsErrors=false' } + if ($warnNotAsError) { + $cmdArgs += " /warnnotaserror:$warnNotAsError /p:AdditionalWarningsNotAsErrors=$warnNotAsError" + } + foreach ($arg in $args) { if ($null -ne $arg -and $arg.Trim() -ne "") { if ($arg.EndsWith('\')) { diff --git a/eng/common/tools.sh b/eng/common/tools.sh index 1b296f646c..a6e0ed594f 100755 --- a/eng/common/tools.sh +++ b/eng/common/tools.sh @@ -52,6 +52,9 @@ fi # Configures warning treatment in msbuild. warn_as_error=${warn_as_error:-true} +# Specifies semi-colon delimited list of warning codes that should not be treated as errors. +warn_not_as_error=${warn_not_as_error:-''} + # True to attempt using .NET Core already that meets requirements specified in global.json # installed on the machine instead of downloading one. use_installed_dotnet_cli=${use_installed_dotnet_cli:-true} @@ -115,9 +118,6 @@ function InitializeDotNetCli { local install=$1 - # Don't resolve runtime, shared framework, or SDK from other locations to ensure build determinism - export DOTNET_MULTILEVEL_LOOKUP=0 - # Disable first run since we want to control all package sources export DOTNET_NOLOGO=1 @@ -166,7 +166,6 @@ function InitializeDotNetCli { # build steps from using anything other than what we've downloaded. Write-PipelinePrependPath -path "$dotnet_root" - Write-PipelineSetVariable -name "DOTNET_MULTILEVEL_LOOKUP" -value "0" Write-PipelineSetVariable -name "DOTNET_NOLOGO" -value "1" # return value @@ -188,6 +187,8 @@ function InstallDotNet { local version=$2 local runtime=$4 + # For performance this check is duplicated in src/Microsoft.DotNet.Arcade.Sdk/src/InstallDotNetCore.cs + # if you are making changes here, consider if you need to make changes there as well. local dotnetVersionLabel="'$runtime v$version'" if [[ -n "${4:-}" ]] && [ "$4" != 'sdk' ]; then runtimePath="$root" @@ -532,7 +533,12 @@ function MSBuild-Core { mt_switch="-mt" fi - RunBuildTool "$_InitializeBuildToolCommand" /m /nologo /clp:Summary /v:$verbosity /nr:$node_reuse $warnaserror_switch $mt_switch /p:TreatWarningsAsErrors=$warn_as_error /p:ContinuousIntegrationBuild=$ci "$@" + local warnnotaserror_switch="" + if [[ -n "$warn_not_as_error" ]]; then + warnnotaserror_switch="/warnnotaserror:$warn_not_as_error /p:AdditionalWarningsNotAsErrors=$warn_not_as_error" + fi + + RunBuildTool "$_InitializeBuildToolCommand" /m /nologo /clp:Summary /v:$verbosity /nr:$node_reuse $warnaserror_switch $mt_switch $warnnotaserror_switch /p:TreatWarningsAsErrors=$warn_as_error /p:ContinuousIntegrationBuild=$ci "$@" } function GetDarc { diff --git a/global.json b/global.json index c222e67a02..64f2a6e5e7 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "10.0.105", + "version": "11.0.100-preview.3.26161.119", "allowPrerelease": true, "paths": [ ".dotnet", @@ -12,7 +12,7 @@ "runner": "Microsoft.Testing.Platform" }, "tools": { - "dotnet": "10.0.105", + "dotnet": "11.0.100-preview.3.26161.119", "vs": { "version": "18.0", "components": [ @@ -22,7 +22,7 @@ "xcopy-msbuild": "18.0.0" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.26177.7", + "Microsoft.DotNet.Arcade.Sdk": "11.0.0-beta.26171.1", "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23255.2" } } From 8573f50da48167b0208d0f19bb0a9da4c0325b93 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 10 Apr 2026 11:59:46 +0200 Subject: [PATCH 2/7] Fix CI: restore FSBuildVersion=101 and PreReleaseIteration=4 from feature branch The merge from main regressed these values to 100/3, causing Check_Published_Package_Versions to fail (packages already published). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- eng/Versions.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 3acd42b675..5ef7109a3b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -14,12 +14,12 @@ - 3 + 4 preview$(FSharpPreReleaseIteration) 11 0 - 100 + 101 0 From 98c4774d9c65a7cd97e370b4c3598b99741122ca Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 10 Apr 2026 13:26:42 +0200 Subject: [PATCH 3/7] Add regression tests for #10043: backtick, @, and ! in type annotations (#19476) Verifies that type annotations with invalid characters produce clear error messages: - backtick: FS3563 'This is not a valid identifier' - at sign: FS0615 'Unexpected infix operator in type expression' - bang: FS1141 'Identifiers followed by ! are reserved for future use' Fixes #10043 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../DiagnosticRegressionTests.fs | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/DiagnosticRegressionTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/DiagnosticRegressionTests.fs index 36e258e4dd..7310f83dbd 100644 --- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/DiagnosticRegressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/DiagnosticRegressionTests.fs @@ -50,6 +50,43 @@ type Vehicle() = class end [ (Error 39, Line 3, Col 14, Line 3, Col 28, "The type 'OutOfScopeType' is not defined.") (Error 267, Line 3, Col 7, Line 3, Col 29, "This is not a valid constant expression or custom attribute value") ] +// https://github.com/dotnet/fsharp/issues/10043 +[] +let ``Issue 10043 - backtick in type annotation should not report unexpected keyword`` () = + FSharp + """ +let i:float`1 = 3.0 + """ + |> typecheck + |> shouldFail + |> withDiagnostics + [ (Error 3563, Line 2, Col 12, Line 2, Col 13, "This is not a valid identifier") + (Error 10, Line 2, Col 13, Line 2, Col 14, "Unexpected integer literal in binding. Expected '=' or other token.") ] + +// https://github.com/dotnet/fsharp/issues/10043 +[] +let ``Issue 10043 - at sign in type annotation should report infix operator`` () = + FSharp + """ +let i:float@1 = 3.0 + """ + |> typecheck + |> shouldFail + |> withDiagnostics + [ (Error 615, Line 2, Col 12, Line 2, Col 13, "Unexpected infix operator in type expression") ] + +// https://github.com/dotnet/fsharp/issues/10043 +[] +let ``Issue 10043 - bang in type annotation should report reserved identifier`` () = + FSharp + """ +let i:float!1 = 3.0 + """ + |> typecheck + |> shouldFail + |> withDiagnostics + [ (Error 1141, Line 2, Col 7, Line 2, Col 13, "Identifiers followed by '!' are reserved for future use") + (Error 10, Line 2, Col 13, Line 2, Col 14, "Unexpected integer literal in binding. Expected '=' or other token.") ] // https://github.com/dotnet/fsharp/issues/7177 [] From 5bcca434c6272b4e133c311a42e1eaf755a66e91 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sat, 11 Apr 2026 11:33:11 +0200 Subject: [PATCH 4/7] Fix wrong warning 20 range in sequential expressions (#5735) (#19504) In TcStmt, the range used for warning 20 was synExpr.Range which, for sequential expressions (e.g. loop bodies with multiple statements), covered the entire body. This made the squiggle highlight the whole block instead of just the offending non-unit expression. Added lastExprRange helper that walks the SynExpr.Sequential chain to find the range of the last expression, so the warning now correctly points at only the expression that produces the ignored value. Added 4 regression tests for for-in, for-to, and while loops. Co-authored-by: Tomas Grosup Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../.FSharp.Compiler.Service/11.0.100.md | 1 + .../Checking/Expressions/CheckExpressions.fs | 11 +++- .../ErrorMessages/WarnExpressionTests.fs | 57 +++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md index d5c2087765..dfdf2f1421 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -3,6 +3,7 @@ * Fix DU case names matching IWSAM member names no longer cause duplicate property entries. (Issue [#14321](https://github.com/dotnet/fsharp/issues/14321), [PR #19341](https://github.com/dotnet/fsharp/pull/19341)) * Fix DefaultAugmentation(false) duplicate entry in method table. (Issue [#16565](https://github.com/dotnet/fsharp/issues/16565), [PR #19341](https://github.com/dotnet/fsharp/pull/19341)) * Fix abstract event accessors now have SpecialName flag. (Issue [#5834](https://github.com/dotnet/fsharp/issues/5834), [PR #19341](https://github.com/dotnet/fsharp/pull/19341)) +* Fix warning 20 ("expression is implicitly ignored") pointing at the wrong range when the last expression in a sequential block (e.g. inside `for`, `while` loops) is non-unit. The squiggle now correctly highlights only the offending expression. ([Issue #5735](https://github.com/dotnet/fsharp/issues/5735), [PR #19504](https://github.com/dotnet/fsharp/pull/19504)) * Fix CLIEvent properties to be correctly recognized as events: `IsEvent` returns `true` and `XmlDocSig` uses `E:` prefix instead of `P:`. ([Issue #10273](https://github.com/dotnet/fsharp/issues/10273), [PR #18584](https://github.com/dotnet/fsharp/pull/18584)) * Fix extra sequence point at the end of match expressions. ([Issue #12052](https://github.com/dotnet/fsharp/issues/12052), [PR #19278](https://github.com/dotnet/fsharp/pull/19278)) * Fix wrong sequence point range for `return`/`yield`/`return!`/`yield!` inside computation expressions. ([Issue #19248](https://github.com/dotnet/fsharp/issues/19248), [PR #19278](https://github.com/dotnet/fsharp/pull/19278)) diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs index 635a0dff04..5a6bbf619f 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs @@ -5522,7 +5522,16 @@ and TcStmtThatCantBeCtorBody (cenv: cenv) env tpenv synExpr = and TcStmt (cenv: cenv) env tpenv synExpr = let g = cenv.g let expr, ty, tpenv = TcExprOfUnknownType cenv env tpenv synExpr - let m = synExpr.Range + + // Use the range of the last expression in a sequential chain for warnings, + // so that "expression is ignored" diagnostics point at the offending expression + // rather than the entire sequential body. See https://github.com/dotnet/fsharp/issues/5735 + let rec lastExprRange (e: SynExpr) = + match e with + | SynExpr.Sequential(expr2 = expr2) -> lastExprRange expr2 + | _ -> e.Range + + let m = lastExprRange synExpr let wasUnit = UnifyUnitType cenv env m ty expr if wasUnit then expr, tpenv diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/WarnExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/WarnExpressionTests.fs index 942ab64dfc..b5cf1bcbcc 100644 --- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/WarnExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/WarnExpressionTests.fs @@ -176,6 +176,63 @@ while x < 1 do |> withSingleDiagnostic (Warning 20, Line 6, Col 5, Line 6, Col 9, "The result of this expression has type 'bool' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.") + // https://github.com/dotnet/fsharp/issues/5735 + [] + let ``Warn On Last Expression In For Loop - int``() = + FSharp """ +module ClassLibrary17 + +for i in 1 .. 10 do + printfn "" + printfn "" |> ignore + 123 + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 20, Line 7, Col 5, Line 7, Col 8, + "The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.") + + // https://github.com/dotnet/fsharp/issues/5735 + [] + let ``Warn On Last Expression In For Loop - string``() = + FSharp """ +for i in 1 .. 10 do + printfn "" + "hello" + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 20, Line 4, Col 5, Line 4, Col 12, + "The result of this expression has type 'string' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.") + + // https://github.com/dotnet/fsharp/issues/5735 + [] + let ``Warn On Last Expression In Integer For Loop``() = + FSharp """ +for i = 1 to 10 do + printfn "" + 42 + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 20, Line 4, Col 5, Line 4, Col 7, + "The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.") + + // https://github.com/dotnet/fsharp/issues/5735 + [] + let ``Warn On Last Expression In While Loop - non-bool``() = + FSharp """ +let mutable x = 0 +while x < 1 do + printfn "unneeded" + x <- x + 1 + 123 + """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 20, Line 6, Col 5, Line 6, Col 8, + "The result of this expression has type 'int' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.") + [] let ``Warn If Possible Property Setter``() = FSharp """ From bd2823e2d07c84f987b4029bce12c19ac10d6a2b Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sat, 11 Apr 2026 18:32:19 +0200 Subject: [PATCH 5/7] Fix completion inconsistently filtering obsolete fields and events (#13512) (#19506) * Fix completion inconsistently filtering obsolete fields and events Add ILFieldInfoIsUnseen and EventInfoIsUnseen functions to filter obsolete IL fields and events from completion, matching existing behavior for methods and properties. Also update ItemIsUnseen to handle ILField and Event items. Fixes #13693 Agent-Logs-Url: https://github.com/dotnet/fsharp/sessions/1d21d452-3f55-4d56-898c-0b50980050b5 Co-authored-by: abonie <20281641+abonie@users.noreply.github.com> * Add C# interop tests for obsolete field/event/method/property filtering Fix issue number to #13512. Add ObsoleteMembersClass to CSharp_Analysis with obsolete and non-obsolete members. Add 6 C# interop completion tests verifying all obsolete member types are consistently hidden. Agent-Logs-Url: https://github.com/dotnet/fsharp/sessions/1d21d452-3f55-4d56-898c-0b50980050b5 Co-authored-by: abonie <20281641+abonie@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: abonie <20281641+abonie@users.noreply.github.com> --- .../.FSharp.Compiler.Service/11.0.100.md | 1 + src/Compiler/Checking/AttributeChecking.fs | 21 +++++ src/Compiler/Checking/AttributeChecking.fsi | 4 + src/Compiler/Checking/NameResolution.fs | 8 +- .../FSharp.Compiler.Service.Tests/Checker.fs | 5 ++ .../CompletionTests.fs | 80 +++++++++++++++++++ .../data/CSharp_Analysis/CSharpClass.cs | 21 +++++ 7 files changed, 138 insertions(+), 2 deletions(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md index dfdf2f1421..d2d59c319a 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -18,6 +18,7 @@ * Fix `YieldFromFinal`/`ReturnFromFinal` being incorrectly called in non-tail positions (`for`, `use`, `use!`, `try/with` handler). ([Issue #19402](https://github.com/dotnet/fsharp/issues/19402), [PR #19403](https://github.com/dotnet/fsharp/pull/19403)) * Fixed how the source ranges of warn directives are reported (as trivia) in the parser output (by not reporting leading spaces). ([Issue #19405](https://github.com/dotnet/fsharp/issues/19405), [PR #19408]((https://github.com/dotnet/fsharp/pull/19408))) * Fix UoM value type `ToString()` returning garbage values when `--checknulls+` is enabled, caused by double address-taking in codegen. ([Issue #19435](https://github.com/dotnet/fsharp/issues/19435), [PR #19440](https://github.com/dotnet/fsharp/pull/19440)) +* Fix completion inconsistently showing some obsolete members (fields and events) while hiding others (methods and properties). All obsolete members are now consistently hidden by default. ([Issue #13512](https://github.com/dotnet/fsharp/issues/13512), [PR #19506](https://github.com/dotnet/fsharp/pull/19506)) ### Added diff --git a/src/Compiler/Checking/AttributeChecking.fs b/src/Compiler/Checking/AttributeChecking.fs index ba62a69e4b..a735291472 100755 --- a/src/Compiler/Checking/AttributeChecking.fs +++ b/src/Compiler/Checking/AttributeChecking.fs @@ -639,6 +639,27 @@ let PropInfoIsUnseen _m allowObsolete pinfo = CheckProvidedAttributesForUnseen (pi.PApply((fun st -> (st :> IProvidedCustomAttributeProvider)), m)) m #endif +/// Indicate if an ILFieldInfo has 'Obsolete' attribute. +/// Used to suppress the item in intellisense. +let ILFieldInfoIsUnseen (finfo: ILFieldInfo) = + match finfo with + | ILFieldInfo(_, fdef) -> CheckILAttributesForUnseen fdef.CustomAttrs +#if !NO_TYPEPROVIDERS + | ProvidedField(_amap, fi, m) -> + CheckProvidedAttributesForUnseen (fi.PApply((fun st -> (st :> IProvidedCustomAttributeProvider)), m)) m +#endif + +/// Indicate if an EventInfo has 'Obsolete' or 'CompilerMessageAttribute'. +/// Used to suppress the item in intellisense. +let EventInfoIsUnseen allowObsolete (einfo: EventInfo) = + match einfo with + | ILEvent(ILEventInfo(_, ilEventDef)) -> CheckILAttributesForUnseen ilEventDef.CustomAttrs + | FSEvent(g, _, addValRef, _) -> CheckFSharpAttributesForUnseen g addValRef.Attribs allowObsolete +#if !NO_TYPEPROVIDERS + | ProvidedEvent(_amap, ei, m) -> + CheckProvidedAttributesForUnseen (ei.PApply((fun st -> (st :> IProvidedCustomAttributeProvider)), m)) m +#endif + /// Check the attributes on a union case, returning errors and warnings as data. let CheckUnionCaseAttributes g (x:UnionCaseRef) m = trackErrors { diff --git a/src/Compiler/Checking/AttributeChecking.fsi b/src/Compiler/Checking/AttributeChecking.fsi index c8198e4a98..564957e1bd 100644 --- a/src/Compiler/Checking/AttributeChecking.fsi +++ b/src/Compiler/Checking/AttributeChecking.fsi @@ -101,6 +101,10 @@ val MethInfoIsUnseen: g: TcGlobals -> m: range -> ty: TType -> minfo: MethInfo - val PropInfoIsUnseen: _m: 'a -> allowObsolete: bool -> pinfo: PropInfo -> bool +val ILFieldInfoIsUnseen: finfo: ILFieldInfo -> bool + +val EventInfoIsUnseen: allowObsolete: bool -> einfo: EventInfo -> bool + val CheckEntityAttributes: g: TcGlobals -> tcref: TyconRef -> m: range -> OperationResult val CheckUnionCaseAttributes: g: TcGlobals -> x: UnionCaseRef -> m: range -> OperationResult diff --git a/src/Compiler/Checking/NameResolution.fs b/src/Compiler/Checking/NameResolution.fs index 55ab3c9219..07d0ea4743 100644 --- a/src/Compiler/Checking/NameResolution.fs +++ b/src/Compiler/Checking/NameResolution.fs @@ -4393,6 +4393,8 @@ let ItemIsUnseen ad g amap m allowObsolete item = isUnseenNameOfOperator || IsValUnseen ad g m allowObsolete x | Item.UnionCase(x, _) -> IsUnionCaseUnseen ad g amap m allowObsolete x.UnionCaseRef | Item.ExnCase x -> IsTyconUnseen ad g amap m allowObsolete x + | Item.ILField finfo -> not allowObsolete && ILFieldInfoIsUnseen finfo + | Item.Event einfo -> not allowObsolete && EventInfoIsUnseen allowObsolete einfo | _ -> false let ItemOfTyconRef ncenv m (x: TyconRef) = @@ -4467,7 +4469,8 @@ let ResolveCompletionsInType (ncenv: NameResolver) nenv (completionTargets: Reso ncenv.InfoReader.GetEventInfosOfType(None, ad, m, ty) |> List.filter (fun x -> IsStandardEventInfo ncenv.InfoReader m ad x && - x.IsStatic = statics) + x.IsStatic = statics && + (allowObsolete || not (EventInfoIsUnseen allowObsolete x))) else [] let nestedTypes = @@ -4482,7 +4485,8 @@ let ResolveCompletionsInType (ncenv: NameResolver) nenv (completionTargets: Reso |> List.filter (fun x -> not x.IsSpecialName && x.IsStatic = statics && - IsILFieldInfoAccessible g amap m ad x) + IsILFieldInfoAccessible g amap m ad x && + (allowObsolete || not (ILFieldInfoIsUnseen x))) let qinfos = ncenv.InfoReader.GetTraitInfosInType None ty diff --git a/tests/FSharp.Compiler.Service.Tests/Checker.fs b/tests/FSharp.Compiler.Service.Tests/Checker.fs index 5d16f87783..22dcf2ad50 100644 --- a/tests/FSharp.Compiler.Service.Tests/Checker.fs +++ b/tests/FSharp.Compiler.Service.Tests/Checker.fs @@ -162,6 +162,11 @@ module Checker = let parseResults, checkResults = getParseAndCheckResults context.Source checkResults.GetCodeCompletionSuggestions(context, parseResults, options) + let getCompletionInfoWithCompilerAndCompletionOptions (compilerOptions: string array) (completionOptions: FSharpCodeCompletionOptions) (markedSource: string) = + let context = getCompletionContext markedSource + let parseResults, checkResults = getParseAndCheckResultsWithOptions compilerOptions context.Source + checkResults.GetCodeCompletionSuggestions(context, parseResults, completionOptions) + let getCompletionInfo markedSource = getCompletionInfoWithOptions FSharpCodeCompletionOptions.Default markedSource diff --git a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs index 43ee08b4ee..e229a6f2b3 100644 --- a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs @@ -691,6 +691,86 @@ exception E try () with E{caret} """ + // https://github.com/dotnet/fsharp/issues/13512 + [] + let ``Event - Instance 01`` () = + assertItem "Ev" """ +type T() = + [] + member _.Ev = Event().Publish + +T().{caret} +""" + + // https://github.com/dotnet/fsharp/issues/13512 + [] + let ``Event - Static 01`` () = + assertItem "Ev" """ +type T() = + [] + static member Ev = Event().Publish + +T.{caret} +""" + + /// Helper to assert completion with a reference to the CSharp_Analysis assembly + let private assertCSharpInteropItem name source = + let csharpAssembly = PathRelativeToTestAssembly "CSharp_Analysis.dll" + let compilerOptions = [| $"-r:{csharpAssembly}" |] + [allowObsoleteOptions; disallowObsoleteOptions] + |> List.iter (fun completionOptions -> + let contains = completionOptions.SuggestObsoleteSymbols + let info = Checker.getCompletionInfoWithCompilerAndCompletionOptions compilerOptions completionOptions source + assertItemsWithNames contains [name] info + ) + + // https://github.com/dotnet/fsharp/issues/13512 + [] + let ``CSharp - Obsolete field is hidden`` () = + assertCSharpInteropItem "ObsoleteField" """ +open FSharp.Compiler.Service.Tests +ObsoleteMembersClass.{caret} +""" + + // https://github.com/dotnet/fsharp/issues/13512 + [] + let ``CSharp - Obsolete method is hidden`` () = + assertCSharpInteropItem "ObsoleteMethod" """ +open FSharp.Compiler.Service.Tests +ObsoleteMembersClass.{caret} +""" + + // https://github.com/dotnet/fsharp/issues/13512 + [] + let ``CSharp - Obsolete property is hidden`` () = + assertCSharpInteropItem "ObsoleteProperty" """ +open FSharp.Compiler.Service.Tests +ObsoleteMembersClass.{caret} +""" + + // https://github.com/dotnet/fsharp/issues/13512 + [] + let ``CSharp - Obsolete event is hidden`` () = + assertCSharpInteropItem "ObsoleteEvent" """ +open FSharp.Compiler.Service.Tests +ObsoleteMembersClass.{caret} +""" + + // https://github.com/dotnet/fsharp/issues/13512 + [] + let ``CSharp - Non-obsolete members are always shown`` () = + let csharpAssembly = PathRelativeToTestAssembly "CSharp_Analysis.dll" + let compilerOptions = [| $"-r:{csharpAssembly}" |] + let source = """ +open FSharp.Compiler.Service.Tests +ObsoleteMembersClass.{caret} +""" + [allowObsoleteOptions; disallowObsoleteOptions] + |> List.iter (fun completionOptions -> + let info = Checker.getCompletionInfoWithCompilerAndCompletionOptions compilerOptions completionOptions source + assertItemsWithNames true ["NonObsoleteField"; "NonObsoleteMethod"; "NonObsoleteProperty"; "NonObsoleteEvent"] info + ) + module PatternNameSuggestions = let private suggestPatternNames = { FSharpCodeCompletionOptions.Default with SuggestPatternNames = true } diff --git a/tests/service/data/CSharp_Analysis/CSharpClass.cs b/tests/service/data/CSharp_Analysis/CSharpClass.cs index a8131651b5..e8afc869dc 100644 --- a/tests/service/data/CSharp_Analysis/CSharpClass.cs +++ b/tests/service/data/CSharp_Analysis/CSharpClass.cs @@ -155,4 +155,25 @@ public class DummyClass { } } + + /// + /// Class with obsolete members for testing completion filtering (issue #13512). + /// + public class ObsoleteMembersClass + { + [Obsolete("Field is obsolete")] public static readonly int ObsoleteField = 1; + + [Obsolete("Method is obsolete")] + public static void ObsoleteMethod() + { + } + + [Obsolete("Property is obsolete")] public static int ObsoleteProperty => 1; + [Obsolete("Event is obsolete")] public static event EventHandler ObsoleteEvent; + + public static readonly int NonObsoleteField = 2; + public static void NonObsoleteMethod() { } + public static int NonObsoleteProperty => 2; + public static event EventHandler NonObsoleteEvent; + } } From 1c1ba20900c90e0180bfca152d8df7c4b8a8b5aa Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 11:52:40 +0200 Subject: [PATCH 6/7] Update dependencies from https://github.com/dotnet/roslyn build 20260410.5 (#19572) On relative base path root Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.Compilers , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.EditorFeatures , Microsoft.CodeAnalysis.EditorFeatures.Text , Microsoft.CodeAnalysis.ExternalAccess.FSharp , Microsoft.CodeAnalysis.Features , Microsoft.VisualStudio.LanguageServices From Version 5.7.0-1.26209.5 -> To Version 5.7.0-1.26210.5 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.props | 16 ++++++++-------- eng/Version.Details.xml | 32 ++++++++++++++++---------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/eng/Version.Details.props b/eng/Version.Details.props index 6a4a344f72..4290ffadab 100644 --- a/eng/Version.Details.props +++ b/eng/Version.Details.props @@ -19,14 +19,14 @@ This file should be imported by eng/Versions.props 1.0.0-prerelease.26180.1 1.0.0-prerelease.26180.1 - 5.7.0-1.26209.5 - 5.7.0-1.26209.5 - 5.7.0-1.26209.5 - 5.7.0-1.26209.5 - 5.7.0-1.26209.5 - 5.7.0-1.26209.5 - 5.7.0-1.26209.5 - 5.7.0-1.26209.5 + 5.7.0-1.26210.5 + 5.7.0-1.26210.5 + 5.7.0-1.26210.5 + 5.7.0-1.26210.5 + 5.7.0-1.26210.5 + 5.7.0-1.26210.5 + 5.7.0-1.26210.5 + 5.7.0-1.26210.5 10.0.2 10.0.2 diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 624ac68b33..a96ff6fe1f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -18,37 +18,37 @@ https://github.com/dotnet/msbuild e5ebe15655a6be2b2e3209464d0cde1b8825ab57 - + https://github.com/dotnet/roslyn - e3a102fb75ef112d064feebd2f9385385a445a06 + 0eca297f565449839436b91fe4aa180f9bcdedd2 - + https://github.com/dotnet/roslyn - e3a102fb75ef112d064feebd2f9385385a445a06 + 0eca297f565449839436b91fe4aa180f9bcdedd2 - + https://github.com/dotnet/roslyn - e3a102fb75ef112d064feebd2f9385385a445a06 + 0eca297f565449839436b91fe4aa180f9bcdedd2 - + https://github.com/dotnet/roslyn - e3a102fb75ef112d064feebd2f9385385a445a06 + 0eca297f565449839436b91fe4aa180f9bcdedd2 - + https://github.com/dotnet/roslyn - e3a102fb75ef112d064feebd2f9385385a445a06 + 0eca297f565449839436b91fe4aa180f9bcdedd2 - + https://github.com/dotnet/roslyn - e3a102fb75ef112d064feebd2f9385385a445a06 + 0eca297f565449839436b91fe4aa180f9bcdedd2 - + https://github.com/dotnet/roslyn - e3a102fb75ef112d064feebd2f9385385a445a06 + 0eca297f565449839436b91fe4aa180f9bcdedd2 - + https://github.com/dotnet/roslyn - e3a102fb75ef112d064feebd2f9385385a445a06 + 0eca297f565449839436b91fe4aa180f9bcdedd2 From 40e815cf51cdf73050504900037c45e97c2eac38 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2026 11:52:56 +0200 Subject: [PATCH 7/7] [main] Source code updates from dotnet/dotnet (#19566) * Backflow from https://github.com/dotnet/dotnet / 0cf6b19 build 309569 [[ commit created by automation ]] * Update dependencies from build 309569 No dependency updates to commit [[ commit created by automation ]] * Fix CI failures: bump FSBuildVersion to 101 The packages FSharp.Core 11.0.100 and FSharp.Compiler.Service 43.12.100 have already been published to NuGet. Bump FSBuildVersion from 100 to 101 to match main and avoid the version collision. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: dotnet-maestro[bot] Co-authored-by: Tomas Grosup Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- eng/Build.ps1 | 7 ++++++- eng/Version.Details.xml | 2 +- eng/build.sh | 14 +++++++++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/eng/Build.ps1 b/eng/Build.ps1 index 40c3275596..cc93c1e68f 100644 --- a/eng/Build.ps1 +++ b/eng/Build.ps1 @@ -48,6 +48,7 @@ param ( [switch]$useGlobalNuGetCache = $true, [switch]$dontUseGlobalNuGetCache = $false, [switch]$warnAsError = $true, + [string]$warnNotAsError = "", [switch][Alias('test')]$testDesktop, [string]$testDesktopBatch = "", [switch]$testCoreClr, @@ -149,6 +150,7 @@ function Print-Usage() { Write-Host " -compressAllMetadata Build product with compressed metadata" Write-Host " -buildnorealsig Build product with realsig- (default use realsig+, where necessary)" Write-Host " -verifypackageshipstatus Verify whether the packages we are building have already shipped to nuget" + Write-Host " -warnNotAsError Suppress specific warnings from being treated as errors (semi-colon delimited)" Write-Host "" Write-Host "Command line arguments starting with '/p:' are passed through to MSBuild." } @@ -305,6 +307,8 @@ function BuildSolution([string] $solutionName, $packSolution) { $pack = if ($packSolution -eq $False) {""} else {$pack} + $msbuildWarnNotAsError = if ($warnAsError -and $warnNotAsError -ne "") { "/warnNotAsError:$warnNotAsError" } else { "" } + MSBuild $toolsetBuildProj ` $bl ` /p:Configuration=$configuration ` @@ -327,7 +331,8 @@ function BuildSolution([string] $solutionName, $packSolution) { /p:BuildNoRealsig=$buildnorealsig ` /v:$verbosity ` $suppressExtensionDeployment ` - @properties + @properties ` + $msbuildWarnNotAsError $env:BUILDING_USING_DOTNET=$BUILDING_USING_DOTNET_ORIG } diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a96ff6fe1f..286094f1ce 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,6 +1,6 @@ - + https://github.com/dotnet/msbuild diff --git a/eng/build.sh b/eng/build.sh index d0d1871241..9a0ed19d04 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -40,6 +40,7 @@ usage() echo " --fromVMR Set when building from within the VMR" echo " --buildnorealsig Build product with realsig- (default use realsig+ where necessary)" echo " --tfm Override the default target framework" + echo " --warnNotAsError Suppress specific warnings from being treated as errors (semi-colon delimited)" echo "" echo "Command line arguments starting with '/p:' are passed through to MSBuild." } @@ -80,6 +81,7 @@ product_build=false from_vmr=false buildnorealsig=true properties="" +warn_not_as_error="" docker=false args="" @@ -189,6 +191,10 @@ while [[ $# > 0 ]]; do tfm=$2 shift ;; + --warnnotaserror) + warn_not_as_error=$2 + shift + ;; /p:*) properties+=("$1") ;; @@ -328,6 +334,11 @@ function BuildSolution { # do real build BuildMessage="Error building solution" + local msbuild_warn_not_as_error="" + if [[ "$warn_not_as_error" != "" && "$warn_as_error" == true ]]; then + msbuild_warn_not_as_error="/warnNotAsError:$warn_not_as_error" + fi + MSBuild $toolset_build_proj \ $bl \ /p:Configuration=$configuration \ @@ -347,7 +358,8 @@ function BuildSolution { /p:DotNetBuild=$product_build \ /p:DotNetBuildSourceOnly=$source_build \ /p:DotNetBuildFromVMR=$from_vmr \ - ${properties[@]+"${properties[@]}"} + ${properties[@]+"${properties[@]}"} \ + $msbuild_warn_not_as_error fi }