├── .editorconfig
├── .gitignore
├── CODE-OF-CONDUCT.md
├── Directory.Build.props
├── Directory.Build.targets
├── LICENSE.txt
├── NuGet.config
├── README.md
├── SECURITY.md
├── THIRD-PARTY-NOTICES.txt
├── build.sh
├── dotnet.sh
├── eng
├── Build.props
├── BuildTask.targets
├── Publishing.props
├── Version.Details.xml
├── Versions.props
├── azure-pipelines.yml
└── common
│ ├── BuildConfiguration
│ └── build-configuration.json
│ ├── CIBuild.cmd
│ ├── PSScriptAnalyzerSettings.psd1
│ ├── README.md
│ ├── SetupNugetSources.ps1
│ ├── SetupNugetSources.sh
│ ├── build.cmd
│ ├── build.ps1
│ ├── build.sh
│ ├── cibuild.sh
│ ├── core-templates
│ ├── job
│ │ ├── job.yml
│ │ ├── onelocbuild.yml
│ │ ├── publish-build-assets.yml
│ │ ├── source-build.yml
│ │ └── source-index-stage1.yml
│ ├── jobs
│ │ ├── codeql-build.yml
│ │ ├── jobs.yml
│ │ └── source-build.yml
│ ├── post-build
│ │ ├── common-variables.yml
│ │ ├── post-build.yml
│ │ └── setup-maestro-vars.yml
│ ├── steps
│ │ ├── cleanup-microbuild.yml
│ │ ├── component-governance.yml
│ │ ├── enable-internal-runtimes.yml
│ │ ├── enable-internal-sources.yml
│ │ ├── generate-sbom.yml
│ │ ├── get-delegation-sas.yml
│ │ ├── get-federated-access-token.yml
│ │ ├── install-microbuild.yml
│ │ ├── publish-build-artifacts.yml
│ │ ├── publish-logs.yml
│ │ ├── publish-pipeline-artifacts.yml
│ │ ├── retain-build.yml
│ │ ├── send-to-helix.yml
│ │ ├── source-build.yml
│ │ └── source-index-stage1-publish.yml
│ └── variables
│ │ └── pool-providers.yml
│ ├── cross
│ ├── arm
│ │ └── tizen
│ │ │ └── tizen.patch
│ ├── arm64
│ │ └── tizen
│ │ │ └── tizen.patch
│ ├── armel
│ │ └── tizen
│ │ │ └── tizen.patch
│ ├── build-android-rootfs.sh
│ ├── build-rootfs.sh
│ ├── install-debs.py
│ ├── riscv64
│ │ └── tizen
│ │ │ └── tizen.patch
│ ├── tizen-build-rootfs.sh
│ ├── tizen-fetch.sh
│ ├── toolchain.cmake
│ ├── x64
│ │ └── tizen
│ │ │ └── tizen.patch
│ └── x86
│ │ └── tizen
│ │ └── tizen.patch
│ ├── darc-init.ps1
│ ├── darc-init.sh
│ ├── dotnet-install.cmd
│ ├── dotnet-install.ps1
│ ├── dotnet-install.sh
│ ├── enable-cross-org-publishing.ps1
│ ├── generate-locproject.ps1
│ ├── generate-sbom-prep.ps1
│ ├── generate-sbom-prep.sh
│ ├── helixpublish.proj
│ ├── init-tools-native.cmd
│ ├── init-tools-native.ps1
│ ├── init-tools-native.sh
│ ├── internal-feed-operations.ps1
│ ├── internal-feed-operations.sh
│ ├── internal
│ ├── Directory.Build.props
│ ├── NuGet.config
│ └── Tools.csproj
│ ├── loc
│ └── P22DotNetHtmlLocalization.lss
│ ├── msbuild.ps1
│ ├── msbuild.sh
│ ├── native
│ ├── CommonLibrary.psm1
│ ├── common-library.sh
│ ├── init-compiler.sh
│ ├── init-distro-rid.sh
│ ├── init-os-and-arch.sh
│ ├── install-cmake-test.sh
│ ├── install-cmake.sh
│ ├── install-dependencies.sh
│ └── install-tool.ps1
│ ├── pipeline-logging-functions.ps1
│ ├── pipeline-logging-functions.sh
│ ├── post-build
│ ├── check-channel-consistency.ps1
│ ├── nuget-validation.ps1
│ ├── nuget-verification.ps1
│ ├── publish-using-darc.ps1
│ ├── redact-logs.ps1
│ ├── sourcelink-validation.ps1
│ └── symbols-validation.ps1
│ ├── retain-build.ps1
│ ├── sdk-task.ps1
│ ├── sdk-task.sh
│ ├── sdl
│ ├── NuGet.config
│ ├── configure-sdl-tool.ps1
│ ├── execute-all-sdl-tools.ps1
│ ├── extract-artifact-archives.ps1
│ ├── extract-artifact-packages.ps1
│ ├── init-sdl.ps1
│ ├── packages.config
│ ├── run-sdl.ps1
│ ├── sdl.ps1
│ └── trim-assets-version.ps1
│ ├── template-guidance.md
│ ├── templates-official
│ ├── job
│ │ ├── job.yml
│ │ ├── onelocbuild.yml
│ │ ├── publish-build-assets.yml
│ │ ├── source-build.yml
│ │ └── source-index-stage1.yml
│ ├── jobs
│ │ ├── codeql-build.yml
│ │ ├── jobs.yml
│ │ └── source-build.yml
│ ├── post-build
│ │ ├── common-variables.yml
│ │ ├── post-build.yml
│ │ └── setup-maestro-vars.yml
│ ├── steps
│ │ ├── component-governance.yml
│ │ ├── enable-internal-runtimes.yml
│ │ ├── enable-internal-sources.yml
│ │ ├── generate-sbom.yml
│ │ ├── get-delegation-sas.yml
│ │ ├── get-federated-access-token.yml
│ │ ├── publish-build-artifacts.yml
│ │ ├── publish-logs.yml
│ │ ├── publish-pipeline-artifacts.yml
│ │ ├── retain-build.yml
│ │ ├── send-to-helix.yml
│ │ ├── source-build.yml
│ │ └── source-index-stage1-publish.yml
│ └── variables
│ │ ├── pool-providers.yml
│ │ └── sdl-variables.yml
│ ├── templates
│ ├── job
│ │ ├── job.yml
│ │ ├── onelocbuild.yml
│ │ ├── publish-build-assets.yml
│ │ ├── source-build.yml
│ │ └── source-index-stage1.yml
│ ├── jobs
│ │ ├── codeql-build.yml
│ │ ├── jobs.yml
│ │ └── source-build.yml
│ ├── post-build
│ │ ├── common-variables.yml
│ │ ├── post-build.yml
│ │ └── setup-maestro-vars.yml
│ ├── steps
│ │ ├── component-governance.yml
│ │ ├── enable-internal-runtimes.yml
│ │ ├── enable-internal-sources.yml
│ │ ├── generate-sbom.yml
│ │ ├── get-delegation-sas.yml
│ │ ├── get-federated-access-token.yml
│ │ ├── publish-build-artifacts.yml
│ │ ├── publish-logs.yml
│ │ ├── publish-pipeline-artifacts.yml
│ │ ├── retain-build.yml
│ │ ├── send-to-helix.yml
│ │ ├── source-build.yml
│ │ ├── source-index-stage1-publish.yml
│ │ └── vmr-sync.yml
│ ├── variables
│ │ └── pool-providers.yml
│ └── vmr-build-pr.yml
│ ├── tools.ps1
│ ├── tools.sh
│ ├── vmr-sync.ps1
│ └── vmr-sync.sh
├── global.json
├── hotreload-utils.proj
├── src
├── Common
│ └── TempDirectory.cs
├── Microsoft.DotNet.HotReload.Utils.Generator.BuildTool
│ ├── Microsoft.DotNet.HotReload.Utils.Generator.BuildTool.csproj
│ ├── Microsoft.DotNet.HotReload.Utils.Generator.BuildTool.targets.in
│ ├── Program.cs
│ └── README.md
├── Microsoft.DotNet.HotReload.Utils.Generator.Data
│ ├── Microsoft.DotNet.HotReload.Utils.Generator.Data.csproj
│ ├── OutputSummary
│ │ └── OutputSummary.cs
│ ├── Script
│ │ └── Json
│ │ │ ├── Script.cs
│ │ │ └── ScriptCapabilitiesConverter.cs
│ └── UpdateHandlerInfo.cs
├── Microsoft.DotNet.HotReload.Utils.Generator.Frontend
│ ├── Frontend.cs
│ └── Microsoft.DotNet.HotReload.Utils.Generator.Frontend.csproj
├── Microsoft.DotNet.HotReload.Utils.Generator.Tasks
│ ├── HotReloadDeltaGeneratorComputeScriptOutputs.cs
│ └── Microsoft.DotNet.HotReload.Utils.Generator.Tasks.csproj
├── Microsoft.DotNet.HotReload.Utils.Generator
│ ├── BaselineArtifacts.cs
│ ├── BaselineProject.cs
│ ├── Config.cs
│ ├── Delta.cs
│ ├── DeltaNaming.cs
│ ├── DeltaOutputStreams.cs
│ ├── DeltaProject.cs
│ ├── DiffyException.cs
│ ├── DocResolver.cs
│ ├── EditAndContinueCapabilitiesParser.cs
│ ├── EnC
│ │ ├── ChangeMaker.cs
│ │ ├── ChangeMakerService.cs
│ │ └── EditAndContinueCapabilities.cs
│ ├── Microsoft.DotNet.HotReload.Utils.Generator.csproj
│ ├── Plan
│ │ └── Change.cs
│ ├── Runner.cs
│ ├── Runners
│ │ ├── LiveRunner.cs
│ │ └── ScriptRunner.cs
│ ├── Script
│ │ ├── Json
│ │ │ └── Parsing.cs
│ │ └── ParsedScript.cs
│ └── Util
│ │ ├── AsyncEnumerableExtras.cs
│ │ └── FSWGen.cs
└── hotreload-delta-gen
│ ├── README.md
│ ├── example
│ ├── TestClass.cs
│ ├── TestClass.csproj
│ ├── TestClass_v1.cs
│ ├── TestClass_v2.cs
│ ├── TestClass_v3.cs
│ └── diffscript.json
│ └── src
│ ├── Program.cs
│ └── hotreload-delta-gen.csproj
└── tests
├── Acceptance
└── EncCapabilitiesCompat.Tests
│ ├── EncCapabilitiesCompat.Tests.csproj
│ └── EncCapabilitiesCompat.cs
├── BuildTool
├── ImportExplcitly.ShouldNotRun.Tests
│ ├── ImportExplicitly.ShouldNotRun.Tests.csproj
│ └── ImportExplicitly.ShouldNotRun.cs
├── ImportExplcitly.Tests
│ ├── ImportExplicitly.Tests.csproj
│ ├── ImportExplicitly.cs
│ ├── TargetClass.cs
│ ├── TargetClass.cs.v1
│ └── delta.json
└── ImportExplicitly.props
└── HotReload.Generator
├── EnC.Tests
├── Assembly.NoParallelism.cs
├── CommonFixtures.cs
├── EnC.Tests.csproj
├── TempMSBuildWorkspaceTest.cs
└── WatchHotReloadServiceTest.cs
└── README.md
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 4
6 | charset = utf-8
7 | trim_trailing_whitespace = true
8 | insert_final_newline = true
9 |
10 | # Xml project files
11 | [*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}]
12 | indent_size = 2
13 |
14 | # Xml config files
15 | [*.{props,targets,config,nuspec}]
16 | indent_size = 2
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .dotnet/
2 | .packages/
3 | Output/
4 | artifacts/
5 | bin/
6 | obj/
7 | publish/
8 | *~
9 | *.dll
10 | *.pdb
11 | *.dil
12 | *.dmeta
13 | *.dpdb
14 | /.vscode/
15 | /out/
16 |
--------------------------------------------------------------------------------
/CODE-OF-CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | This project has adopted the code of conduct defined by the Contributor Covenant
4 | to clarify expected behavior in our community.
5 |
6 | For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).
7 |
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(CopyrightNetFoundation)
7 | MIT
8 | True
9 | embedded
10 | true
11 | Latest
12 | $(NetCurrent)
13 | enable
14 |
15 |
18 | false
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) .NET Foundation and Contributors
4 |
5 | All rights reserved.
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE.
24 |
--------------------------------------------------------------------------------
/NuGet.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Hot Reload Utilities #
2 |
3 | Testing utilities for ".NET Hot Reload".
4 |
5 | ## What's in here ##
6 |
7 | - [Microsoft.DotNet.HotReload.Utils.Generator.BuildTool](src/Microsoft.DotNet.HotReload.Utils.Generator.BuildTool/) - MSBuild integration package to generate deltas from a script of changes. This is what you want for CI testing. ([README.md](src/Microsoft.DotNet.HotReload.Utils.Generator.BuildTool/README.md))
8 |
9 |
10 | - [Microsoft.DotNet.HotReload.Utils.Generator](src/Microsoft.DotNet.HotReload.Utils.Generator/) - A library for creating tools that generate hot reload deltas.
11 | - [hotreload-delta-gen](src/hotreload-delta-gen/) - A script-driven delta generator packaged as a `dotnet tool`. This is mostly useful for experimentation. ([README.md](src/hotreload-delta-gen/README.md))
12 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Security
4 |
5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
6 |
7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below.
8 |
9 | ## Reporting Security Issues
10 |
11 | **Please do not report security vulnerabilities through public GitHub issues.**
12 |
13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report).
14 |
15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc).
16 |
17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).
18 |
19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
20 |
21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
22 | * Full paths of source file(s) related to the manifestation of the issue
23 | * The location of the affected source code (tag/branch/commit or direct URL)
24 | * Any special configuration required to reproduce the issue
25 | * Step-by-step instructions to reproduce the issue
26 | * Proof-of-concept or exploit code (if possible)
27 | * Impact of the issue, including how an attacker might exploit the issue
28 |
29 | This information will help us triage your report more quickly.
30 |
31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs.
32 |
33 | ## Preferred Languages
34 |
35 | We prefer all communications to be in English.
36 |
37 | ## Policy
38 |
39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd).
40 |
41 |
42 |
--------------------------------------------------------------------------------
/THIRD-PARTY-NOTICES.txt:
--------------------------------------------------------------------------------
1 | .NET Runtime uses third-party libraries or other resources that may be
2 | distributed under licenses different than the .NET Runtime software.
3 |
4 | In the event that we accidentally failed to list a required notice, please
5 | bring it to our attention. Post an issue or email us:
6 |
7 | dotnet@microsoft.com
8 |
9 | The attached notices are provided for information only.
10 |
11 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source="${BASH_SOURCE[0]}"
4 |
5 | # resolve $SOURCE until the file is no longer a symlink
6 | while [[ -h $source ]]; do
7 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
8 | source="$(readlink "$source")"
9 |
10 | # if $source was a relative symlink, we need to resolve it relative to the path where the
11 | # symlink file was located
12 | [[ $source != /* ]] && source="$scriptroot/$source"
13 | done
14 |
15 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
16 |
17 | "$scriptroot/eng/common/build.sh" $@
18 |
19 |
--------------------------------------------------------------------------------
/dotnet.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source="${BASH_SOURCE[0]}"
4 | # resolve $SOURCE until the file is no longer a symlink
5 | while [[ -h $source ]]; do
6 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
7 | source="$(readlink "$source")"
8 |
9 | # if $source was a relative symlink, we need to resolve it relative to the path where the
10 | # symlink file was located
11 | [[ $source != /* ]] && source="$scriptroot/$source"
12 | done
13 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
14 |
15 | # Don't resolve runtime, shared framework, or SDK from other locations to ensure build determinism
16 | export DOTNET_MULTILEVEL_LOOKUP=0
17 |
18 | # Disable first run since we want to control all package sources
19 | export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
20 |
21 | source $scriptroot/eng/common/tools.sh
22 |
23 | InitializeDotNetCli true # Install
24 | __dotnetDir=${_InitializeDotNetCli}
25 |
26 | dotnetPath=${__dotnetDir}/dotnet
27 | ${dotnetPath} "$@"
28 |
--------------------------------------------------------------------------------
/eng/Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/eng/Publishing.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 3
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/eng/Version.Details.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | https://github.com/dotnet/roslyn
6 | 1119c85de2f6e18124cb27816c5fb189af0745a4
7 |
8 |
9 |
10 |
11 | https://github.com/dotnet/arcade
12 | aba421eb78276b26d1a24df7772474806b27aa13
13 |
14 |
15 | https://github.com/dotnet/arcade
16 | aba421eb78276b26d1a24df7772474806b27aa13
17 |
18 |
19 | https://github.com/dotnet/arcade
20 | aba421eb78276b26d1a24df7772474806b27aa13
21 |
22 |
23 | https://github.com/dotnet/arcade
24 | aba421eb78276b26d1a24df7772474806b27aa13
25 |
26 |
27 | https://github.com/dotnet/arcade
28 | aba421eb78276b26d1a24df7772474806b27aa13
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/eng/Versions.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 10.0.0
6 |
7 | alpha
8 |
9 | 0
10 |
11 | false
12 |
13 | 3.11.0
14 | 5.0.0-1.25308.2
15 |
16 | 10.0.0-beta.25305.3
17 | 10.0.0-beta.25305.3
18 | 10.0.0-beta.25305.3
19 | 2.9.2-beta.25305.3
20 |
24 | 17.11.4
25 | $(RefOnlyMicrosoftBuildVersion)
26 | $(RefOnlyMicrosoftBuildVersion)
27 | $(RefOnlyMicrosoftBuildVersion)
28 |
29 |
30 |
--------------------------------------------------------------------------------
/eng/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | variables:
2 | - template: /eng/common/templates/variables/pool-providers.yml
3 | - name: Build.Repository.Clean
4 | value: true
5 | - name: _TeamName
6 | value: DotNetCore
7 | - name: _InternalBuildArgs
8 | value: ''
9 | - name: _InternalPublishArg
10 | value: ''
11 |
12 | - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
13 | - name: _SignType
14 | value: real
15 | # Publish-Build-Assets provides: MaestroAccessToken, BotAccount-dotnet-maestro-bot-PAT
16 | # DotNet-HelixApi-Access provides: HelixApiAccessToken
17 | - group: Publish-Build-Assets
18 | - group: DotNet-HelixApi-Access
19 | - group: SDL_Settings
20 | - name: _InternalPublishArg
21 | value: -publish
22 | - name: _InternalBuildArgs
23 | value: /p:DotNetSignType=$(_SignType)
24 | /p:TeamName=$(_TeamName)
25 | /p:DotNetPublishUsingPipelines=true
26 | /p:OfficialBuildId=$(BUILD.BUILDNUMBER)
27 |
28 | trigger:
29 | batch: true
30 | branches:
31 | include:
32 | - main
33 | - release/*
34 |
35 | pr:
36 | branches:
37 | include:
38 | - main
39 | - release/*
40 |
41 | stages:
42 | - stage: build
43 | displayName: Build
44 | jobs:
45 | - template: /eng/common/templates/jobs/jobs.yml
46 | parameters:
47 | enablePublishBuildArtifacts: true
48 | enablePublishBuildAssets: true
49 | enablePublishUsingPipelines: true
50 | variables:
51 | - _BuildConfig: Release
52 | jobs:
53 | - job: Build_Linux
54 | displayName: Linux
55 | timeoutInMinutes: 30
56 | pool:
57 | ${{ if eq(variables['System.TeamProject'], 'public') }}:
58 | name: $(DncEngPublicBuildPool)
59 | demands: ImageOverride -equals build.ubuntu.2204.amd64.open
60 | ${{ if eq(variables['System.TeamProject'], 'internal') }}:
61 | name: $(DncEngInternalBuildPool)
62 | demands: ImageOverride -equals build.ubuntu.2204.amd64
63 | steps:
64 | - bash: |
65 | eng/common/cibuild.sh -configuration $(_BuildConfig) $(_InternalPublishArg) /p:ToolConfiguration=$(_BuildConfig) /p:ToolRid=linux-x64 $(_InternalBuildArgs)
66 | displayName: Build and Publish
67 |
68 | - task: PublishTestResults@2
69 | displayName: Publish Test Results
70 | inputs:
71 | testRunner: XUnit
72 | testResultsFiles: 'artifacts/TestResults/$(_BuildConfig)/*.xml'
73 | mergeTestResults: true
74 | testRunTitle: 'Unit Tests'
75 | condition: always()
76 |
77 | ############ POST BUILD ARCADE LOGIC ############
78 | - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
79 | - template: /eng/common/templates/post-build/post-build.yml
80 | parameters:
81 | publishingInfraVersion: 3
82 | enableSourceLinkValidation: true
83 | enableSigningValidation: false
84 | enableSymbolValidation: false
85 | enableNugetValidation: true
86 |
--------------------------------------------------------------------------------
/eng/common/BuildConfiguration/build-configuration.json:
--------------------------------------------------------------------------------
1 | {
2 | "RetryCountLimit": 1,
3 | "RetryByAnyError": false
4 | }
5 |
--------------------------------------------------------------------------------
/eng/common/CIBuild.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 | powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0Build.ps1""" -restore -build -test -sign -pack -publish -ci %*"
3 |
--------------------------------------------------------------------------------
/eng/common/PSScriptAnalyzerSettings.psd1:
--------------------------------------------------------------------------------
1 | @{
2 | IncludeRules=@('PSAvoidUsingCmdletAliases',
3 | 'PSAvoidUsingWMICmdlet',
4 | 'PSAvoidUsingPositionalParameters',
5 | 'PSAvoidUsingInvokeExpression',
6 | 'PSUseDeclaredVarsMoreThanAssignments',
7 | 'PSUseCmdletCorrectly',
8 | 'PSStandardDSCFunctionsInResource',
9 | 'PSUseIdenticalMandatoryParametersForDSC',
10 | 'PSUseIdenticalParametersForDSC')
11 | }
--------------------------------------------------------------------------------
/eng/common/README.md:
--------------------------------------------------------------------------------
1 | # Don't touch this folder
2 |
3 | uuuuuuuuuuuuuuuuuuuu
4 | u" uuuuuuuuuuuuuuuuuu "u
5 | u" u$$$$$$$$$$$$$$$$$$$$u "u
6 | u" u$$$$$$$$$$$$$$$$$$$$$$$$u "u
7 | u" u$$$$$$$$$$$$$$$$$$$$$$$$$$$$u "u
8 | u" u$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$u "u
9 | u" u$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$u "u
10 | $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $
11 | $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $
12 | $ $$$" ... "$... ...$" ... "$$$ ... "$$$ $
13 | $ $$$u `"$$$$$$$ $$$ $$$$$ $$ $$$ $$$ $
14 | $ $$$$$$uu "$$$$ $$$ $$$$$ $$ """ u$$$ $
15 | $ $$$""$$$ $$$$ $$$u "$$$" u$$ $$$$$$$$ $
16 | $ $$$$....,$$$$$..$$$$$....,$$$$..$$$$$$$$ $
17 | $ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $
18 | "u "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" u"
19 | "u "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" u"
20 | "u "$$$$$$$$$$$$$$$$$$$$$$$$$$$$" u"
21 | "u "$$$$$$$$$$$$$$$$$$$$$$$$" u"
22 | "u "$$$$$$$$$$$$$$$$$$$$" u"
23 | "u """""""""""""""""" u"
24 | """"""""""""""""""""
25 |
26 | !!! Changes made in this directory are subject to being overwritten by automation !!!
27 |
28 | The files in this directory are shared by all Arcade repos and managed by automation. If you need to make changes to these files, open an issue or submit a pull request to https://github.com/dotnet/arcade first.
29 |
--------------------------------------------------------------------------------
/eng/common/build.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 | powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0build.ps1""" %*"
3 | exit /b %ErrorLevel%
4 |
--------------------------------------------------------------------------------
/eng/common/cibuild.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source="${BASH_SOURCE[0]}"
4 |
5 | # resolve $SOURCE until the file is no longer a symlink
6 | while [[ -h $source ]]; do
7 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
8 | source="$(readlink "$source")"
9 |
10 | # if $source was a relative symlink, we need to resolve it relative to the path where
11 | # the symlink file was located
12 | [[ $source != /* ]] && source="$scriptroot/$source"
13 | done
14 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
15 |
16 | . "$scriptroot/build.sh" --restore --build --test --pack --publish --ci $@
17 |
--------------------------------------------------------------------------------
/eng/common/core-templates/job/source-index-stage1.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | runAsPublic: false
3 | sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci"
4 | preSteps: []
5 | binlogPath: artifacts/log/Debug/Build.binlog
6 | condition: ''
7 | dependsOn: ''
8 | pool: ''
9 | is1ESPipeline: ''
10 |
11 | jobs:
12 | - job: SourceIndexStage1
13 | dependsOn: ${{ parameters.dependsOn }}
14 | condition: ${{ parameters.condition }}
15 | variables:
16 | - name: BinlogPath
17 | value: ${{ parameters.binlogPath }}
18 | - template: /eng/common/core-templates/variables/pool-providers.yml
19 | parameters:
20 | is1ESPipeline: ${{ parameters.is1ESPipeline }}
21 |
22 | ${{ if ne(parameters.pool, '') }}:
23 | pool: ${{ parameters.pool }}
24 | ${{ if eq(parameters.pool, '') }}:
25 | pool:
26 | ${{ if eq(variables['System.TeamProject'], 'public') }}:
27 | name: $(DncEngPublicBuildPool)
28 | image: windows.vs2022.amd64.open
29 | ${{ if eq(variables['System.TeamProject'], 'internal') }}:
30 | name: $(DncEngInternalBuildPool)
31 | image: windows.vs2022.amd64
32 |
33 | steps:
34 | - ${{ if eq(parameters.is1ESPipeline, '') }}:
35 | - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error
36 |
37 | - ${{ each preStep in parameters.preSteps }}:
38 | - ${{ preStep }}
39 | - script: ${{ parameters.sourceIndexBuildCommand }}
40 | displayName: Build Repository
41 |
42 | - template: /eng/common/core-templates/steps/source-index-stage1-publish.yml
43 | parameters:
44 | binLogPath: ${{ parameters.binLogPath }}
--------------------------------------------------------------------------------
/eng/common/core-templates/jobs/codeql-build.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md
3 | continueOnError: false
4 | # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job
5 | jobs: []
6 | # Optional: if specified, restore and use this version of Guardian instead of the default.
7 | overrideGuardianVersion: ''
8 | is1ESPipeline: ''
9 |
10 | jobs:
11 | - template: /eng/common/core-templates/jobs/jobs.yml
12 | parameters:
13 | is1ESPipeline: ${{ parameters.is1ESPipeline }}
14 | enableMicrobuild: false
15 | enablePublishBuildArtifacts: false
16 | enablePublishTestResults: false
17 | enablePublishBuildAssets: false
18 | enableTelemetry: true
19 |
20 | variables:
21 | - group: Publish-Build-Assets
22 | # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in
23 | # sync with the packages.config file.
24 | - name: DefaultGuardianVersion
25 | value: 0.109.0
26 | - name: GuardianPackagesConfigFile
27 | value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config
28 | - name: GuardianVersion
29 | value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }}
30 |
31 | jobs: ${{ parameters.jobs }}
32 |
33 |
--------------------------------------------------------------------------------
/eng/common/core-templates/jobs/source-build.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | # This template adds arcade-powered source-build to CI. A job is created for each platform, as
3 | # well as an optional server job that completes when all platform jobs complete.
4 |
5 | # The name of the "join" job for all source-build platforms. If set to empty string, the job is
6 | # not included. Existing repo pipelines can use this job depend on all source-build jobs
7 | # completing without maintaining a separate list of every single job ID: just depend on this one
8 | # server job. By default, not included. Recommended name if used: 'Source_Build_Complete'.
9 | allCompletedJobId: ''
10 |
11 | # See /eng/common/core-templates/job/source-build.yml
12 | jobNamePrefix: 'Source_Build'
13 |
14 | # This is the default platform provided by Arcade, intended for use by a managed-only repo.
15 | defaultManagedPlatform:
16 | name: 'Managed'
17 | container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream-10-amd64'
18 |
19 | # Defines the platforms on which to run build jobs. One job is created for each platform, and the
20 | # object in this array is sent to the job template as 'platform'. If no platforms are specified,
21 | # one job runs on 'defaultManagedPlatform'.
22 | platforms: []
23 |
24 | is1ESPipeline: ''
25 |
26 | # If set to true and running on a non-public project,
27 | # Internal nuget and blob storage locations will be enabled.
28 | # This is not enabled by default because many repositories do not need internal sources
29 | # and do not need to have the required service connections approved in the pipeline.
30 | enableInternalSources: false
31 |
32 | jobs:
33 |
34 | - ${{ if ne(parameters.allCompletedJobId, '') }}:
35 | - job: ${{ parameters.allCompletedJobId }}
36 | displayName: Source-Build Complete
37 | pool: server
38 | dependsOn:
39 | - ${{ each platform in parameters.platforms }}:
40 | - ${{ parameters.jobNamePrefix }}_${{ platform.name }}
41 | - ${{ if eq(length(parameters.platforms), 0) }}:
42 | - ${{ parameters.jobNamePrefix }}_${{ parameters.defaultManagedPlatform.name }}
43 |
44 | - ${{ each platform in parameters.platforms }}:
45 | - template: /eng/common/core-templates/job/source-build.yml
46 | parameters:
47 | is1ESPipeline: ${{ parameters.is1ESPipeline }}
48 | jobNamePrefix: ${{ parameters.jobNamePrefix }}
49 | platform: ${{ platform }}
50 | enableInternalSources: ${{ parameters.enableInternalSources }}
51 |
52 | - ${{ if eq(length(parameters.platforms), 0) }}:
53 | - template: /eng/common/core-templates/job/source-build.yml
54 | parameters:
55 | is1ESPipeline: ${{ parameters.is1ESPipeline }}
56 | jobNamePrefix: ${{ parameters.jobNamePrefix }}
57 | platform: ${{ parameters.defaultManagedPlatform }}
58 | enableInternalSources: ${{ parameters.enableInternalSources }}
59 |
--------------------------------------------------------------------------------
/eng/common/core-templates/post-build/common-variables.yml:
--------------------------------------------------------------------------------
1 | variables:
2 | - group: Publish-Build-Assets
3 |
4 | # Whether the build is internal or not
5 | - name: IsInternalBuild
6 | value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }}
7 |
8 | # Default Maestro++ API Endpoint and API Version
9 | - name: MaestroApiEndPoint
10 | value: "https://maestro.dot.net"
11 | - name: MaestroApiVersion
12 | value: "2020-02-20"
13 |
14 | - name: SourceLinkCLIVersion
15 | value: 3.0.0
16 | - name: SymbolToolVersion
17 | value: 1.0.1
18 | - name: BinlogToolVersion
19 | value: 1.0.11
20 |
21 | - name: runCodesignValidationInjection
22 | value: false
23 |
--------------------------------------------------------------------------------
/eng/common/core-templates/post-build/setup-maestro-vars.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | BARBuildId: ''
3 | PromoteToChannelIds: ''
4 | is1ESPipeline: ''
5 |
6 | steps:
7 | - ${{ if eq(parameters.is1ESPipeline, '') }}:
8 | - 'Illegal entry point, is1ESPipeline is not defined. Repository yaml should not directly reference templates in core-templates folder.': error
9 |
10 | - ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}:
11 | - task: DownloadBuildArtifacts@0
12 | displayName: Download Release Configs
13 | inputs:
14 | buildType: current
15 | artifactName: ReleaseConfigs
16 | checkDownloadedFiles: true
17 |
18 | - task: AzureCLI@2
19 | name: setReleaseVars
20 | displayName: Set Release Configs Vars
21 | inputs:
22 | azureSubscription: "Darc: Maestro Production"
23 | scriptType: pscore
24 | scriptLocation: inlineScript
25 | inlineScript: |
26 | try {
27 | if (!$Env:PromoteToMaestroChannels -or $Env:PromoteToMaestroChannels.Trim() -eq '') {
28 | $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt
29 |
30 | $BarId = $Content | Select -Index 0
31 | $Channels = $Content | Select -Index 1
32 | $IsStableBuild = $Content | Select -Index 2
33 |
34 | $AzureDevOpsProject = $Env:System_TeamProject
35 | $AzureDevOpsBuildDefinitionId = $Env:System_DefinitionId
36 | $AzureDevOpsBuildId = $Env:Build_BuildId
37 | }
38 | else {
39 | . $(Build.SourcesDirectory)\eng\common\tools.ps1
40 | $darc = Get-Darc
41 | $buildInfo = & $darc get-build `
42 | --id ${{ parameters.BARBuildId }} `
43 | --extended `
44 | --output-format json `
45 | --ci `
46 | | convertFrom-Json
47 |
48 | $BarId = ${{ parameters.BARBuildId }}
49 | $Channels = $Env:PromoteToMaestroChannels -split ","
50 | $Channels = $Channels -join "]["
51 | $Channels = "[$Channels]"
52 |
53 | $IsStableBuild = $buildInfo.stable
54 | $AzureDevOpsProject = $buildInfo.azureDevOpsProject
55 | $AzureDevOpsBuildDefinitionId = $buildInfo.azureDevOpsBuildDefinitionId
56 | $AzureDevOpsBuildId = $buildInfo.azureDevOpsBuildId
57 | }
58 |
59 | Write-Host "##vso[task.setvariable variable=BARBuildId]$BarId"
60 | Write-Host "##vso[task.setvariable variable=TargetChannels]$Channels"
61 | Write-Host "##vso[task.setvariable variable=IsStableBuild]$IsStableBuild"
62 |
63 | Write-Host "##vso[task.setvariable variable=AzDOProjectName]$AzureDevOpsProject"
64 | Write-Host "##vso[task.setvariable variable=AzDOPipelineId]$AzureDevOpsBuildDefinitionId"
65 | Write-Host "##vso[task.setvariable variable=AzDOBuildId]$AzureDevOpsBuildId"
66 | }
67 | catch {
68 | Write-Host $_
69 | Write-Host $_.Exception
70 | Write-Host $_.ScriptStackTrace
71 | exit 1
72 | }
73 | env:
74 | PromoteToMaestroChannels: ${{ parameters.PromoteToChannelIds }}
75 |
--------------------------------------------------------------------------------
/eng/common/core-templates/steps/cleanup-microbuild.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | # Enable cleanup tasks for MicroBuild
3 | enableMicrobuild: false
4 | # Enable cleanup tasks for MicroBuild on Mac and Linux
5 | # Will be ignored if 'enableMicrobuild' is false or 'Agent.Os' is 'Windows_NT'
6 | enableMicrobuildForMacAndLinux: false
7 | continueOnError: false
8 |
9 | steps:
10 | - ${{ if eq(parameters.enableMicrobuild, 'true') }}:
11 | - task: MicroBuildCleanup@1
12 | displayName: Execute Microbuild cleanup tasks
13 | condition: and(
14 | always(),
15 | or(
16 | and(
17 | eq(variables['Agent.Os'], 'Windows_NT'),
18 | in(variables['_SignType'], 'real', 'test')
19 | ),
20 | and(
21 | ${{ eq(parameters.enableMicrobuildForMacAndLinux, true) }},
22 | ne(variables['Agent.Os'], 'Windows_NT'),
23 | eq(variables['_SignType'], 'real')
24 | )
25 | ))
26 | continueOnError: ${{ parameters.continueOnError }}
27 | env:
28 | TeamName: $(_TeamName)
29 |
--------------------------------------------------------------------------------
/eng/common/core-templates/steps/component-governance.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | disableComponentGovernance: false
3 | componentGovernanceIgnoreDirectories: ''
4 | is1ESPipeline: false
5 | displayName: 'Component Detection'
6 |
7 | steps:
8 | - ${{ if eq(parameters.disableComponentGovernance, 'true') }}:
9 | - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true"
10 | displayName: Set skipComponentGovernanceDetection variable
11 | - ${{ if ne(parameters.disableComponentGovernance, 'true') }}:
12 | - task: ComponentGovernanceComponentDetection@0
13 | continueOnError: true
14 | displayName: ${{ parameters.displayName }}
15 | inputs:
16 | ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }}
17 |
--------------------------------------------------------------------------------
/eng/common/core-templates/steps/enable-internal-runtimes.yml:
--------------------------------------------------------------------------------
1 | # Obtains internal runtime download credentials and populates the 'dotnetbuilds-internal-container-read-token-base64'
2 | # variable with the base64-encoded SAS token, by default
3 |
4 | parameters:
5 | - name: federatedServiceConnection
6 | type: string
7 | default: 'dotnetbuilds-internal-read'
8 | - name: outputVariableName
9 | type: string
10 | default: 'dotnetbuilds-internal-container-read-token-base64'
11 | - name: expiryInHours
12 | type: number
13 | default: 1
14 | - name: base64Encode
15 | type: boolean
16 | default: true
17 | - name: is1ESPipeline
18 | type: boolean
19 | default: false
20 |
21 | steps:
22 | - ${{ if ne(variables['System.TeamProject'], 'public') }}:
23 | - template: /eng/common/core-templates/steps/get-delegation-sas.yml
24 | parameters:
25 | federatedServiceConnection: ${{ parameters.federatedServiceConnection }}
26 | outputVariableName: ${{ parameters.outputVariableName }}
27 | expiryInHours: ${{ parameters.expiryInHours }}
28 | base64Encode: ${{ parameters.base64Encode }}
29 | storageAccount: dotnetbuilds
30 | container: internal
31 | permissions: rl
32 | is1ESPipeline: ${{ parameters.is1ESPipeline }}
--------------------------------------------------------------------------------
/eng/common/core-templates/steps/enable-internal-sources.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | # This is the Azure federated service connection that we log into to get an access token.
3 | - name: nugetFederatedServiceConnection
4 | type: string
5 | default: 'dnceng-artifacts-feeds-read'
6 | - name: is1ESPipeline
7 | type: boolean
8 | default: false
9 | # Legacy parameters to allow for PAT usage
10 | - name: legacyCredential
11 | type: string
12 | default: ''
13 |
14 | steps:
15 | - ${{ if ne(variables['System.TeamProject'], 'public') }}:
16 | - ${{ if ne(parameters.legacyCredential, '') }}:
17 | - task: PowerShell@2
18 | displayName: Setup Internal Feeds
19 | inputs:
20 | filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1
21 | arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $Env:Token
22 | env:
23 | Token: ${{ parameters.legacyCredential }}
24 | # If running on dnceng (internal project), just use the default behavior for NuGetAuthenticate.
25 | # If running on DevDiv, NuGetAuthenticate is not really an option. It's scoped to a single feed, and we have many feeds that
26 | # may be added. Instead, we'll use the traditional approach (add cred to nuget.config), but use an account token.
27 | - ${{ else }}:
28 | - ${{ if eq(variables['System.TeamProject'], 'internal') }}:
29 | - task: PowerShell@2
30 | displayName: Setup Internal Feeds
31 | inputs:
32 | filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1
33 | arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config
34 | - ${{ else }}:
35 | - template: /eng/common/templates/steps/get-federated-access-token.yml
36 | parameters:
37 | federatedServiceConnection: ${{ parameters.nugetFederatedServiceConnection }}
38 | outputVariableName: 'dnceng-artifacts-feeds-read-access-token'
39 | - task: PowerShell@2
40 | displayName: Setup Internal Feeds
41 | inputs:
42 | filePath: $(Build.SourcesDirectory)/eng/common/SetupNugetSources.ps1
43 | arguments: -ConfigFile $(Build.SourcesDirectory)/NuGet.config -Password $(dnceng-artifacts-feeds-read-access-token)
44 | # This is required in certain scenarios to install the ADO credential provider.
45 | # It installed by default in some msbuild invocations (e.g. VS msbuild), but needs to be installed for others
46 | # (e.g. dotnet msbuild).
47 | - task: NuGetAuthenticate@1
48 |
--------------------------------------------------------------------------------
/eng/common/core-templates/steps/generate-sbom.yml:
--------------------------------------------------------------------------------
1 | # BuildDropPath - The root folder of the drop directory for which the manifest file will be generated.
2 | # PackageName - The name of the package this SBOM represents.
3 | # PackageVersion - The version of the package this SBOM represents.
4 | # ManifestDirPath - The path of the directory where the generated manifest files will be placed
5 | # IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector.
6 |
7 | parameters:
8 | PackageVersion: 10.0.0
9 | BuildDropPath: '$(Build.SourcesDirectory)/artifacts'
10 | PackageName: '.NET'
11 | ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom
12 | IgnoreDirectories: ''
13 | sbomContinueOnError: true
14 | is1ESPipeline: false
15 | # disable publishArtifacts if some other step is publishing the artifacts (like job.yml).
16 | publishArtifacts: true
17 |
18 | steps:
19 | - task: PowerShell@2
20 | displayName: Prep for SBOM generation in (Non-linux)
21 | condition: or(eq(variables['Agent.Os'], 'Windows_NT'), eq(variables['Agent.Os'], 'Darwin'))
22 | inputs:
23 | filePath: ./eng/common/generate-sbom-prep.ps1
24 | arguments: ${{parameters.manifestDirPath}}
25 |
26 | # Chmodding is a workaround for https://github.com/dotnet/arcade/issues/8461
27 | - script: |
28 | chmod +x ./eng/common/generate-sbom-prep.sh
29 | ./eng/common/generate-sbom-prep.sh ${{parameters.manifestDirPath}}
30 | displayName: Prep for SBOM generation in (Linux)
31 | condition: eq(variables['Agent.Os'], 'Linux')
32 | continueOnError: ${{ parameters.sbomContinueOnError }}
33 |
34 | - task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0
35 | displayName: 'Generate SBOM manifest'
36 | continueOnError: ${{ parameters.sbomContinueOnError }}
37 | inputs:
38 | PackageName: ${{ parameters.packageName }}
39 | BuildDropPath: ${{ parameters.buildDropPath }}
40 | PackageVersion: ${{ parameters.packageVersion }}
41 | ManifestDirPath: ${{ parameters.manifestDirPath }}/$(ARTIFACT_NAME)
42 | ${{ if ne(parameters.IgnoreDirectories, '') }}:
43 | AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}'
44 |
45 | - ${{ if eq(parameters.publishArtifacts, 'true')}}:
46 | - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
47 | parameters:
48 | is1ESPipeline: ${{ parameters.is1ESPipeline }}
49 | args:
50 | displayName: Publish SBOM manifest
51 | continueOnError: ${{parameters.sbomContinueOnError}}
52 | targetPath: '${{ parameters.manifestDirPath }}'
53 | artifactName: $(ARTIFACT_NAME)
54 |
55 |
--------------------------------------------------------------------------------
/eng/common/core-templates/steps/get-delegation-sas.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | - name: federatedServiceConnection
3 | type: string
4 | - name: outputVariableName
5 | type: string
6 | - name: expiryInHours
7 | type: number
8 | default: 1
9 | - name: base64Encode
10 | type: boolean
11 | default: false
12 | - name: storageAccount
13 | type: string
14 | - name: container
15 | type: string
16 | - name: permissions
17 | type: string
18 | default: 'rl'
19 | - name: is1ESPipeline
20 | type: boolean
21 | default: false
22 |
23 | steps:
24 | - task: AzureCLI@2
25 | displayName: 'Generate delegation SAS Token for ${{ parameters.storageAccount }}/${{ parameters.container }}'
26 | inputs:
27 | azureSubscription: ${{ parameters.federatedServiceConnection }}
28 | scriptType: 'pscore'
29 | scriptLocation: 'inlineScript'
30 | inlineScript: |
31 | # Calculate the expiration of the SAS token and convert to UTC
32 | $expiry = (Get-Date).AddHours(${{ parameters.expiryInHours }}).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
33 |
34 | $sas = az storage container generate-sas --account-name ${{ parameters.storageAccount }} --name ${{ parameters.container }} --permissions ${{ parameters.permissions }} --expiry $expiry --auth-mode login --as-user -o tsv
35 |
36 | if ($LASTEXITCODE -ne 0) {
37 | Write-Error "Failed to generate SAS token."
38 | exit 1
39 | }
40 |
41 | if ('${{ parameters.base64Encode }}' -eq 'true') {
42 | $sas = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($sas))
43 | }
44 |
45 | Write-Host "Setting '${{ parameters.outputVariableName }}' with the access token value"
46 | Write-Host "##vso[task.setvariable variable=${{ parameters.outputVariableName }};issecret=true]$sas"
47 |
--------------------------------------------------------------------------------
/eng/common/core-templates/steps/get-federated-access-token.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | - name: federatedServiceConnection
3 | type: string
4 | - name: outputVariableName
5 | type: string
6 | - name: is1ESPipeline
7 | type: boolean
8 | - name: stepName
9 | type: string
10 | default: 'getFederatedAccessToken'
11 | - name: condition
12 | type: string
13 | default: ''
14 | # Resource to get a token for. Common values include:
15 | # - '499b84ac-1321-427f-aa17-267ca6975798' for Azure DevOps
16 | # - 'https://storage.azure.com/' for storage
17 | # Defaults to Azure DevOps
18 | - name: resource
19 | type: string
20 | default: '499b84ac-1321-427f-aa17-267ca6975798'
21 | - name: isStepOutputVariable
22 | type: boolean
23 | default: false
24 |
25 | steps:
26 | - task: AzureCLI@2
27 | displayName: 'Getting federated access token for feeds'
28 | name: ${{ parameters.stepName }}
29 | ${{ if ne(parameters.condition, '') }}:
30 | condition: ${{ parameters.condition }}
31 | inputs:
32 | azureSubscription: ${{ parameters.federatedServiceConnection }}
33 | scriptType: 'pscore'
34 | scriptLocation: 'inlineScript'
35 | inlineScript: |
36 | $accessToken = az account get-access-token --query accessToken --resource ${{ parameters.resource }} --output tsv
37 | if ($LASTEXITCODE -ne 0) {
38 | Write-Error "Failed to get access token for resource '${{ parameters.resource }}'"
39 | exit 1
40 | }
41 | Write-Host "Setting '${{ parameters.outputVariableName }}' with the access token value"
42 | Write-Host "##vso[task.setvariable variable=${{ parameters.outputVariableName }};issecret=true;isOutput=${{ parameters.isStepOutputVariable }}]$accessToken"
--------------------------------------------------------------------------------
/eng/common/core-templates/steps/install-microbuild.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | # Enable install tasks for MicroBuild
3 | enableMicrobuild: false
4 | # Enable install tasks for MicroBuild on Mac and Linux
5 | # Will be ignored if 'enableMicrobuild' is false or 'Agent.Os' is 'Windows_NT'
6 | enableMicrobuildForMacAndLinux: false
7 | # Location of the MicroBuild output folder
8 | microBuildOutputFolder: '$(Build.SourcesDirectory)'
9 | continueOnError: false
10 |
11 | steps:
12 | - ${{ if eq(parameters.enableMicrobuild, 'true') }}:
13 | - ${{ if eq(parameters.enableMicrobuildForMacAndLinux, 'true') }}:
14 | # Needed to download the MicroBuild plugin nupkgs on Mac and Linux when nuget.exe is unavailable
15 | - task: UseDotNet@2
16 | displayName: Install .NET 8.0 SDK for MicroBuild Plugin
17 | inputs:
18 | packageType: sdk
19 | version: 8.0.x
20 | installationPath: ${{ parameters.microBuildOutputFolder }}/.dotnet
21 | workingDirectory: ${{ parameters.microBuildOutputFolder }}
22 | condition: and(succeeded(), ne(variables['Agent.Os'], 'Windows_NT'))
23 |
24 | - task: MicroBuildSigningPlugin@4
25 | displayName: Install MicroBuild plugin
26 | inputs:
27 | signType: $(_SignType)
28 | zipSources: false
29 | feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json
30 | ${{ if and(eq(parameters.enableMicrobuildForMacAndLinux, 'true'), ne(variables['Agent.Os'], 'Windows_NT')) }}:
31 | azureSubscription: 'MicroBuild Signing Task (DevDiv)'
32 | useEsrpCli: true
33 | env:
34 | TeamName: $(_TeamName)
35 | MicroBuildOutputFolderOverride: ${{ parameters.microBuildOutputFolder }}
36 | SYSTEM_ACCESSTOKEN: $(System.AccessToken)
37 | continueOnError: ${{ parameters.continueOnError }}
38 | condition: and(
39 | succeeded(),
40 | or(
41 | and(
42 | eq(variables['Agent.Os'], 'Windows_NT'),
43 | in(variables['_SignType'], 'real', 'test')
44 | ),
45 | and(
46 | ${{ eq(parameters.enableMicrobuildForMacAndLinux, true) }},
47 | ne(variables['Agent.Os'], 'Windows_NT'),
48 | eq(variables['_SignType'], 'real')
49 | )
50 | ))
51 |
--------------------------------------------------------------------------------
/eng/common/core-templates/steps/publish-build-artifacts.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | - name: is1ESPipeline
3 | type: boolean
4 | default: false
5 | - name: args
6 | type: object
7 | default: {}
8 | steps:
9 | - ${{ if ne(parameters.is1ESPipeline, true) }}:
10 | - template: /eng/common/templates/steps/publish-build-artifacts.yml
11 | parameters:
12 | is1ESPipeline: ${{ parameters.is1ESPipeline }}
13 | ${{ each parameter in parameters.args }}:
14 | ${{ parameter.key }}: ${{ parameter.value }}
15 | - ${{ else }}:
16 | - template: /eng/common/templates-official/steps/publish-build-artifacts.yml
17 | parameters:
18 | is1ESPipeline: ${{ parameters.is1ESPipeline }}
19 | ${{ each parameter in parameters.args }}:
20 | ${{ parameter.key }}: ${{ parameter.value }}
--------------------------------------------------------------------------------
/eng/common/core-templates/steps/publish-logs.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | StageLabel: ''
3 | JobLabel: ''
4 | CustomSensitiveDataList: ''
5 | # A default - in case value from eng/common/core-templates/post-build/common-variables.yml is not passed
6 | BinlogToolVersion: '1.0.11'
7 | is1ESPipeline: false
8 |
9 | steps:
10 | - task: Powershell@2
11 | displayName: Prepare Binlogs to Upload
12 | inputs:
13 | targetType: inline
14 | script: |
15 | New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/
16 | Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/
17 | continueOnError: true
18 | condition: always()
19 |
20 | - task: PowerShell@2
21 | displayName: Redact Logs
22 | inputs:
23 | filePath: $(Build.SourcesDirectory)/eng/common/post-build/redact-logs.ps1
24 | # For now this needs to have explicit list of all sensitive data. Taken from eng/publishing/v3/publish.yml
25 | # Sensitive data can as well be added to $(Build.SourcesDirectory)/eng/BinlogSecretsRedactionFile.txt'
26 | # If the file exists - sensitive data for redaction will be sourced from it
27 | # (single entry per line, lines starting with '# ' are considered comments and skipped)
28 | arguments: -InputPath '$(Build.SourcesDirectory)/PostBuildLogs'
29 | -BinlogToolVersion ${{parameters.BinlogToolVersion}}
30 | -TokensFilePath '$(Build.SourcesDirectory)/eng/BinlogSecretsRedactionFile.txt'
31 | '$(publishing-dnceng-devdiv-code-r-build-re)'
32 | '$(MaestroAccessToken)'
33 | '$(dn-bot-all-orgs-artifact-feeds-rw)'
34 | '$(akams-client-id)'
35 | '$(microsoft-symbol-server-pat)'
36 | '$(symweb-symbol-server-pat)'
37 | '$(dnceng-symbol-server-pat)'
38 | '$(dn-bot-all-orgs-build-rw-code-rw)'
39 | '$(System.AccessToken)'
40 | ${{parameters.CustomSensitiveDataList}}
41 | continueOnError: true
42 | condition: always()
43 |
44 | - task: CopyFiles@2
45 | displayName: Gather post build logs
46 | inputs:
47 | SourceFolder: '$(Build.SourcesDirectory)/PostBuildLogs'
48 | Contents: '**'
49 | TargetFolder: '$(Build.ArtifactStagingDirectory)/PostBuildLogs'
50 | condition: always()
51 |
52 | - template: /eng/common/core-templates/steps/publish-build-artifacts.yml
53 | parameters:
54 | is1ESPipeline: ${{ parameters.is1ESPipeline }}
55 | args:
56 | displayName: Publish Logs
57 | pathToPublish: '$(Build.ArtifactStagingDirectory)/PostBuildLogs'
58 | publishLocation: Container
59 | artifactName: PostBuildLogs
60 | continueOnError: true
61 | condition: always()
62 |
--------------------------------------------------------------------------------
/eng/common/core-templates/steps/publish-pipeline-artifacts.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | - name: is1ESPipeline
3 | type: boolean
4 | default: false
5 |
6 | - name: args
7 | type: object
8 | default: {}
9 |
10 | steps:
11 | - ${{ if ne(parameters.is1ESPipeline, true) }}:
12 | - template: /eng/common/templates/steps/publish-pipeline-artifacts.yml
13 | parameters:
14 | ${{ each parameter in parameters }}:
15 | ${{ parameter.key }}: ${{ parameter.value }}
16 | - ${{ else }}:
17 | - template: /eng/common/templates-official/steps/publish-pipeline-artifacts.yml
18 | parameters:
19 | ${{ each parameter in parameters }}:
20 | ${{ parameter.key }}: ${{ parameter.value }}
21 |
--------------------------------------------------------------------------------
/eng/common/core-templates/steps/retain-build.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | # Optional azure devops PAT with build execute permissions for the build's organization,
3 | # only needed if the build that should be retained ran on a different organization than
4 | # the pipeline where this template is executing from
5 | Token: ''
6 | # Optional BuildId to retain, defaults to the current running build
7 | BuildId: ''
8 | # Azure devops Organization URI for the build in the https://dev.azure.com/ format.
9 | # Defaults to the organization the current pipeline is running on
10 | AzdoOrgUri: '$(System.CollectionUri)'
11 | # Azure devops project for the build. Defaults to the project the current pipeline is running on
12 | AzdoProject: '$(System.TeamProject)'
13 |
14 | steps:
15 | - task: powershell@2
16 | inputs:
17 | targetType: 'filePath'
18 | filePath: eng/common/retain-build.ps1
19 | pwsh: true
20 | arguments: >
21 | -AzdoOrgUri: ${{parameters.AzdoOrgUri}}
22 | -AzdoProject ${{parameters.AzdoProject}}
23 | -Token ${{coalesce(parameters.Token, '$env:SYSTEM_ACCESSTOKEN') }}
24 | -BuildId ${{coalesce(parameters.BuildId, '$env:BUILD_ID')}}
25 | displayName: Enable permanent build retention
26 | env:
27 | SYSTEM_ACCESSTOKEN: $(System.AccessToken)
28 | BUILD_ID: $(Build.BuildId)
--------------------------------------------------------------------------------
/eng/common/core-templates/steps/source-build.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | # This template adds arcade-powered source-build to CI.
3 |
4 | # This is a 'steps' template, and is intended for advanced scenarios where the existing build
5 | # infra has a careful build methodology that must be followed. For example, a repo
6 | # (dotnet/runtime) might choose to clone the GitHub repo only once and store it as a pipeline
7 | # artifact for all subsequent jobs to use, to reduce dependence on a strong network connection to
8 | # GitHub. Using this steps template leaves room for that infra to be included.
9 |
10 | # Defines the platform on which to run the steps. See 'eng/common/core-templates/job/source-build.yml'
11 | # for details. The entire object is described in the 'job' template for simplicity, even though
12 | # the usage of the properties on this object is split between the 'job' and 'steps' templates.
13 | platform: {}
14 | is1ESPipeline: false
15 |
16 | steps:
17 | # Build. Keep it self-contained for simple reusability. (No source-build-specific job variables.)
18 | - script: |
19 | set -x
20 | df -h
21 |
22 | # If building on the internal project, the internal storage variable may be available (usually only if needed)
23 | # In that case, add variables to allow the download of internal runtimes if the specified versions are not found
24 | # in the default public locations.
25 | internalRuntimeDownloadArgs=
26 | if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then
27 | 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)'
28 | fi
29 |
30 | buildConfig=Release
31 | # Check if AzDO substitutes in a build config from a variable, and use it if so.
32 | if [ '$(_BuildConfig)' != '$''(_BuildConfig)' ]; then
33 | buildConfig='$(_BuildConfig)'
34 | fi
35 |
36 | targetRidArgs=
37 | if [ '${{ parameters.platform.targetRID }}' != '' ]; then
38 | targetRidArgs='/p:TargetRid=${{ parameters.platform.targetRID }}'
39 | fi
40 |
41 | baseRidArgs=
42 | if [ '${{ parameters.platform.baseRID }}' != '' ]; then
43 | baseRidArgs='/p:BaseRid=${{ parameters.platform.baseRID }}'
44 | fi
45 |
46 | portableBuildArgs=
47 | if [ '${{ parameters.platform.portableBuild }}' != '' ]; then
48 | portableBuildArgs='/p:PortableBuild=${{ parameters.platform.portableBuild }}'
49 | fi
50 |
51 | ${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \
52 | --configuration $buildConfig \
53 | --restore --build --pack -bl \
54 | --source-build \
55 | ${{ parameters.platform.buildArguments }} \
56 | $internalRuntimeDownloadArgs \
57 | $targetRidArgs \
58 | $baseRidArgs \
59 | $portableBuildArgs \
60 | displayName: Build
61 |
62 | - template: /eng/common/core-templates/steps/publish-pipeline-artifacts.yml
63 | parameters:
64 | is1ESPipeline: ${{ parameters.is1ESPipeline }}
65 | args:
66 | displayName: Publish BuildLogs
67 | targetPath: artifacts/log/${{ coalesce(variables._BuildConfig, 'Release') }}
68 | artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt)
69 | continueOnError: true
70 | condition: succeededOrFailed()
71 | sbomEnabled: false # we don't need SBOM for logs
72 |
--------------------------------------------------------------------------------
/eng/common/core-templates/steps/source-index-stage1-publish.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | sourceIndexUploadPackageVersion: 2.0.0-20250425.2
3 | sourceIndexProcessBinlogPackageVersion: 1.0.1-20250425.2
4 | sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json
5 | binlogPath: artifacts/log/Debug/Build.binlog
6 |
7 | steps:
8 | - task: UseDotNet@2
9 | displayName: "Source Index: Use .NET 8 SDK"
10 | inputs:
11 | packageType: sdk
12 | version: 8.0.x
13 | installationPath: $(Agent.TempDirectory)/dotnet
14 | workingDirectory: $(Agent.TempDirectory)
15 |
16 | - script: |
17 | $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version ${{parameters.sourceIndexProcessBinlogPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
18 | $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version ${{parameters.sourceIndexUploadPackageVersion}} --add-source ${{parameters.SourceIndexPackageSource}} --tool-path $(Agent.TempDirectory)/.source-index/tools
19 | displayName: "Source Index: Download netsourceindex Tools"
20 | # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk.
21 | workingDirectory: $(Agent.TempDirectory)
22 |
23 | - script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i ${{parameters.BinlogPath}} -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output
24 | displayName: "Source Index: Process Binlog into indexable sln"
25 |
26 | - ${{ if and(ne(parameters.runAsPublic, 'true'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
27 | - task: AzureCLI@2
28 | displayName: "Source Index: Upload Source Index stage1 artifacts to Azure"
29 | inputs:
30 | azureSubscription: 'SourceDotNet Stage1 Publish'
31 | addSpnToEnvironment: true
32 | scriptType: 'ps'
33 | scriptLocation: 'inlineScript'
34 | inlineScript: |
35 | $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) -s netsourceindexstage1 -b stage1
36 |
--------------------------------------------------------------------------------
/eng/common/core-templates/variables/pool-providers.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | is1ESPipeline: false
3 |
4 | variables:
5 | - ${{ if eq(parameters.is1ESPipeline, 'true') }}:
6 | - template: /eng/common/templates-official/variables/pool-providers.yml
7 | - ${{ else }}:
8 | - template: /eng/common/templates/variables/pool-providers.yml
--------------------------------------------------------------------------------
/eng/common/cross/arm/tizen/tizen.patch:
--------------------------------------------------------------------------------
1 | diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so
2 | --- a/usr/lib/libc.so 2016-12-30 23:00:08.284951863 +0900
3 | +++ b/usr/lib/libc.so 2016-12-30 23:00:32.140951815 +0900
4 | @@ -2,4 +2,4 @@
5 | Use the shared library, but some functions are only in
6 | the static library, so try that secondarily. */
7 | OUTPUT_FORMAT(elf32-littlearm)
8 | -GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux-armhf.so.3 ) )
9 | +GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux-armhf.so.3 ) )
10 |
--------------------------------------------------------------------------------
/eng/common/cross/arm64/tizen/tizen.patch:
--------------------------------------------------------------------------------
1 | diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so
2 | --- a/usr/lib64/libc.so 2016-12-30 23:00:08.284951863 +0900
3 | +++ b/usr/lib64/libc.so 2016-12-30 23:00:32.140951815 +0900
4 | @@ -2,4 +2,4 @@
5 | Use the shared library, but some functions are only in
6 | the static library, so try that secondarily. */
7 | OUTPUT_FORMAT(elf64-littleaarch64)
8 | -GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED ( /lib64/ld-linux-aarch64.so.1 ) )
9 | +GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux-aarch64.so.1 ) )
10 |
--------------------------------------------------------------------------------
/eng/common/cross/armel/tizen/tizen.patch:
--------------------------------------------------------------------------------
1 | diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so
2 | --- a/usr/lib/libc.so 2016-12-30 23:00:08.284951863 +0900
3 | +++ b/usr/lib/libc.so 2016-12-30 23:00:32.140951815 +0900
4 | @@ -2,4 +2,4 @@
5 | Use the shared library, but some functions are only in
6 | the static library, so try that secondarily. */
7 | OUTPUT_FORMAT(elf32-littlearm)
8 | -GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a AS_NEEDED ( /lib/ld-linux.so.3 ) )
9 | +GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux.so.3 ) )
10 |
--------------------------------------------------------------------------------
/eng/common/cross/riscv64/tizen/tizen.patch:
--------------------------------------------------------------------------------
1 | diff -u -r a/usr/lib/libc.so b/usr/lib/libc.so
2 | --- a/usr/lib64/libc.so 2016-12-30 23:00:08.284951863 +0900
3 | +++ b/usr/lib64/libc.so 2016-12-30 23:00:32.140951815 +0900
4 | @@ -2,4 +2,4 @@
5 | Use the shared library, but some functions are only in
6 | the static library, so try that secondarily. */
7 | OUTPUT_FORMAT(elf64-littleriscv)
8 | -GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a AS_NEEDED ( /lib64/ld-linux-riscv64-lp64d.so.1 ) )
9 | +GROUP ( libc.so.6 libc_nonshared.a AS_NEEDED ( ld-linux-riscv64-lp64d.so.1 ) )
10 |
--------------------------------------------------------------------------------
/eng/common/cross/tizen-build-rootfs.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -e
3 |
4 | ARCH=$1
5 | LINK_ARCH=$ARCH
6 |
7 | case "$ARCH" in
8 | arm)
9 | TIZEN_ARCH="armv7hl"
10 | ;;
11 | armel)
12 | TIZEN_ARCH="armv7l"
13 | LINK_ARCH="arm"
14 | ;;
15 | arm64)
16 | TIZEN_ARCH="aarch64"
17 | ;;
18 | x86)
19 | TIZEN_ARCH="i686"
20 | ;;
21 | x64)
22 | TIZEN_ARCH="x86_64"
23 | LINK_ARCH="x86"
24 | ;;
25 | riscv64)
26 | TIZEN_ARCH="riscv64"
27 | LINK_ARCH="riscv"
28 | ;;
29 | *)
30 | echo "Unsupported architecture for tizen: $ARCH"
31 | exit 1
32 | esac
33 |
34 | __CrossDir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
35 | __TIZEN_CROSSDIR="$__CrossDir/${ARCH}/tizen"
36 |
37 | if [[ -z "$ROOTFS_DIR" ]]; then
38 | echo "ROOTFS_DIR is not defined."
39 | exit 1;
40 | fi
41 |
42 | TIZEN_TMP_DIR=$ROOTFS_DIR/tizen_tmp
43 | mkdir -p $TIZEN_TMP_DIR
44 |
45 | # Download files
46 | echo ">>Start downloading files"
47 | VERBOSE=1 $__CrossDir/tizen-fetch.sh $TIZEN_TMP_DIR $TIZEN_ARCH
48 | echo "<>Start constructing Tizen rootfs"
51 | TIZEN_RPM_FILES=`ls $TIZEN_TMP_DIR/*.rpm`
52 | cd $ROOTFS_DIR
53 | for f in $TIZEN_RPM_FILES; do
54 | rpm2cpio $f | cpio -idm --quiet
55 | done
56 | echo "<>Start configuring Tizen rootfs"
63 | ln -sfn asm-${LINK_ARCH} ./usr/include/asm
64 | patch -p1 < $__TIZEN_CROSSDIR/tizen.patch
65 | if [[ "$TIZEN_ARCH" == "riscv64" ]]; then
66 | echo "Fixing broken symlinks in $PWD"
67 | rm ./usr/lib64/libresolv.so
68 | ln -s ../../lib64/libresolv.so.2 ./usr/lib64/libresolv.so
69 | rm ./usr/lib64/libpthread.so
70 | ln -s ../../lib64/libpthread.so.0 ./usr/lib64/libpthread.so
71 | rm ./usr/lib64/libdl.so
72 | ln -s ../../lib64/libdl.so.2 ./usr/lib64/libdl.so
73 | rm ./usr/lib64/libutil.so
74 | ln -s ../../lib64/libutil.so.1 ./usr/lib64/libutil.so
75 | rm ./usr/lib64/libm.so
76 | ln -s ../../lib64/libm.so.6 ./usr/lib64/libm.so
77 | rm ./usr/lib64/librt.so
78 | ln -s ../../lib64/librt.so.1 ./usr/lib64/librt.so
79 | rm ./lib/ld-linux-riscv64-lp64d.so.1
80 | ln -s ../lib64/ld-linux-riscv64-lp64d.so.1 ./lib/ld-linux-riscv64-lp64d.so.1
81 | fi
82 | echo "< 0 ]]; do
9 | opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")"
10 | case "$opt" in
11 | --darcversion)
12 | darcVersion=$2
13 | shift
14 | ;;
15 | --versionendpoint)
16 | versionEndpoint=$2
17 | shift
18 | ;;
19 | --verbosity)
20 | verbosity=$2
21 | shift
22 | ;;
23 | --toolpath)
24 | toolpath=$2
25 | shift
26 | ;;
27 | *)
28 | echo "Invalid argument: $1"
29 | usage
30 | exit 1
31 | ;;
32 | esac
33 |
34 | shift
35 | done
36 |
37 | # resolve $source until the file is no longer a symlink
38 | while [[ -h "$source" ]]; do
39 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
40 | source="$(readlink "$source")"
41 | # if $source was a relative symlink, we need to resolve it relative to the path where the
42 | # symlink file was located
43 | [[ $source != /* ]] && source="$scriptroot/$source"
44 | done
45 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
46 |
47 | . "$scriptroot/tools.sh"
48 |
49 | if [ -z "$darcVersion" ]; then
50 | darcVersion=$(curl -X GET "$versionEndpoint" -H "accept: text/plain")
51 | fi
52 |
53 | function InstallDarcCli {
54 | local darc_cli_package_name="microsoft.dotnet.darc"
55 |
56 | InitializeDotNetCli true
57 | local dotnet_root=$_InitializeDotNetCli
58 |
59 | if [ -z "$toolpath" ]; then
60 | local tool_list=$($dotnet_root/dotnet tool list -g)
61 | if [[ $tool_list = *$darc_cli_package_name* ]]; then
62 | echo $($dotnet_root/dotnet tool uninstall $darc_cli_package_name -g)
63 | fi
64 | else
65 | local tool_list=$($dotnet_root/dotnet tool list --tool-path "$toolpath")
66 | if [[ $tool_list = *$darc_cli_package_name* ]]; then
67 | echo $($dotnet_root/dotnet tool uninstall $darc_cli_package_name --tool-path "$toolpath")
68 | fi
69 | fi
70 |
71 | local arcadeServicesSource="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json"
72 |
73 | echo "Installing Darc CLI version $darcVersion..."
74 | echo "You may need to restart your command shell if this is the first dotnet tool you have installed."
75 | if [ -z "$toolpath" ]; then
76 | echo $($dotnet_root/dotnet tool install $darc_cli_package_name --version $darcVersion --add-source "$arcadeServicesSource" -v $verbosity -g)
77 | else
78 | echo $($dotnet_root/dotnet tool install $darc_cli_package_name --version $darcVersion --add-source "$arcadeServicesSource" -v $verbosity --tool-path "$toolpath")
79 | fi
80 | }
81 |
82 | InstallDarcCli
83 |
--------------------------------------------------------------------------------
/eng/common/dotnet-install.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 | powershell -ExecutionPolicy ByPass -NoProfile -command "& """%~dp0dotnet-install.ps1""" %*"
--------------------------------------------------------------------------------
/eng/common/dotnet-install.ps1:
--------------------------------------------------------------------------------
1 | [CmdletBinding(PositionalBinding=$false)]
2 | Param(
3 | [string] $verbosity = 'minimal',
4 | [string] $architecture = '',
5 | [string] $version = 'Latest',
6 | [string] $runtime = 'dotnet',
7 | [string] $RuntimeSourceFeed = '',
8 | [string] $RuntimeSourceFeedKey = ''
9 | )
10 |
11 | . $PSScriptRoot\tools.ps1
12 |
13 | $dotnetRoot = Join-Path $RepoRoot '.dotnet'
14 |
15 | $installdir = $dotnetRoot
16 | try {
17 | if ($architecture -and $architecture.Trim() -eq 'x86') {
18 | $installdir = Join-Path $installdir 'x86'
19 | }
20 | InstallDotNet $installdir $version $architecture $runtime $true -RuntimeSourceFeed $RuntimeSourceFeed -RuntimeSourceFeedKey $RuntimeSourceFeedKey
21 | }
22 | catch {
23 | Write-Host $_.ScriptStackTrace
24 | Write-PipelineTelemetryError -Category 'InitializeToolset' -Message $_
25 | ExitWithExitCode 1
26 | }
27 |
28 | ExitWithExitCode 0
29 |
--------------------------------------------------------------------------------
/eng/common/dotnet-install.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source="${BASH_SOURCE[0]}"
4 | # resolve $source until the file is no longer a symlink
5 | while [[ -h "$source" ]]; do
6 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
7 | source="$(readlink "$source")"
8 | # if $source was a relative symlink, we need to resolve it relative to the path where the
9 | # symlink file was located
10 | [[ $source != /* ]] && source="$scriptroot/$source"
11 | done
12 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
13 |
14 | . "$scriptroot/tools.sh"
15 |
16 | version='Latest'
17 | architecture=''
18 | runtime='dotnet'
19 | runtimeSourceFeed=''
20 | runtimeSourceFeedKey=''
21 | while [[ $# > 0 ]]; do
22 | opt="$(echo "$1" | tr "[:upper:]" "[:lower:]")"
23 | case "$opt" in
24 | -version|-v)
25 | shift
26 | version="$1"
27 | ;;
28 | -architecture|-a)
29 | shift
30 | architecture="$1"
31 | ;;
32 | -runtime|-r)
33 | shift
34 | runtime="$1"
35 | ;;
36 | -runtimesourcefeed)
37 | shift
38 | runtimeSourceFeed="$1"
39 | ;;
40 | -runtimesourcefeedkey)
41 | shift
42 | runtimeSourceFeedKey="$1"
43 | ;;
44 | *)
45 | Write-PipelineTelemetryError -Category 'Build' -Message "Invalid argument: $1"
46 | exit 1
47 | ;;
48 | esac
49 | shift
50 | done
51 |
52 | # Use uname to determine what the CPU is, see https://en.wikipedia.org/wiki/Uname#Examples
53 | cpuname=$(uname -m)
54 | case $cpuname in
55 | arm64|aarch64)
56 | buildarch=arm64
57 | if [ "$(getconf LONG_BIT)" -lt 64 ]; then
58 | # This is 32-bit OS running on 64-bit CPU (for example Raspberry Pi OS)
59 | buildarch=arm
60 | fi
61 | ;;
62 | loongarch64)
63 | buildarch=loongarch64
64 | ;;
65 | amd64|x86_64)
66 | buildarch=x64
67 | ;;
68 | armv*l)
69 | buildarch=arm
70 | ;;
71 | i[3-6]86)
72 | buildarch=x86
73 | ;;
74 | riscv64)
75 | buildarch=riscv64
76 | ;;
77 | *)
78 | echo "Unknown CPU $cpuname detected, treating it as x64"
79 | buildarch=x64
80 | ;;
81 | esac
82 |
83 | dotnetRoot="${repo_root}.dotnet"
84 | if [[ $architecture != "" ]] && [[ $architecture != $buildarch ]]; then
85 | dotnetRoot="$dotnetRoot/$architecture"
86 | fi
87 |
88 | InstallDotNet "$dotnetRoot" $version "$architecture" $runtime true $runtimeSourceFeed $runtimeSourceFeedKey || {
89 | local exit_code=$?
90 | Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "dotnet-install.sh failed (exit code '$exit_code')." >&2
91 | ExitWithExitCode $exit_code
92 | }
93 |
94 | ExitWithExitCode 0
95 |
--------------------------------------------------------------------------------
/eng/common/enable-cross-org-publishing.ps1:
--------------------------------------------------------------------------------
1 | param(
2 | [string] $token
3 | )
4 |
5 |
6 | . $PSScriptRoot\pipeline-logging-functions.ps1
7 |
8 | # Write-PipelineSetVariable will no-op if a variable named $ci is not defined
9 | # Since this script is only ever called in AzDO builds, just universally set it
10 | $ci = $true
11 |
12 | Write-PipelineSetVariable -Name 'VSS_NUGET_ACCESSTOKEN' -Value $token -IsMultiJobVariable $false
13 | Write-PipelineSetVariable -Name 'VSS_NUGET_URI_PREFIXES' -Value 'https://dnceng.pkgs.visualstudio.com/;https://pkgs.dev.azure.com/dnceng/;https://devdiv.pkgs.visualstudio.com/;https://pkgs.dev.azure.com/devdiv/' -IsMultiJobVariable $false
14 |
--------------------------------------------------------------------------------
/eng/common/generate-sbom-prep.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | [Parameter(Mandatory=$true)][string] $ManifestDirPath # Manifest directory where sbom will be placed
3 | )
4 |
5 | . $PSScriptRoot\pipeline-logging-functions.ps1
6 |
7 | # Normally - we'd listen to the manifest path given, but 1ES templates will overwrite if this level gets uploaded directly
8 | # with their own overwriting ours. So we create it as a sub directory of the requested manifest path.
9 | $ArtifactName = "${env:SYSTEM_STAGENAME}_${env:AGENT_JOBNAME}_SBOM"
10 | $SafeArtifactName = $ArtifactName -replace '["/:<>\\|?@*"() ]', '_'
11 | $SbomGenerationDir = Join-Path $ManifestDirPath $SafeArtifactName
12 |
13 | Write-Host "Artifact name before : $ArtifactName"
14 | Write-Host "Artifact name after : $SafeArtifactName"
15 |
16 | Write-Host "Creating dir $ManifestDirPath"
17 |
18 | # create directory for sbom manifest to be placed
19 | if (!(Test-Path -path $SbomGenerationDir))
20 | {
21 | New-Item -ItemType Directory -path $SbomGenerationDir
22 | Write-Host "Successfully created directory $SbomGenerationDir"
23 | }
24 | else{
25 | Write-PipelineTelemetryError -category 'Build' "Unable to create sbom folder."
26 | }
27 |
28 | Write-Host "Updating artifact name"
29 | Write-Host "##vso[task.setvariable variable=ARTIFACT_NAME]$SafeArtifactName"
30 |
--------------------------------------------------------------------------------
/eng/common/generate-sbom-prep.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source="${BASH_SOURCE[0]}"
4 |
5 | # resolve $SOURCE until the file is no longer a symlink
6 | while [[ -h $source ]]; do
7 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
8 | source="$(readlink "$source")"
9 |
10 | # if $source was a relative symlink, we need to resolve it relative to the path where the
11 | # symlink file was located
12 | [[ $source != /* ]] && source="$scriptroot/$source"
13 | done
14 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
15 | . $scriptroot/pipeline-logging-functions.sh
16 |
17 |
18 | # replace all special characters with _, some builds use special characters like : in Agent.Jobname, that is not a permissible name while uploading artifacts.
19 | artifact_name=$SYSTEM_STAGENAME"_"$AGENT_JOBNAME"_SBOM"
20 | safe_artifact_name="${artifact_name//["/:<>\\|?@*$" ]/_}"
21 | manifest_dir=$1
22 |
23 | # Normally - we'd listen to the manifest path given, but 1ES templates will overwrite if this level gets uploaded directly
24 | # with their own overwriting ours. So we create it as a sub directory of the requested manifest path.
25 | sbom_generation_dir="$manifest_dir/$safe_artifact_name"
26 |
27 | if [ ! -d "$sbom_generation_dir" ] ; then
28 | mkdir -p "$sbom_generation_dir"
29 | echo "Sbom directory created." $sbom_generation_dir
30 | else
31 | Write-PipelineTelemetryError -category 'Build' "Unable to create sbom folder."
32 | fi
33 |
34 | echo "Artifact name before : "$artifact_name
35 | echo "Artifact name after : "$safe_artifact_name
36 | export ARTIFACT_NAME=$safe_artifact_name
37 | echo "##vso[task.setvariable variable=ARTIFACT_NAME]$safe_artifact_name"
38 |
39 | exit 0
40 |
--------------------------------------------------------------------------------
/eng/common/helixpublish.proj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | msbuild
6 |
7 |
8 |
9 |
10 | %(Identity)
11 |
12 |
13 |
14 |
15 |
16 | $(WorkItemDirectory)
17 | $(WorkItemCommand)
18 | $(WorkItemTimeout)
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/eng/common/init-tools-native.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 | powershell -NoProfile -NoLogo -ExecutionPolicy ByPass -command "& """%~dp0init-tools-native.ps1""" %*"
3 | exit /b %ErrorLevel%
--------------------------------------------------------------------------------
/eng/common/internal/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | false
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/eng/common/internal/NuGet.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/eng/common/internal/Tools.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net472
6 | false
7 | false
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/eng/common/loc/P22DotNetHtmlLocalization.lss:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
22 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/eng/common/msbuild.ps1:
--------------------------------------------------------------------------------
1 | [CmdletBinding(PositionalBinding=$false)]
2 | Param(
3 | [string] $verbosity = 'minimal',
4 | [bool] $warnAsError = $true,
5 | [bool] $nodeReuse = $true,
6 | [switch] $ci,
7 | [switch] $prepareMachine,
8 | [switch] $excludePrereleaseVS,
9 | [string] $msbuildEngine = $null,
10 | [Parameter(ValueFromRemainingArguments=$true)][String[]]$extraArgs
11 | )
12 |
13 | . $PSScriptRoot\tools.ps1
14 |
15 | try {
16 | if ($ci) {
17 | $nodeReuse = $false
18 | }
19 |
20 | MSBuild @extraArgs
21 | }
22 | catch {
23 | Write-Host $_.ScriptStackTrace
24 | Write-PipelineTelemetryError -Category 'Build' -Message $_
25 | ExitWithExitCode 1
26 | }
27 |
28 | ExitWithExitCode 0
--------------------------------------------------------------------------------
/eng/common/msbuild.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source="${BASH_SOURCE[0]}"
4 |
5 | # resolve $source until the file is no longer a symlink
6 | while [[ -h "$source" ]]; do
7 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
8 | source="$(readlink "$source")"
9 | # if $source was a relative symlink, we need to resolve it relative to the path where the
10 | # symlink file was located
11 | [[ $source != /* ]] && source="$scriptroot/$source"
12 | done
13 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
14 |
15 | verbosity='minimal'
16 | warn_as_error=true
17 | node_reuse=true
18 | prepare_machine=false
19 | extra_args=''
20 |
21 | while (($# > 0)); do
22 | lowerI="$(echo $1 | tr "[:upper:]" "[:lower:]")"
23 | case $lowerI in
24 | --verbosity)
25 | verbosity=$2
26 | shift 2
27 | ;;
28 | --warnaserror)
29 | warn_as_error=$2
30 | shift 2
31 | ;;
32 | --nodereuse)
33 | node_reuse=$2
34 | shift 2
35 | ;;
36 | --ci)
37 | ci=true
38 | shift 1
39 | ;;
40 | --preparemachine)
41 | prepare_machine=true
42 | shift 1
43 | ;;
44 | *)
45 | extra_args="$extra_args $1"
46 | shift 1
47 | ;;
48 | esac
49 | done
50 |
51 | . "$scriptroot/tools.sh"
52 |
53 | if [[ "$ci" == true ]]; then
54 | node_reuse=false
55 | fi
56 |
57 | MSBuild $extra_args
58 | ExitWithExitCode 0
59 |
--------------------------------------------------------------------------------
/eng/common/native/init-os-and-arch.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Use uname to determine what the OS is.
4 | OSName=$(uname -s | tr '[:upper:]' '[:lower:]')
5 |
6 | if command -v getprop && getprop ro.product.system.model 2>&1 | grep -qi android; then
7 | OSName="android"
8 | fi
9 |
10 | case "$OSName" in
11 | freebsd|linux|netbsd|openbsd|sunos|android|haiku)
12 | os="$OSName" ;;
13 | darwin)
14 | os=osx ;;
15 | *)
16 | echo "Unsupported OS $OSName detected!"
17 | exit 1 ;;
18 | esac
19 |
20 | # On Solaris, `uname -m` is discouraged, see https://docs.oracle.com/cd/E36784_01/html/E36870/uname-1.html
21 | # and `uname -p` returns processor type (e.g. i386 on amd64).
22 | # The appropriate tool to determine CPU is isainfo(1) https://docs.oracle.com/cd/E36784_01/html/E36870/isainfo-1.html.
23 | if [ "$os" = "sunos" ]; then
24 | if uname -o 2>&1 | grep -q illumos; then
25 | os="illumos"
26 | else
27 | os="solaris"
28 | fi
29 | CPUName=$(isainfo -n)
30 | else
31 | # For the rest of the operating systems, use uname(1) to determine what the CPU is.
32 | CPUName=$(uname -m)
33 | fi
34 |
35 | case "$CPUName" in
36 | arm64|aarch64)
37 | arch=arm64
38 | if [ "$(getconf LONG_BIT)" -lt 64 ]; then
39 | # This is 32-bit OS running on 64-bit CPU (for example Raspberry Pi OS)
40 | arch=arm
41 | fi
42 | ;;
43 |
44 | loongarch64)
45 | arch=loongarch64
46 | ;;
47 |
48 | riscv64)
49 | arch=riscv64
50 | ;;
51 |
52 | amd64|x86_64)
53 | arch=x64
54 | ;;
55 |
56 | armv7l|armv8l)
57 | # shellcheck disable=SC1091
58 | if (NAME=""; . /etc/os-release; test "$NAME" = "Tizen"); then
59 | arch=armel
60 | else
61 | arch=arm
62 | fi
63 | ;;
64 |
65 | armv6l)
66 | arch=armv6
67 | ;;
68 |
69 | i[3-6]86)
70 | echo "Unsupported CPU $CPUName detected, build might not succeed!"
71 | arch=x86
72 | ;;
73 |
74 | s390x)
75 | arch=s390x
76 | ;;
77 |
78 | ppc64le)
79 | arch=ppc64le
80 | ;;
81 | *)
82 | echo "Unknown CPU $CPUName detected!"
83 | exit 1
84 | ;;
85 | esac
86 |
--------------------------------------------------------------------------------
/eng/common/native/install-cmake-test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source="${BASH_SOURCE[0]}"
4 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
5 |
6 | . $scriptroot/common-library.sh
7 |
8 | base_uri=
9 | install_path=
10 | version=
11 | clean=false
12 | force=false
13 | download_retries=5
14 | retry_wait_time_seconds=30
15 |
16 | while (($# > 0)); do
17 | lowerI="$(echo $1 | tr "[:upper:]" "[:lower:]")"
18 | case $lowerI in
19 | --baseuri)
20 | base_uri=$2
21 | shift 2
22 | ;;
23 | --installpath)
24 | install_path=$2
25 | shift 2
26 | ;;
27 | --version)
28 | version=$2
29 | shift 2
30 | ;;
31 | --clean)
32 | clean=true
33 | shift 1
34 | ;;
35 | --force)
36 | force=true
37 | shift 1
38 | ;;
39 | --downloadretries)
40 | download_retries=$2
41 | shift 2
42 | ;;
43 | --retrywaittimeseconds)
44 | retry_wait_time_seconds=$2
45 | shift 2
46 | ;;
47 | --help)
48 | echo "Common settings:"
49 | echo " --baseuri Base file directory or Url wrom which to acquire tool archives"
50 | echo " --installpath Base directory to install native tool to"
51 | echo " --clean Don't install the tool, just clean up the current install of the tool"
52 | echo " --force Force install of tools even if they previously exist"
53 | echo " --help Print help and exit"
54 | echo ""
55 | echo "Advanced settings:"
56 | echo " --downloadretries Total number of retry attempts"
57 | echo " --retrywaittimeseconds Wait time between retry attempts in seconds"
58 | echo ""
59 | exit 0
60 | ;;
61 | esac
62 | done
63 |
64 | tool_name="cmake-test"
65 | tool_os=$(GetCurrentOS)
66 | tool_folder="$(echo $tool_os | tr "[:upper:]" "[:lower:]")"
67 | tool_arch="x86_64"
68 | tool_name_moniker="$tool_name-$version-$tool_os-$tool_arch"
69 | tool_install_directory="$install_path/$tool_name/$version"
70 | tool_file_path="$tool_install_directory/$tool_name_moniker/bin/$tool_name"
71 | shim_path="$install_path/$tool_name.sh"
72 | uri="${base_uri}/$tool_folder/$tool_name/$tool_name_moniker.tar.gz"
73 |
74 | # Clean up tool and installers
75 | if [[ $clean = true ]]; then
76 | echo "Cleaning $tool_install_directory"
77 | if [[ -d $tool_install_directory ]]; then
78 | rm -rf $tool_install_directory
79 | fi
80 |
81 | echo "Cleaning $shim_path"
82 | if [[ -f $shim_path ]]; then
83 | rm -rf $shim_path
84 | fi
85 |
86 | tool_temp_path=$(GetTempPathFileName $uri)
87 | echo "Cleaning $tool_temp_path"
88 | if [[ -f $tool_temp_path ]]; then
89 | rm -rf $tool_temp_path
90 | fi
91 |
92 | exit 0
93 | fi
94 |
95 | # Install tool
96 | if [[ -f $tool_file_path ]] && [[ $force = false ]]; then
97 | echo "$tool_name ($version) already exists, skipping install"
98 | exit 0
99 | fi
100 |
101 | DownloadAndExtract $uri $tool_install_directory $force $download_retries $retry_wait_time_seconds
102 |
103 | if [[ $? != 0 ]]; then
104 | Write-PipelineTelemetryError -category 'NativeToolsBootstrap' 'Installation failed'
105 | exit 1
106 | fi
107 |
108 | # Generate Shim
109 | # Always rewrite shims so that we are referencing the expected version
110 | NewScriptShim $shim_path $tool_file_path true
111 |
112 | if [[ $? != 0 ]]; then
113 | Write-PipelineTelemetryError -category 'NativeToolsBootstrap' 'Shim generation failed'
114 | exit 1
115 | fi
116 |
117 | exit 0
118 |
--------------------------------------------------------------------------------
/eng/common/native/install-cmake.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | source="${BASH_SOURCE[0]}"
4 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
5 |
6 | . $scriptroot/common-library.sh
7 |
8 | base_uri=
9 | install_path=
10 | version=
11 | clean=false
12 | force=false
13 | download_retries=5
14 | retry_wait_time_seconds=30
15 |
16 | while (($# > 0)); do
17 | lowerI="$(echo $1 | tr "[:upper:]" "[:lower:]")"
18 | case $lowerI in
19 | --baseuri)
20 | base_uri=$2
21 | shift 2
22 | ;;
23 | --installpath)
24 | install_path=$2
25 | shift 2
26 | ;;
27 | --version)
28 | version=$2
29 | shift 2
30 | ;;
31 | --clean)
32 | clean=true
33 | shift 1
34 | ;;
35 | --force)
36 | force=true
37 | shift 1
38 | ;;
39 | --downloadretries)
40 | download_retries=$2
41 | shift 2
42 | ;;
43 | --retrywaittimeseconds)
44 | retry_wait_time_seconds=$2
45 | shift 2
46 | ;;
47 | --help)
48 | echo "Common settings:"
49 | echo " --baseuri Base file directory or Url wrom which to acquire tool archives"
50 | echo " --installpath Base directory to install native tool to"
51 | echo " --clean Don't install the tool, just clean up the current install of the tool"
52 | echo " --force Force install of tools even if they previously exist"
53 | echo " --help Print help and exit"
54 | echo ""
55 | echo "Advanced settings:"
56 | echo " --downloadretries Total number of retry attempts"
57 | echo " --retrywaittimeseconds Wait time between retry attempts in seconds"
58 | echo ""
59 | exit 0
60 | ;;
61 | esac
62 | done
63 |
64 | tool_name="cmake"
65 | tool_os=$(GetCurrentOS)
66 | tool_folder="$(echo $tool_os | tr "[:upper:]" "[:lower:]")"
67 | tool_arch="x86_64"
68 | tool_name_moniker="$tool_name-$version-$tool_os-$tool_arch"
69 | tool_install_directory="$install_path/$tool_name/$version"
70 | tool_file_path="$tool_install_directory/$tool_name_moniker/bin/$tool_name"
71 | shim_path="$install_path/$tool_name.sh"
72 | uri="${base_uri}/$tool_folder/$tool_name/$tool_name_moniker.tar.gz"
73 |
74 | # Clean up tool and installers
75 | if [[ $clean = true ]]; then
76 | echo "Cleaning $tool_install_directory"
77 | if [[ -d $tool_install_directory ]]; then
78 | rm -rf $tool_install_directory
79 | fi
80 |
81 | echo "Cleaning $shim_path"
82 | if [[ -f $shim_path ]]; then
83 | rm -rf $shim_path
84 | fi
85 |
86 | tool_temp_path=$(GetTempPathFileName $uri)
87 | echo "Cleaning $tool_temp_path"
88 | if [[ -f $tool_temp_path ]]; then
89 | rm -rf $tool_temp_path
90 | fi
91 |
92 | exit 0
93 | fi
94 |
95 | # Install tool
96 | if [[ -f $tool_file_path ]] && [[ $force = false ]]; then
97 | echo "$tool_name ($version) already exists, skipping install"
98 | exit 0
99 | fi
100 |
101 | DownloadAndExtract $uri $tool_install_directory $force $download_retries $retry_wait_time_seconds
102 |
103 | if [[ $? != 0 ]]; then
104 | Write-PipelineTelemetryError -category 'NativeToolsBootstrap' 'Installation failed'
105 | exit 1
106 | fi
107 |
108 | # Generate Shim
109 | # Always rewrite shims so that we are referencing the expected version
110 | NewScriptShim $shim_path $tool_file_path true
111 |
112 | if [[ $? != 0 ]]; then
113 | Write-PipelineTelemetryError -category 'NativeToolsBootstrap' 'Shim generation failed'
114 | exit 1
115 | fi
116 |
117 | exit 0
118 |
--------------------------------------------------------------------------------
/eng/common/native/install-dependencies.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -e
4 |
5 | # This is a simple script primarily used for CI to install necessary dependencies
6 | #
7 | # Usage:
8 | #
9 | # ./install-dependencies.sh
10 |
11 | os="$(echo "$1" | tr "[:upper:]" "[:lower:]")"
12 |
13 | if [ -z "$os" ]; then
14 | . "$(dirname "$0")"/init-os-and-arch.sh
15 | fi
16 |
17 | case "$os" in
18 | linux)
19 | if [ -e /etc/os-release ]; then
20 | . /etc/os-release
21 | fi
22 |
23 | if [ "$ID" = "debian" ] || [ "$ID_LIKE" = "debian" ]; then
24 | apt update
25 |
26 | apt install -y build-essential gettext locales cmake llvm clang lld lldb liblldb-dev libunwind8-dev libicu-dev liblttng-ust-dev \
27 | libssl-dev libkrb5-dev pigz cpio
28 |
29 | localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
30 | elif [ "$ID" = "fedora" ] || [ "$ID" = "rhel" ] || [ "$ID" = "azurelinux" ]; then
31 | pkg_mgr="$(command -v tdnf 2>/dev/null || command -v dnf)"
32 | $pkg_mgr install -y cmake llvm lld lldb clang python curl libicu-devel openssl-devel krb5-devel lttng-ust-devel pigz cpio
33 | elif [ "$ID" = "alpine" ]; then
34 | apk add build-base cmake bash curl clang llvm-dev lld lldb krb5-dev lttng-ust-dev icu-dev openssl-dev pigz cpio
35 | else
36 | echo "Unsupported distro. distro: $ID"
37 | exit 1
38 | fi
39 | ;;
40 |
41 | osx|maccatalyst|ios|iossimulator|tvos|tvossimulator)
42 | echo "Installed xcode version: $(xcode-select -p)"
43 |
44 | export HOMEBREW_NO_INSTALL_CLEANUP=1
45 | export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1
46 | # Skip brew update for now, see https://github.com/actions/setup-python/issues/577
47 | # brew update --preinstall
48 | brew bundle --no-upgrade --file=- < Name of Arcade task (name of a project in SdkTasks directory of the Arcade SDK package)"
6 | echo " --restore Restore dependencies"
7 | echo " --verbosity Msbuild verbosity: q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]"
8 | echo " --help Print help and exit"
9 | echo ""
10 |
11 | echo "Advanced settings:"
12 | echo " --excludeCIBinarylog Don't output binary log (short: -nobl)"
13 | echo ""
14 | echo "Command line arguments not listed above are passed thru to msbuild."
15 | }
16 |
17 | source="${BASH_SOURCE[0]}"
18 |
19 | # resolve $source until the file is no longer a symlink
20 | while [[ -h "$source" ]]; do
21 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
22 | source="$(readlink "$source")"
23 | # if $source was a relative symlink, we need to resolve it relative to the path where the
24 | # symlink file was located
25 | [[ $source != /* ]] && source="$scriptroot/$source"
26 | done
27 | scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
28 |
29 | Build() {
30 | local target=$1
31 | local log_suffix=""
32 | [[ "$target" != "Execute" ]] && log_suffix=".$target"
33 | local log="$log_dir/$task$log_suffix.binlog"
34 | local binaryLogArg=""
35 | [[ $binary_log == true ]] && binaryLogArg="/bl:$log"
36 | local output_path="$toolset_dir/$task/"
37 |
38 | MSBuild "$taskProject" \
39 | $binaryLogArg \
40 | /t:"$target" \
41 | /p:Configuration="$configuration" \
42 | /p:RepoRoot="$repo_root" \
43 | /p:BaseIntermediateOutputPath="$output_path" \
44 | /v:"$verbosity" \
45 | $properties
46 | }
47 |
48 | binary_log=true
49 | configuration="Debug"
50 | verbosity="minimal"
51 | exclude_ci_binary_log=false
52 | restore=false
53 | help=false
54 | properties=''
55 |
56 | while (($# > 0)); do
57 | lowerI="$(echo $1 | tr "[:upper:]" "[:lower:]")"
58 | case $lowerI in
59 | --task)
60 | task=$2
61 | shift 2
62 | ;;
63 | --restore)
64 | restore=true
65 | shift 1
66 | ;;
67 | --verbosity)
68 | verbosity=$2
69 | shift 2
70 | ;;
71 | --excludecibinarylog|--nobl)
72 | binary_log=false
73 | exclude_ci_binary_log=true
74 | shift 1
75 | ;;
76 | --help)
77 | help=true
78 | shift 1
79 | ;;
80 | *)
81 | properties="$properties $1"
82 | shift 1
83 | ;;
84 | esac
85 | done
86 |
87 | ci=true
88 | warnAsError=true
89 |
90 | if $help; then
91 | show_usage
92 | exit 0
93 | fi
94 |
95 | . "$scriptroot/tools.sh"
96 | InitializeToolset
97 |
98 | if [[ -z "$task" ]]; then
99 | Write-PipelineTelemetryError -Category 'Task' -Name 'MissingTask' -Message "Missing required parameter '-task '"
100 | ExitWithExitCode 1
101 | fi
102 |
103 | taskProject=$(GetSdkTaskProject "$task")
104 | if [[ ! -e "$taskProject" ]]; then
105 | Write-PipelineTelemetryError -Category 'Task' -Name 'UnknownTask' -Message "Unknown task: $task"
106 | ExitWithExitCode 1
107 | fi
108 |
109 | if $restore; then
110 | Build "Restore"
111 | fi
112 |
113 | Build "Execute"
114 |
115 |
116 | ExitWithExitCode 0
117 |
--------------------------------------------------------------------------------
/eng/common/sdl/NuGet.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/eng/common/sdl/extract-artifact-archives.ps1:
--------------------------------------------------------------------------------
1 | # This script looks for each archive file in a directory and extracts it into the target directory.
2 | # For example, the file "$InputPath/bin.tar.gz" extracts to "$ExtractPath/bin.tar.gz.extracted/**".
3 | # Uses the "tar" utility added to Windows 10 / Windows 2019 that supports tar.gz and zip.
4 | param(
5 | # Full path to directory where archives are stored.
6 | [Parameter(Mandatory=$true)][string] $InputPath,
7 | # Full path to directory to extract archives into. May be the same as $InputPath.
8 | [Parameter(Mandatory=$true)][string] $ExtractPath
9 | )
10 |
11 | $ErrorActionPreference = 'Stop'
12 | Set-StrictMode -Version 2.0
13 |
14 | $disableConfigureToolsetImport = $true
15 |
16 | try {
17 | # `tools.ps1` checks $ci to perform some actions. Since the SDL
18 | # scripts don't necessarily execute in the same agent that run the
19 | # build.ps1/sh script this variable isn't automatically set.
20 | $ci = $true
21 | . $PSScriptRoot\..\tools.ps1
22 |
23 | Measure-Command {
24 | $jobs = @()
25 |
26 | # Find archive files for non-Windows and Windows builds.
27 | $archiveFiles = @(
28 | Get-ChildItem (Join-Path $InputPath "*.tar.gz")
29 | Get-ChildItem (Join-Path $InputPath "*.zip")
30 | )
31 |
32 | foreach ($targzFile in $archiveFiles) {
33 | $jobs += Start-Job -ScriptBlock {
34 | $file = $using:targzFile
35 | $fileName = [System.IO.Path]::GetFileName($file)
36 | $extractDir = Join-Path $using:ExtractPath "$fileName.extracted"
37 |
38 | New-Item $extractDir -ItemType Directory -Force | Out-Null
39 |
40 | Write-Host "Extracting '$file' to '$extractDir'..."
41 |
42 | # Pipe errors to stdout to prevent PowerShell detecting them and quitting the job early.
43 | # This type of quit skips the catch, so we wouldn't be able to tell which file triggered the
44 | # error. Save output so it can be stored in the exception string along with context.
45 | $output = tar -xf $file -C $extractDir 2>&1
46 | # Handle NZEC manually rather than using Exit-IfNZEC: we are in a background job, so we
47 | # don't have access to the outer scope.
48 | if ($LASTEXITCODE -ne 0) {
49 | throw "Error extracting '$file': non-zero exit code ($LASTEXITCODE). Output: '$output'"
50 | }
51 |
52 | Write-Host "Extracted to $extractDir"
53 | }
54 | }
55 |
56 | Receive-Job $jobs -Wait
57 | }
58 | }
59 | catch {
60 | Write-Host $_
61 | Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_
62 | ExitWithExitCode 1
63 | }
64 |
--------------------------------------------------------------------------------
/eng/common/sdl/extract-artifact-packages.ps1:
--------------------------------------------------------------------------------
1 | param(
2 | [Parameter(Mandatory=$true)][string] $InputPath, # Full path to directory where artifact packages are stored
3 | [Parameter(Mandatory=$true)][string] $ExtractPath # Full path to directory where the packages will be extracted
4 | )
5 |
6 | $ErrorActionPreference = 'Stop'
7 | Set-StrictMode -Version 2.0
8 |
9 | $disableConfigureToolsetImport = $true
10 |
11 | function ExtractArtifacts {
12 | if (!(Test-Path $InputPath)) {
13 | Write-Host "Input Path does not exist: $InputPath"
14 | ExitWithExitCode 0
15 | }
16 | $Jobs = @()
17 | Get-ChildItem "$InputPath\*.nupkg" |
18 | ForEach-Object {
19 | $Jobs += Start-Job -ScriptBlock $ExtractPackage -ArgumentList $_.FullName
20 | }
21 |
22 | foreach ($Job in $Jobs) {
23 | Wait-Job -Id $Job.Id | Receive-Job
24 | }
25 | }
26 |
27 | try {
28 | # `tools.ps1` checks $ci to perform some actions. Since the SDL
29 | # scripts don't necessarily execute in the same agent that run the
30 | # build.ps1/sh script this variable isn't automatically set.
31 | $ci = $true
32 | . $PSScriptRoot\..\tools.ps1
33 |
34 | $ExtractPackage = {
35 | param(
36 | [string] $PackagePath # Full path to a NuGet package
37 | )
38 |
39 | if (!(Test-Path $PackagePath)) {
40 | Write-PipelineTelemetryError -Category 'Build' -Message "Input file does not exist: $PackagePath"
41 | ExitWithExitCode 1
42 | }
43 |
44 | $RelevantExtensions = @('.dll', '.exe', '.pdb')
45 | Write-Host -NoNewLine 'Extracting ' ([System.IO.Path]::GetFileName($PackagePath)) '...'
46 |
47 | $PackageId = [System.IO.Path]::GetFileNameWithoutExtension($PackagePath)
48 | $ExtractPath = Join-Path -Path $using:ExtractPath -ChildPath $PackageId
49 |
50 | Add-Type -AssemblyName System.IO.Compression.FileSystem
51 |
52 | [System.IO.Directory]::CreateDirectory($ExtractPath);
53 |
54 | try {
55 | $zip = [System.IO.Compression.ZipFile]::OpenRead($PackagePath)
56 |
57 | $zip.Entries |
58 | Where-Object {$RelevantExtensions -contains [System.IO.Path]::GetExtension($_.Name)} |
59 | ForEach-Object {
60 | $TargetPath = Join-Path -Path $ExtractPath -ChildPath (Split-Path -Path $_.FullName)
61 | [System.IO.Directory]::CreateDirectory($TargetPath);
62 |
63 | $TargetFile = Join-Path -Path $ExtractPath -ChildPath $_.FullName
64 | [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_, $TargetFile)
65 | }
66 | }
67 | catch {
68 | Write-Host $_
69 | Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_
70 | ExitWithExitCode 1
71 | }
72 | finally {
73 | $zip.Dispose()
74 | }
75 | }
76 | Measure-Command { ExtractArtifacts }
77 | }
78 | catch {
79 | Write-Host $_
80 | Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_
81 | ExitWithExitCode 1
82 | }
83 |
--------------------------------------------------------------------------------
/eng/common/sdl/init-sdl.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | [string] $GuardianCliLocation,
3 | [string] $Repository,
4 | [string] $BranchName='master',
5 | [string] $WorkingDirectory,
6 | [string] $AzureDevOpsAccessToken,
7 | [string] $GuardianLoggerLevel='Standard'
8 | )
9 |
10 | $ErrorActionPreference = 'Stop'
11 | Set-StrictMode -Version 2.0
12 | $disableConfigureToolsetImport = $true
13 | $global:LASTEXITCODE = 0
14 |
15 | # `tools.ps1` checks $ci to perform some actions. Since the SDL
16 | # scripts don't necessarily execute in the same agent that run the
17 | # build.ps1/sh script this variable isn't automatically set.
18 | $ci = $true
19 | . $PSScriptRoot\..\tools.ps1
20 |
21 | # Don't display the console progress UI - it's a huge perf hit
22 | $ProgressPreference = 'SilentlyContinue'
23 |
24 | # Construct basic auth from AzDO access token; construct URI to the repository's gdn folder stored in that repository; construct location of zip file
25 | $encodedPat = [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$AzureDevOpsAccessToken"))
26 | $escapedRepository = [Uri]::EscapeDataString("/$Repository/$BranchName/.gdn")
27 | $uri = "https://dev.azure.com/dnceng/internal/_apis/git/repositories/sdl-tool-cfg/Items?path=$escapedRepository&versionDescriptor[versionOptions]=0&`$format=zip&api-version=5.0"
28 | $zipFile = "$WorkingDirectory/gdn.zip"
29 |
30 | Add-Type -AssemblyName System.IO.Compression.FileSystem
31 | $gdnFolder = (Join-Path $WorkingDirectory '.gdn')
32 |
33 | try {
34 | # if the folder does not exist, we'll do a guardian init and push it to the remote repository
35 | Write-Host 'Initializing Guardian...'
36 | Write-Host "$GuardianCliLocation init --working-directory $WorkingDirectory --logger-level $GuardianLoggerLevel"
37 | & $GuardianCliLocation init --working-directory $WorkingDirectory --logger-level $GuardianLoggerLevel
38 | if ($LASTEXITCODE -ne 0) {
39 | Write-PipelineTelemetryError -Force -Category 'Build' -Message "Guardian init failed with exit code $LASTEXITCODE."
40 | ExitWithExitCode $LASTEXITCODE
41 | }
42 | # We create the mainbaseline so it can be edited later
43 | Write-Host "$GuardianCliLocation baseline --working-directory $WorkingDirectory --name mainbaseline"
44 | & $GuardianCliLocation baseline --working-directory $WorkingDirectory --name mainbaseline
45 | if ($LASTEXITCODE -ne 0) {
46 | Write-PipelineTelemetryError -Force -Category 'Build' -Message "Guardian baseline failed with exit code $LASTEXITCODE."
47 | ExitWithExitCode $LASTEXITCODE
48 | }
49 | ExitWithExitCode 0
50 | }
51 | catch {
52 | Write-Host $_.ScriptStackTrace
53 | Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_
54 | ExitWithExitCode 1
55 | }
56 |
--------------------------------------------------------------------------------
/eng/common/sdl/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/eng/common/sdl/run-sdl.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | [string] $GuardianCliLocation,
3 | [string] $WorkingDirectory,
4 | [string] $GdnFolder,
5 | [string] $UpdateBaseline,
6 | [string] $GuardianLoggerLevel='Standard'
7 | )
8 |
9 | $ErrorActionPreference = 'Stop'
10 | Set-StrictMode -Version 2.0
11 | $disableConfigureToolsetImport = $true
12 | $global:LASTEXITCODE = 0
13 |
14 | try {
15 | # `tools.ps1` checks $ci to perform some actions. Since the SDL
16 | # scripts don't necessarily execute in the same agent that run the
17 | # build.ps1/sh script this variable isn't automatically set.
18 | $ci = $true
19 | . $PSScriptRoot\..\tools.ps1
20 |
21 | # We store config files in the r directory of .gdn
22 | $gdnConfigPath = Join-Path $GdnFolder 'r'
23 | $ValidPath = Test-Path $GuardianCliLocation
24 |
25 | if ($ValidPath -eq $False)
26 | {
27 | Write-PipelineTelemetryError -Force -Category 'Sdl' -Message "Invalid Guardian CLI Location."
28 | ExitWithExitCode 1
29 | }
30 |
31 | $gdnConfigFiles = Get-ChildItem $gdnConfigPath -Recurse -Include '*.gdnconfig'
32 | Write-Host "Discovered Guardian config files:"
33 | $gdnConfigFiles | Out-String | Write-Host
34 |
35 | Exec-BlockVerbosely {
36 | & $GuardianCliLocation run `
37 | --working-directory $WorkingDirectory `
38 | --baseline mainbaseline `
39 | --update-baseline $UpdateBaseline `
40 | --logger-level $GuardianLoggerLevel `
41 | --config @gdnConfigFiles
42 | Exit-IfNZEC "Sdl"
43 | }
44 | }
45 | catch {
46 | Write-Host $_.ScriptStackTrace
47 | Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_
48 | ExitWithExitCode 1
49 | }
50 |
--------------------------------------------------------------------------------
/eng/common/sdl/sdl.ps1:
--------------------------------------------------------------------------------
1 |
2 | function Install-Gdn {
3 | param(
4 | [Parameter(Mandatory=$true)]
5 | [string]$Path,
6 |
7 | # If omitted, install the latest version of Guardian, otherwise install that specific version.
8 | [string]$Version
9 | )
10 |
11 | $ErrorActionPreference = 'Stop'
12 | Set-StrictMode -Version 2.0
13 | $disableConfigureToolsetImport = $true
14 | $global:LASTEXITCODE = 0
15 |
16 | # `tools.ps1` checks $ci to perform some actions. Since the SDL
17 | # scripts don't necessarily execute in the same agent that run the
18 | # build.ps1/sh script this variable isn't automatically set.
19 | $ci = $true
20 | . $PSScriptRoot\..\tools.ps1
21 |
22 | $argumentList = @("install", "Microsoft.Guardian.Cli", "-Source https://securitytools.pkgs.visualstudio.com/_packaging/Guardian/nuget/v3/index.json", "-OutputDirectory $Path", "-NonInteractive", "-NoCache")
23 |
24 | if ($Version) {
25 | $argumentList += "-Version $Version"
26 | }
27 |
28 | Start-Process nuget -Verbose -ArgumentList $argumentList -NoNewWindow -Wait
29 |
30 | $gdnCliPath = Get-ChildItem -Filter guardian.cmd -Recurse -Path $Path
31 |
32 | if (!$gdnCliPath)
33 | {
34 | Write-PipelineTelemetryError -Category 'Sdl' -Message 'Failure installing Guardian'
35 | }
36 |
37 | return $gdnCliPath.FullName
38 | }
--------------------------------------------------------------------------------
/eng/common/sdl/trim-assets-version.ps1:
--------------------------------------------------------------------------------
1 | <#
2 | .SYNOPSIS
3 | Install and run the 'Microsoft.DotNet.VersionTools.Cli' tool with the 'trim-artifacts-version' command to trim the version from the NuGet assets file name.
4 |
5 | .PARAMETER InputPath
6 | Full path to directory where artifact packages are stored
7 |
8 | .PARAMETER Recursive
9 | Search for NuGet packages recursively
10 |
11 | #>
12 |
13 | Param(
14 | [string] $InputPath,
15 | [bool] $Recursive = $true
16 | )
17 |
18 | $CliToolName = "Microsoft.DotNet.VersionTools.Cli"
19 |
20 | function Install-VersionTools-Cli {
21 | param(
22 | [Parameter(Mandatory=$true)][string]$Version
23 | )
24 |
25 | Write-Host "Installing the package '$CliToolName' with a version of '$version' ..."
26 | $feed = "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json"
27 |
28 | $argumentList = @("tool", "install", "--local", "$CliToolName", "--add-source $feed", "--no-cache", "--version $Version", "--create-manifest-if-needed")
29 | Start-Process "$dotnet" -Verbose -ArgumentList $argumentList -NoNewWindow -Wait
30 | }
31 |
32 | # -------------------------------------------------------------------
33 |
34 | if (!(Test-Path $InputPath)) {
35 | Write-Host "Input Path '$InputPath' does not exist"
36 | ExitWithExitCode 1
37 | }
38 |
39 | $ErrorActionPreference = 'Stop'
40 | Set-StrictMode -Version 2.0
41 |
42 | $disableConfigureToolsetImport = $true
43 | $global:LASTEXITCODE = 0
44 |
45 | # `tools.ps1` checks $ci to perform some actions. Since the SDL
46 | # scripts don't necessarily execute in the same agent that run the
47 | # build.ps1/sh script this variable isn't automatically set.
48 | $ci = $true
49 | . $PSScriptRoot\..\tools.ps1
50 |
51 | try {
52 | $dotnetRoot = InitializeDotNetCli -install:$true
53 | $dotnet = "$dotnetRoot\dotnet.exe"
54 |
55 | $toolsetVersion = Read-ArcadeSdkVersion
56 | Install-VersionTools-Cli -Version $toolsetVersion
57 |
58 | $cliToolFound = (& "$dotnet" tool list --local | Where-Object {$_.Split(' ')[0] -eq $CliToolName})
59 | if ($null -eq $cliToolFound) {
60 | Write-PipelineTelemetryError -Force -Category 'Sdl' -Message "The '$CliToolName' tool is not installed."
61 | ExitWithExitCode 1
62 | }
63 |
64 | Exec-BlockVerbosely {
65 | & "$dotnet" $CliToolName trim-assets-version `
66 | --assets-path $InputPath `
67 | --recursive $Recursive
68 | Exit-IfNZEC "Sdl"
69 | }
70 | }
71 | catch {
72 | Write-Host $_
73 | Write-PipelineTelemetryError -Force -Category 'Sdl' -Message $_
74 | ExitWithExitCode 1
75 | }
76 |
--------------------------------------------------------------------------------
/eng/common/templates-official/job/onelocbuild.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - template: /eng/common/core-templates/job/onelocbuild.yml
3 | parameters:
4 | is1ESPipeline: true
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates-official/job/publish-build-assets.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - template: /eng/common/core-templates/job/publish-build-assets.yml
3 | parameters:
4 | is1ESPipeline: true
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates-official/job/source-build.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - template: /eng/common/core-templates/job/source-build.yml
3 | parameters:
4 | is1ESPipeline: true
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates-official/job/source-index-stage1.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - template: /eng/common/core-templates/job/source-index-stage1.yml
3 | parameters:
4 | is1ESPipeline: true
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates-official/jobs/codeql-build.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - template: /eng/common/core-templates/jobs/codeql-build.yml
3 | parameters:
4 | is1ESPipeline: true
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates-official/jobs/jobs.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - template: /eng/common/core-templates/jobs/jobs.yml
3 | parameters:
4 | is1ESPipeline: true
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates-official/jobs/source-build.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - template: /eng/common/core-templates/jobs/source-build.yml
3 | parameters:
4 | is1ESPipeline: true
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
--------------------------------------------------------------------------------
/eng/common/templates-official/post-build/common-variables.yml:
--------------------------------------------------------------------------------
1 | variables:
2 | - template: /eng/common/core-templates/post-build/common-variables.yml
3 | parameters:
4 | # Specifies whether to use 1ES
5 | is1ESPipeline: true
6 |
7 | ${{ each parameter in parameters }}:
8 | ${{ parameter.key }}: ${{ parameter.value }}
--------------------------------------------------------------------------------
/eng/common/templates-official/post-build/post-build.yml:
--------------------------------------------------------------------------------
1 | stages:
2 | - template: /eng/common/core-templates/post-build/post-build.yml
3 | parameters:
4 | # Specifies whether to use 1ES
5 | is1ESPipeline: true
6 |
7 | ${{ each parameter in parameters }}:
8 | ${{ parameter.key }}: ${{ parameter.value }}
9 |
--------------------------------------------------------------------------------
/eng/common/templates-official/post-build/setup-maestro-vars.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml
3 | parameters:
4 | # Specifies whether to use 1ES
5 | is1ESPipeline: true
6 |
7 | ${{ each parameter in parameters }}:
8 | ${{ parameter.key }}: ${{ parameter.value }}
--------------------------------------------------------------------------------
/eng/common/templates-official/steps/component-governance.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/component-governance.yml
3 | parameters:
4 | is1ESPipeline: true
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates-official/steps/enable-internal-runtimes.yml:
--------------------------------------------------------------------------------
1 | # Obtains internal runtime download credentials and populates the 'dotnetbuilds-internal-container-read-token-base64'
2 | # variable with the base64-encoded SAS token, by default
3 | steps:
4 | - template: /eng/common/core-templates/steps/enable-internal-runtimes.yml
5 | parameters:
6 | is1ESPipeline: true
7 |
8 | ${{ each parameter in parameters }}:
9 | ${{ parameter.key }}: ${{ parameter.value }}
10 |
--------------------------------------------------------------------------------
/eng/common/templates-official/steps/enable-internal-sources.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/enable-internal-sources.yml
3 | parameters:
4 | is1ESPipeline: true
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
--------------------------------------------------------------------------------
/eng/common/templates-official/steps/generate-sbom.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/generate-sbom.yml
3 | parameters:
4 | is1ESPipeline: true
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates-official/steps/get-delegation-sas.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/get-delegation-sas.yml
3 | parameters:
4 | is1ESPipeline: true
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates-official/steps/get-federated-access-token.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/get-federated-access-token.yml
3 | parameters:
4 | is1ESPipeline: true
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
--------------------------------------------------------------------------------
/eng/common/templates-official/steps/publish-build-artifacts.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | - name: displayName
3 | type: string
4 | default: 'Publish to Build Artifact'
5 |
6 | - name: condition
7 | type: string
8 | default: succeeded()
9 |
10 | - name: artifactName
11 | type: string
12 |
13 | - name: pathToPublish
14 | type: string
15 |
16 | - name: continueOnError
17 | type: boolean
18 | default: false
19 |
20 | - name: publishLocation
21 | type: string
22 | default: 'Container'
23 |
24 | - name: is1ESPipeline
25 | type: boolean
26 | default: true
27 |
28 | - name: retryCountOnTaskFailure
29 | type: string
30 | default: 10
31 |
32 | steps:
33 | - ${{ if ne(parameters.is1ESPipeline, true) }}:
34 | - 'eng/common/templates-official cannot be referenced from a non-1ES managed template': error
35 | - task: 1ES.PublishBuildArtifacts@1
36 | displayName: ${{ parameters.displayName }}
37 | condition: ${{ parameters.condition }}
38 | ${{ if parameters.continueOnError }}:
39 | continueOnError: ${{ parameters.continueOnError }}
40 | inputs:
41 | PublishLocation: ${{ parameters.publishLocation }}
42 | PathtoPublish: ${{ parameters.pathToPublish }}
43 | ${{ if parameters.artifactName }}:
44 | ArtifactName: ${{ parameters.artifactName }}
45 | ${{ if parameters.retryCountOnTaskFailure }}:
46 | retryCountOnTaskFailure: ${{ parameters.retryCountOnTaskFailure }}
47 |
--------------------------------------------------------------------------------
/eng/common/templates-official/steps/publish-logs.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/publish-logs.yml
3 | parameters:
4 | is1ESPipeline: true
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates-official/steps/publish-pipeline-artifacts.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | - name: is1ESPipeline
3 | type: boolean
4 | default: true
5 |
6 | - name: args
7 | type: object
8 | default: {}
9 |
10 | steps:
11 | - ${{ if ne(parameters.is1ESPipeline, true) }}:
12 | - 'eng/common/templates-official cannot be referenced from a non-1ES managed template': error
13 | - task: 1ES.PublishPipelineArtifact@1
14 | displayName: ${{ coalesce(parameters.args.displayName, 'Publish to Build Artifact') }}
15 | ${{ if parameters.args.condition }}:
16 | condition: ${{ parameters.args.condition }}
17 | ${{ else }}:
18 | condition: succeeded()
19 | ${{ if parameters.args.continueOnError }}:
20 | continueOnError: ${{ parameters.args.continueOnError }}
21 | inputs:
22 | targetPath: ${{ parameters.args.targetPath }}
23 | ${{ if parameters.args.artifactName }}:
24 | artifactName: ${{ parameters.args.artifactName }}
25 | ${{ if parameters.args.properties }}:
26 | properties: ${{ parameters.args.properties }}
27 | ${{ if parameters.args.sbomEnabled }}:
28 | sbomEnabled: ${{ parameters.args.sbomEnabled }}
29 |
--------------------------------------------------------------------------------
/eng/common/templates-official/steps/retain-build.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/retain-build.yml
3 | parameters:
4 | is1ESPipeline: true
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates-official/steps/send-to-helix.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/send-to-helix.yml
3 | parameters:
4 | is1ESPipeline: true
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates-official/steps/source-build.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/source-build.yml
3 | parameters:
4 | is1ESPipeline: true
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates-official/steps/source-index-stage1-publish.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/source-index-stage1-publish.yml
3 | parameters:
4 | is1ESPipeline: true
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates-official/variables/pool-providers.yml:
--------------------------------------------------------------------------------
1 | # Select a pool provider based off branch name. Anything with branch name containing 'release' must go into an -Svc pool,
2 | # otherwise it should go into the "normal" pools. This separates out the queueing and billing of released branches.
3 |
4 | # Motivation:
5 | # Once a given branch of a repository's output has been officially "shipped" once, it is then considered to be COGS
6 | # (Cost of goods sold) and should be moved to a servicing pool provider. This allows both separation of queueing
7 | # (allowing release builds and main PR builds to not intefere with each other) and billing (required for COGS.
8 | # Additionally, the pool provider name itself may be subject to change when the .NET Core Engineering Services
9 | # team needs to move resources around and create new and potentially differently-named pools. Using this template
10 | # file from an Arcade-ified repo helps guard against both having to update one's release/* branches and renaming.
11 |
12 | # How to use:
13 | # This yaml assumes your shipped product branches use the naming convention "release/..." (which many do).
14 | # If we find alternate naming conventions in broad usage it can be added to the condition below.
15 | #
16 | # First, import the template in an arcade-ified repo to pick up the variables, e.g.:
17 | #
18 | # variables:
19 | # - template: /eng/common/templates-official/variables/pool-providers.yml
20 | #
21 | # ... then anywhere specifying the pool provider use the runtime variables,
22 | # $(DncEngInternalBuildPool)
23 | #
24 | # pool:
25 | # name: $(DncEngInternalBuildPool)
26 | # image: 1es-windows-2022
27 |
28 | variables:
29 | # Coalesce the target and source branches so we know when a PR targets a release branch
30 | # If these variables are somehow missing, fall back to main (tends to have more capacity)
31 |
32 | # Any new -Svc alternative pools should have variables added here to allow for splitting work
33 |
34 | - name: DncEngInternalBuildPool
35 | value: $[
36 | replace(
37 | replace(
38 | eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'),
39 | True,
40 | 'NetCore1ESPool-Svc-Internal'
41 | ),
42 | False,
43 | 'NetCore1ESPool-Internal'
44 | )
45 | ]
--------------------------------------------------------------------------------
/eng/common/templates-official/variables/sdl-variables.yml:
--------------------------------------------------------------------------------
1 | variables:
2 | # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in
3 | # sync with the packages.config file.
4 | - name: DefaultGuardianVersion
5 | value: 0.109.0
6 | - name: GuardianPackagesConfigFile
7 | value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config
--------------------------------------------------------------------------------
/eng/common/templates/job/onelocbuild.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - template: /eng/common/core-templates/job/onelocbuild.yml
3 | parameters:
4 | is1ESPipeline: false
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates/job/publish-build-assets.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - template: /eng/common/core-templates/job/publish-build-assets.yml
3 | parameters:
4 | is1ESPipeline: false
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates/job/source-build.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - template: /eng/common/core-templates/job/source-build.yml
3 | parameters:
4 | is1ESPipeline: false
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates/job/source-index-stage1.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - template: /eng/common/core-templates/job/source-index-stage1.yml
3 | parameters:
4 | is1ESPipeline: false
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates/jobs/codeql-build.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - template: /eng/common/core-templates/jobs/codeql-build.yml
3 | parameters:
4 | is1ESPipeline: false
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates/jobs/jobs.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - template: /eng/common/core-templates/jobs/jobs.yml
3 | parameters:
4 | is1ESPipeline: false
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates/jobs/source-build.yml:
--------------------------------------------------------------------------------
1 | jobs:
2 | - template: /eng/common/core-templates/jobs/source-build.yml
3 | parameters:
4 | is1ESPipeline: false
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
--------------------------------------------------------------------------------
/eng/common/templates/post-build/common-variables.yml:
--------------------------------------------------------------------------------
1 | variables:
2 | - template: /eng/common/core-templates/post-build/common-variables.yml
3 | parameters:
4 | # Specifies whether to use 1ES
5 | is1ESPipeline: false
6 |
7 | ${{ each parameter in parameters }}:
8 | ${{ parameter.key }}: ${{ parameter.value }}
--------------------------------------------------------------------------------
/eng/common/templates/post-build/post-build.yml:
--------------------------------------------------------------------------------
1 | stages:
2 | - template: /eng/common/core-templates/post-build/post-build.yml
3 | parameters:
4 | # Specifies whether to use 1ES
5 | is1ESPipeline: false
6 |
7 | ${{ each parameter in parameters }}:
8 | ${{ parameter.key }}: ${{ parameter.value }}
--------------------------------------------------------------------------------
/eng/common/templates/post-build/setup-maestro-vars.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/post-build/setup-maestro-vars.yml
3 | parameters:
4 | # Specifies whether to use 1ES
5 | is1ESPipeline: false
6 |
7 | ${{ each parameter in parameters }}:
8 | ${{ parameter.key }}: ${{ parameter.value }}
--------------------------------------------------------------------------------
/eng/common/templates/steps/component-governance.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/component-governance.yml
3 | parameters:
4 | is1ESPipeline: false
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates/steps/enable-internal-runtimes.yml:
--------------------------------------------------------------------------------
1 | # Obtains internal runtime download credentials and populates the 'dotnetbuilds-internal-container-read-token-base64'
2 | # variable with the base64-encoded SAS token, by default
3 |
4 | steps:
5 | - template: /eng/common/core-templates/steps/enable-internal-runtimes.yml
6 | parameters:
7 | is1ESPipeline: false
8 |
9 | ${{ each parameter in parameters }}:
10 | ${{ parameter.key }}: ${{ parameter.value }}
11 |
--------------------------------------------------------------------------------
/eng/common/templates/steps/enable-internal-sources.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/enable-internal-sources.yml
3 | parameters:
4 | is1ESPipeline: false
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
--------------------------------------------------------------------------------
/eng/common/templates/steps/generate-sbom.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/generate-sbom.yml
3 | parameters:
4 | is1ESPipeline: false
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates/steps/get-delegation-sas.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/get-delegation-sas.yml
3 | parameters:
4 | is1ESPipeline: false
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates/steps/get-federated-access-token.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/get-federated-access-token.yml
3 | parameters:
4 | is1ESPipeline: false
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
--------------------------------------------------------------------------------
/eng/common/templates/steps/publish-build-artifacts.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | - name: is1ESPipeline
3 | type: boolean
4 | default: false
5 |
6 | - name: displayName
7 | type: string
8 | default: 'Publish to Build Artifact'
9 |
10 | - name: condition
11 | type: string
12 | default: succeeded()
13 |
14 | - name: artifactName
15 | type: string
16 |
17 | - name: pathToPublish
18 | type: string
19 |
20 | - name: continueOnError
21 | type: boolean
22 | default: false
23 |
24 | - name: publishLocation
25 | type: string
26 | default: 'Container'
27 |
28 | - name: retryCountOnTaskFailure
29 | type: string
30 | default: 10
31 |
32 | steps:
33 | - ${{ if eq(parameters.is1ESPipeline, true) }}:
34 | - 'eng/common/templates cannot be referenced from a 1ES managed template': error
35 | - task: PublishBuildArtifacts@1
36 | displayName: ${{ parameters.displayName }}
37 | condition: ${{ parameters.condition }}
38 | ${{ if parameters.continueOnError }}:
39 | continueOnError: ${{ parameters.continueOnError }}
40 | inputs:
41 | PublishLocation: ${{ parameters.publishLocation }}
42 | PathtoPublish: ${{ parameters.pathToPublish }}
43 | ${{ if parameters.artifactName }}:
44 | ArtifactName: ${{ parameters.artifactName }}
45 | ${{ if parameters.retryCountOnTaskFailure }}:
46 | retryCountOnTaskFailure: ${{ parameters.retryCountOnTaskFailure }}
47 |
--------------------------------------------------------------------------------
/eng/common/templates/steps/publish-logs.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/publish-logs.yml
3 | parameters:
4 | is1ESPipeline: false
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates/steps/publish-pipeline-artifacts.yml:
--------------------------------------------------------------------------------
1 | parameters:
2 | - name: is1ESPipeline
3 | type: boolean
4 | default: false
5 |
6 | - name: args
7 | type: object
8 | default: {}
9 |
10 | steps:
11 | - ${{ if eq(parameters.is1ESPipeline, true) }}:
12 | - 'eng/common/templates cannot be referenced from a 1ES managed template': error
13 | - task: PublishPipelineArtifact@1
14 | displayName: ${{ coalesce(parameters.args.displayName, 'Publish to Build Artifact') }}
15 | ${{ if parameters.args.condition }}:
16 | condition: ${{ parameters.args.condition }}
17 | ${{ else }}:
18 | condition: succeeded()
19 | ${{ if parameters.args.continueOnError }}:
20 | continueOnError: ${{ parameters.args.continueOnError }}
21 | inputs:
22 | targetPath: ${{ parameters.args.targetPath }}
23 | ${{ if parameters.args.artifactName }}:
24 | artifactName: ${{ parameters.args.artifactName }}
25 | ${{ if parameters.args.publishLocation }}:
26 | publishLocation: ${{ parameters.args.publishLocation }}
27 | ${{ if parameters.args.fileSharePath }}:
28 | fileSharePath: ${{ parameters.args.fileSharePath }}
29 | ${{ if parameters.args.Parallel }}:
30 | parallel: ${{ parameters.args.Parallel }}
31 | ${{ if parameters.args.parallelCount }}:
32 | parallelCount: ${{ parameters.args.parallelCount }}
33 | ${{ if parameters.args.properties }}:
34 | properties: ${{ parameters.args.properties }}
--------------------------------------------------------------------------------
/eng/common/templates/steps/retain-build.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/retain-build.yml
3 | parameters:
4 | is1ESPipeline: false
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates/steps/send-to-helix.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/send-to-helix.yml
3 | parameters:
4 | is1ESPipeline: false
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates/steps/source-build.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/source-build.yml
3 | parameters:
4 | is1ESPipeline: false
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates/steps/source-index-stage1-publish.yml:
--------------------------------------------------------------------------------
1 | steps:
2 | - template: /eng/common/core-templates/steps/source-index-stage1-publish.yml
3 | parameters:
4 | is1ESPipeline: false
5 |
6 | ${{ each parameter in parameters }}:
7 | ${{ parameter.key }}: ${{ parameter.value }}
8 |
--------------------------------------------------------------------------------
/eng/common/templates/variables/pool-providers.yml:
--------------------------------------------------------------------------------
1 | # Select a pool provider based off branch name. Anything with branch name containing 'release' must go into an -Svc pool,
2 | # otherwise it should go into the "normal" pools. This separates out the queueing and billing of released branches.
3 |
4 | # Motivation:
5 | # Once a given branch of a repository's output has been officially "shipped" once, it is then considered to be COGS
6 | # (Cost of goods sold) and should be moved to a servicing pool provider. This allows both separation of queueing
7 | # (allowing release builds and main PR builds to not intefere with each other) and billing (required for COGS.
8 | # Additionally, the pool provider name itself may be subject to change when the .NET Core Engineering Services
9 | # team needs to move resources around and create new and potentially differently-named pools. Using this template
10 | # file from an Arcade-ified repo helps guard against both having to update one's release/* branches and renaming.
11 |
12 | # How to use:
13 | # This yaml assumes your shipped product branches use the naming convention "release/..." (which many do).
14 | # If we find alternate naming conventions in broad usage it can be added to the condition below.
15 | #
16 | # First, import the template in an arcade-ified repo to pick up the variables, e.g.:
17 | #
18 | # variables:
19 | # - template: /eng/common/templates/variables/pool-providers.yml
20 | #
21 | # ... then anywhere specifying the pool provider use the runtime variables,
22 | # $(DncEngInternalBuildPool) and $ (DncEngPublicBuildPool), e.g.:
23 | #
24 | # pool:
25 | # name: $(DncEngInternalBuildPool)
26 | # demands: ImageOverride -equals windows.vs2019.amd64
27 | variables:
28 | - ${{ if eq(variables['System.TeamProject'], 'internal') }}:
29 | - template: /eng/common/templates-official/variables/pool-providers.yml
30 | - ${{ else }}:
31 | # Coalesce the target and source branches so we know when a PR targets a release branch
32 | # If these variables are somehow missing, fall back to main (tends to have more capacity)
33 |
34 | # Any new -Svc alternative pools should have variables added here to allow for splitting work
35 | - name: DncEngPublicBuildPool
36 | value: $[
37 | replace(
38 | replace(
39 | eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'),
40 | True,
41 | 'NetCore-Svc-Public'
42 | ),
43 | False,
44 | 'NetCore-Public'
45 | )
46 | ]
47 |
48 | - name: DncEngInternalBuildPool
49 | value: $[
50 | replace(
51 | replace(
52 | eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'),
53 | True,
54 | 'NetCore1ESPool-Svc-Internal'
55 | ),
56 | False,
57 | 'NetCore1ESPool-Internal'
58 | )
59 | ]
60 |
--------------------------------------------------------------------------------
/eng/common/templates/vmr-build-pr.yml:
--------------------------------------------------------------------------------
1 | trigger: none
2 | pr:
3 | branches:
4 | include:
5 | - main
6 | - release/*
7 | paths:
8 | exclude:
9 | - documentation/*
10 | - README.md
11 | - CODEOWNERS
12 |
13 | variables:
14 | - template: /eng/common/templates/variables/pool-providers.yml@self
15 |
16 | - name: skipComponentGovernanceDetection # we run CG on internal builds only
17 | value: true
18 |
19 | - name: Codeql.Enabled # we run CodeQL on internal builds only
20 | value: false
21 |
22 | resources:
23 | repositories:
24 | - repository: vmr
25 | type: github
26 | name: dotnet/dotnet
27 | endpoint: dotnet
28 |
29 | stages:
30 | - template: /eng/pipelines/templates/stages/vmr-build.yml@vmr
31 | parameters:
32 | isBuiltFromVmr: false
33 | scope: lite
34 |
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "tools": {
3 | "dotnet": "10.0.100-preview.5.25265.106"
4 | },
5 | "msbuild-sdks": {
6 | "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25305.3",
7 | "Microsoft.Build.Traversal": "3.4.0"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/hotreload-utils.proj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/Common/TempDirectory.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System;
5 | using System.IO;
6 |
7 | namespace Microsoft.DotNet.HotReload.Utils.Common;
8 |
9 | internal class TempDirectory : IDisposable
10 | {
11 | public TempDirectory(bool keep = false, string? dirname = null)
12 | {
13 | string subdir = dirname ?? System.IO.Path.GetRandomFileName();
14 | Path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), subdir);
15 | Keep = keep;
16 | Directory.CreateDirectory(Path);
17 | }
18 |
19 | public string Path { get; }
20 | public bool Keep { get; set; }
21 |
22 | public void Dispose()
23 | {
24 | if (!Keep)
25 | Directory.Delete(Path, true);
26 | GC.SuppressFinalize(this);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator.BuildTool/Microsoft.DotNet.HotReload.Utils.Generator.BuildTool.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | MSBuildSdk
6 |
7 | Major
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Microsoft.DotNet.HotReload.Utils.Generator.BuildTool.targets.in
22 | $(IntermediateOutputPath)Microsoft.DotNet.HotReload.Utils.Generator.BuildTool.targets
23 |
24 |
25 |
29 |
30 |
33 |
34 |
35 |
36 |
37 |
38 | build/Microsoft.DotNet.HotReload.Utils.Generator.BuildTool.targets
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator.BuildTool/Program.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | return Microsoft.DotNet.HotReload.Utils.Generator.Frontend.Frontend.Main(args);
5 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator.BuildTool/README.md:
--------------------------------------------------------------------------------
1 | # Microsoft.DotNet.HotReload.Utils.Generator.BuildTool #
2 |
3 | Generate deltas as part of an MSBuild project.
4 |
5 | ## How to use it ##
6 |
7 | Starting with an existing SDK-style project, add:
8 |
9 | ```xml
10 |
11 |
12 |
13 |
14 |
15 | deltascript.json
16 |
17 | ```
18 |
19 | Where the `deltascript.json` file contains the changes to be applied:
20 |
21 | ```json
22 | {"changes":
23 | [
24 | {"document": "relativePath/to/file.cs", "update": "relativePath/to/file_v1.cs"},
25 | {"document": "file2.cs", "update": "file2_v2.cs"},
26 | {"document": "relativePath/to/file.cs", "update": "relativePath/to/file_v3.cs"}
27 | ]
28 | }
29 | ```
30 |
31 | The tool will run as part of the build after the `Build` target and generate `.dmeta`, `.dil` and `.dpdb` files in `$(OutputPath)`.
32 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator.Data/Microsoft.DotNet.HotReload.Utils.Generator.Data.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator.Data/OutputSummary/OutputSummary.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System.Text.Json.Serialization;
5 |
6 |
7 | namespace Microsoft.DotNet.HotReload.Utils.Generator.OutputSummary;
8 |
9 | public class OutputSummary {
10 | [JsonPropertyName("deltas")]
11 | public Delta[]? Deltas {get; init;}
12 |
13 | [JsonExtensionData]
14 | public System.Collections.Generic.Dictionary? Extra {get; init;}
15 |
16 | [JsonConstructor]
17 | public OutputSummary(Delta[]? deltas) {
18 | Deltas = deltas;
19 | }
20 | }
21 |
22 | public class Delta {
23 | [JsonPropertyName("assembly")]
24 | public string? Assembly {get; init;}
25 | [JsonPropertyName("metadata")]
26 | public string? Metadata {get; init;}
27 | [JsonPropertyName("il")]
28 | public string? IL {get; init;}
29 | [JsonPropertyName("pdb")]
30 | public string? Pdb {get; init;}
31 |
32 | [JsonConstructor]
33 | public Delta (string? assembly, string? metadata, string? il, string? pdb) {
34 | Assembly = assembly;
35 | Metadata = metadata;
36 | IL = il;
37 | Pdb = pdb;
38 | }
39 |
40 | [JsonExtensionData]
41 | public System.Collections.Generic.Dictionary? Extra {get; set;}
42 | }
43 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator.Data/Script/Json/Script.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System.Text.Json.Serialization;
5 |
6 | namespace Microsoft.DotNet.HotReload.Utils.Generator.Script.Json;
7 | public class Script {
8 |
9 | [JsonConverter(typeof(ScriptCapabilitiesConverter))]
10 | public string? Capabilities {get; init;}
11 | public Change[]? Changes {get; init;}
12 |
13 | [System.Text.Json.Serialization.JsonConstructor]
14 | public Script (string? capabilities, Change[]? changes) {
15 | Capabilities = capabilities;
16 | Changes = changes;
17 | }
18 |
19 | }
20 |
21 | public class Change {
22 | public string Document {get; init;}
23 | public string Update {get; init;}
24 |
25 | [System.Text.Json.Serialization.JsonConstructor]
26 | public Change (string document, string update) {
27 | Document = document;
28 | Update = update;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator.Data/Script/Json/ScriptCapabilitiesConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text.Json;
3 | using System.Text.Json.Serialization;
4 |
5 |
6 | namespace Microsoft.DotNet.HotReload.Utils.Generator.Script.Json;
7 |
8 | /// Deserialize capabilities as either a JSON string value, or an array of JSON string values
9 | public class ScriptCapabilitiesConverter : JsonConverter {
10 | public override bool HandleNull => true;
11 |
12 | public ScriptCapabilitiesConverter() {}
13 |
14 | public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
15 | => reader.TokenType switch {
16 | JsonTokenType.Null => string.Empty,
17 | JsonTokenType.String => reader.GetString(),
18 | JsonTokenType.StartArray => ReadCapsArray (ref reader, options),
19 | _ => throw new JsonException(),
20 | };
21 |
22 | private static string ReadCapsArray(ref Utf8JsonReader reader, JsonSerializerOptions options) {
23 | var elems = JsonSerializer.Deserialize (ref reader, options);
24 | if (elems == null)
25 | throw new JsonException();
26 | return String.Join(' ', elems);
27 | }
28 | public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) => writer.WriteStringValue(value);
29 | }
30 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator.Data/UpdateHandlerInfo.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System.Collections.Immutable;
5 | using System.Text.Json.Serialization;
6 |
7 |
8 | namespace Microsoft.DotNet.HotReload.Utils.Generator;
9 |
10 | public class UpdateHandlerInfo {
11 |
12 | [JsonPropertyName("updatedTypes")]
13 | public ImmutableArray UpdatedTypes {get; init;}
14 |
15 | public UpdateHandlerInfo(ImmutableArray updatedTypes) {
16 | UpdatedTypes = updatedTypes;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator.Frontend/Microsoft.DotNet.HotReload.Utils.Generator.Frontend.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator.Tasks/Microsoft.DotNet.HotReload.Utils.Generator.Tasks.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator/BaselineArtifacts.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using Microsoft.CodeAnalysis;
5 |
6 | namespace Microsoft.DotNet.HotReload.Utils.Generator;
7 |
8 | /// What we know about the base compilation
9 | ///
10 | /// BaselineSolution: the solution we're working on
11 | /// BaselineProjectId: the project we're working on; FIXME: need to be more clever when there are project references
12 | /// BaselineOutputAsmPath: absolute path of the baseline assembly
13 | /// DocResolver: a map from document ids to documents
14 | /// ChangeMakerService: A stateful encapsulatio of the series of changes that have been made to the baseline
15 | public record struct BaselineArtifacts (Solution BaselineSolution, ProjectId BaselineProjectId, string BaselineOutputAsmPath, DocResolver DocResolver, EnC.ChangeMakerService ChangeMakerService);
16 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator/Config.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System.Collections.Generic;
5 | using System.IO;
6 |
7 | namespace Microsoft.DotNet.HotReload.Utils.Generator;
8 |
9 | public class Config
10 | {
11 |
12 | public static ConfigBuilder Builder () => new ();
13 |
14 | public class ConfigBuilder {
15 | internal ConfigBuilder () {}
16 |
17 | public bool Live {get; set;} = false;
18 |
19 | public List> Properties {get; set;} = new List> ();
20 | public string ProjectPath {get; set; } = "";
21 |
22 | public string ScriptPath {get; set; } = "";
23 |
24 | public string OutputSummaryPath {get; set; } = "";
25 | public Config Bake () {
26 | return new MsbuildConfig(this);
27 | }
28 |
29 | public List EditAndContinueCapabilities {get; set; } = new List();
30 |
31 | public bool NoWarnUnknownCapabilities {get; set;} = false;
32 | }
33 |
34 | protected Config (ConfigBuilder builder) {
35 | Live = builder.Live;
36 | Properties = builder.Properties;
37 | ProjectPath = builder.ProjectPath;
38 | ScriptPath = builder.ScriptPath;
39 | OutputSummaryPath = builder.OutputSummaryPath;
40 | EditAndContinueCapabilities = builder.EditAndContinueCapabilities.ToArray();
41 | NoWarnUnknownCapabilities = builder.NoWarnUnknownCapabilities;
42 | }
43 |
44 | public bool Live { get; }
45 |
46 | /// Additional properties for msbuild
47 | public IReadOnlyList> Properties { get; }
48 |
49 |
50 | /// the csproj for this project
51 | public string ProjectPath { get; }
52 |
53 | /// the files to watch for live changes
54 | public string LiveCodingWatchPattern { get => "*.cs"; }
55 |
56 | /// the directory to watch for live changes
57 | public string LiveCodingWatchDir { get => Path.GetDirectoryName(ProjectPath) ?? "."; }
58 |
59 | /// the path of a JSON script to drive the delta generation
60 | public string ScriptPath { get; }
61 |
62 | /// A path for a JSON file to collect the produced artifacts
63 | public string OutputSummaryPath { get; }
64 |
65 | /// A set of strings specifying edit and continue capabilities to pass to Roslyn
66 | public string[] EditAndContinueCapabilities { get; }
67 |
68 | /// If 'true' don't print a warning if a capability is not known.
69 | public bool NoWarnUnknownCapabilities {get; }
70 | }
71 |
72 | internal class MsbuildConfig : Config {
73 | internal MsbuildConfig (ConfigBuilder builder) : base (builder) {}
74 | }
75 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator/Delta.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using Microsoft.CodeAnalysis;
5 |
6 | namespace Microsoft.DotNet.HotReload.Utils.Generator;
7 |
8 | /// A Delta represents an input that is used to produce the metadata, IL and PDB emitted differences.
9 | /// It contains a Change which identifies the source document that changed and its updated contents
10 | public readonly record struct Delta (Plan.Change Change);
11 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator/DeltaNaming.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | namespace Microsoft.DotNet.HotReload.Utils.Generator;
5 |
6 | /// Properties describing names of the artifacts for a given revision of a baseline assembly
7 | public class DeltaNaming {
8 |
9 | readonly string _baseAssemblyPath;
10 | readonly int _rev;
11 |
12 | public DeltaNaming (string baseAssemblyPath, int rev) {
13 | _rev = rev;
14 | _baseAssemblyPath = baseAssemblyPath;
15 | }
16 | public string Dmeta => _baseAssemblyPath + "." + Rev + ".dmeta";
17 | public string Dil => _baseAssemblyPath + "." + Rev + ".dil";
18 | public string Dpdb => _baseAssemblyPath + "." + Rev + ".dpdb";
19 |
20 | public string UpdateHandlerInfo => _baseAssemblyPath + "." + Rev + ".handler.json";
21 | public int Rev => _rev;
22 |
23 | public DeltaNaming Next()
24 | {
25 | return new DeltaNaming(_baseAssemblyPath, Rev+1);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator/DeltaOutputStreams.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System;
5 | using System.IO;
6 | using System.Threading.Tasks;
7 |
8 | namespace Microsoft.DotNet.HotReload.Utils.Generator;
9 | public sealed class DeltaOutputStreams : IAsyncDisposable {
10 | public Stream MetaStream {get; private set;}
11 | public Stream IlStream {get; private set;}
12 | public Stream PdbStream {get; private set;}
13 |
14 | public Stream UpdateHandlerInfoStream {get; private set;}
15 |
16 | public DeltaOutputStreams(Stream dmeta, Stream dil, Stream dpdb, Stream updateHandlerInfo) {
17 | MetaStream = dmeta;
18 | IlStream = dil;
19 | PdbStream = dpdb;
20 | UpdateHandlerInfoStream = updateHandlerInfo;
21 | }
22 |
23 | public void Dispose () {
24 | MetaStream?.Dispose();
25 | IlStream?.Dispose();
26 | PdbStream?.Dispose();
27 | UpdateHandlerInfoStream?.Dispose();
28 | }
29 |
30 | public async ValueTask DisposeAsync () {
31 | if (MetaStream != null) await MetaStream.DisposeAsync();
32 | if (IlStream != null) await IlStream.DisposeAsync();
33 | if (PdbStream != null) await PdbStream.DisposeAsync();
34 | if (UpdateHandlerInfoStream != null) await UpdateHandlerInfoStream.DisposeAsync();
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator/DiffyException.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System;
5 |
6 | namespace Microsoft.DotNet.HotReload.Utils.Generator;
7 |
8 | public class DiffyException : Exception {
9 | public int ExitStatus { get; }
10 |
11 | public DiffyException(int exitStatus) : base () {
12 | ExitStatus = exitStatus;
13 | }
14 |
15 | public DiffyException (string message, int exitStatus) : base (message) {
16 | ExitStatus = exitStatus;
17 | }
18 |
19 | public DiffyException (string message, Exception innerException, int exitStatus) : base (message, innerException) {
20 | ExitStatus = exitStatus;
21 | }
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator/DocResolver.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System.IO;
5 | using System.Collections.Generic;
6 | using System.Collections.Immutable;
7 | using System.Diagnostics.CodeAnalysis;
8 |
9 | using Microsoft.CodeAnalysis;
10 |
11 | namespace Microsoft.DotNet.HotReload.Utils.Generator;
12 |
13 | /// Maps a source file path to a DocumentId in a given Project
14 | public class DocResolver {
15 |
16 | private readonly Project project;
17 |
18 | private readonly ImmutableDictionary docMap;
19 | public DocResolver(Project project) {
20 | this.project = project;
21 | this.docMap = BuildDocMap (project.Documents);
22 | }
23 |
24 | public Project Project { get => project; }
25 |
26 | private static ImmutableDictionary BuildDocMap (IEnumerable docs)
27 | {
28 | var builder = ImmutableDictionary.CreateBuilder();
29 | foreach (var doc in docs) {
30 | var key = doc.FilePath;
31 | var value = doc.Id;
32 | var kvp = KeyValuePair.Create(key!, value);
33 | builder.Add(kvp);
34 | }
35 | return builder.ToImmutable();
36 | }
37 |
38 | public bool TryResolveDocumentId (string relativePath, [NotNullWhen(true)] out DocumentId id) {
39 | var absolutePath = Path.GetFullPath(relativePath);
40 | return docMap.TryGetValue(absolutePath, out id!);
41 | }
42 |
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator/EditAndContinueCapabilitiesParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text.RegularExpressions;
4 |
5 | namespace Microsoft.DotNet.HotReload.Utils.Generator;
6 |
7 | public static class EditAndContinueCapabilitiesParser {
8 |
9 | public readonly struct Token {
10 | public readonly string Value {get; init;}
11 | }
12 | static public readonly Regex capabilitiesTokenizer = new (@"^\s*(?:(\S+)\s+)*(\S+)?$", RegexOptions.CultureInvariant);
13 | public static IEnumerable Tokenize (string capabilities)
14 | {
15 | Match match = capabilitiesTokenizer.Match (capabilities);
16 | if (!match.Success)
17 | yield break;
18 | foreach (Capture c in match.Groups[1].Captures) {
19 | yield return new Token { Value = c.Value };
20 | }
21 | foreach (Capture c in match.Groups[2].Captures) {
22 | yield return new Token { Value = c.Value };
23 | }
24 | }
25 |
26 | public static IEnumerable Tokenize (IEnumerable capabilities)
27 | {
28 | foreach (var cap in capabilities) {
29 | foreach (var token in Tokenize(cap))
30 | yield return token;
31 | }
32 | }
33 |
34 | internal static (IEnumerable capabilities, IEnumerable unknowns) Parse (IEnumerable tokens)
35 | {
36 | List unknowns = new();
37 | List capabilities = new();
38 | foreach (var tok in tokens)
39 | {
40 | if (ParseToken (tok, out var cap)) {
41 | capabilities.Add (cap);
42 | } else {
43 | unknowns.Add (tok.Value);
44 | }
45 | }
46 | return (capabilities, unknowns);
47 | }
48 |
49 | internal static (IEnumerable capabilities, IEnumerable unknowns) Parse (string capabilities)
50 | {
51 | return Parse(Tokenize(capabilities));
52 | }
53 |
54 | internal static (IEnumerable capabilities, IEnumerable unknowns) Parse (IEnumerable capabilities)
55 | {
56 | return Parse(Tokenize(capabilities));
57 | }
58 |
59 | internal static bool ParseToken (Token token, out EnC.EditAndContinueCapabilities res) =>
60 | Enum.TryParse(token.Value, ignoreCase: true, out res);
61 |
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator/EnC/ChangeMaker.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System;
5 | using System.Runtime.Loader;
6 | using System.Reflection;
7 |
8 | namespace Microsoft.DotNet.HotReload.Utils.Generator.EnC;
9 |
10 | //
11 | // Inspired by https://github.com/dotnet/roslyn/issues/8962
12 | public class ChangeMaker {
13 | private const string codeAnalysisFeaturesAssemblyName = "Microsoft.CodeAnalysis.Features";
14 |
15 | private const string capabilitiesTypeName = "Microsoft.CodeAnalysis.EditAndContinue.EditAndContinueCapabilities";
16 |
17 | readonly record struct Reflected (Type Capabilities);
18 |
19 | private readonly Reflected _reflected;
20 |
21 | public Type EditAncContinueCapabilitiesType => _reflected.Capabilities;
22 |
23 | public ChangeMaker () {
24 | _reflected = ReflectionInit();
25 | }
26 | // Get all the Roslyn stuff we need
27 | private static Reflected ReflectionInit ()
28 | {
29 |
30 | var an = new AssemblyName(codeAnalysisFeaturesAssemblyName);
31 | var assm = AssemblyLoadContext.Default.LoadFromAssemblyName(an);
32 |
33 | var caps = assm.GetType (capabilitiesTypeName);
34 |
35 | if (caps == null) {
36 | throw new Exception ("Couldn't find EditAndContinueCapabilities type");
37 | }
38 |
39 | return new Reflected() { Capabilities = caps,
40 | };
41 | }
42 |
43 | /// Convert my EditAndContinueCapabilities enum value to
44 | /// [Microsoft.CodeAnalysis.Features]Microsoft.CodeAnalysis.EditAndContinue.EditAndContinueCapabilities
45 | public object ConvertCapabilities (EditAndContinueCapabilities myCaps)
46 | {
47 | int i = (int)myCaps;
48 | object theirCaps = Enum.ToObject(_reflected.Capabilities, i);
49 | return theirCaps;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator/EnC/EditAndContinueCapabilities.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Microsoft.DotNet.HotReload.Utils.Generator.EnC;
4 |
5 | /// Copied from https://github.com/dotnet/roslyn/blob/e8e6d30fe462edd48ce13f6438e91d26876c17bb/src/Features/Core/Portable/EditAndContinue/EditAndContinueCapabilities.cs
6 | /// Keep in sync
7 | ///
8 | /// The capabilities that the runtime has with respect to edit and continue
9 | ///
10 | [Flags]
11 | public enum EditAndContinueCapabilities
12 | {
13 | None = 0,
14 |
15 | ///
16 | /// Edit and continue is generally available with the set of capabilities that Mono 6, .NET Framework and .NET 5 have in common.
17 | ///
18 | Baseline = 1 << 0,
19 |
20 | ///
21 | /// Adding a static or instance method to an existing type.
22 | ///
23 | AddMethodToExistingType = 1 << 1,
24 |
25 | ///
26 | /// Adding a static field to an existing type.
27 | ///
28 | AddStaticFieldToExistingType = 1 << 2,
29 |
30 | ///
31 | /// Adding an instance field to an existing type.
32 | ///
33 | AddInstanceFieldToExistingType = 1 << 3,
34 |
35 | ///
36 | /// Creating a new type definition.
37 | ///
38 | NewTypeDefinition = 1 << 4,
39 | ///
40 | /// Adding, updating and deleting of custom attributes (as distinct from pseudo-custom attributes)
41 | ///
42 | ChangeCustomAttributes = 1 << 5,
43 |
44 | ///
45 | /// Whether the runtime supports updating the Param table, and hence related edits (eg parameter renames)
46 | ///
47 | UpdateParameters = 1 << 6,
48 |
49 | ///
50 | /// Adding a static or instance method, property or event to an existing type (without backing fields), such that the method and/or the type are generic.
51 | ///
52 | GenericAddMethodToExistingType = 1 << 7,
53 |
54 | ///
55 | /// Updating an existing static or instance method, property or event (without backing fields) that is generic and/or contained in a generic type.
56 | ///
57 | GenericUpdateMethod = 1 << 8,
58 |
59 | ///
60 | /// Adding a static or instance field to an existing generic type.
61 | ///
62 | GenericAddFieldToExistingType = 1 << 9,
63 |
64 | ///
65 | /// The runtime supports adding to InterfaceImpl table.
66 | ///
67 | AddExplicitInterfaceImplementation = 1 << 10,
68 |
69 | AddFieldRva = 1 << 11,
70 | }
71 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator/Microsoft.DotNet.HotReload.Utils.Generator.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | runtime; build; native; contentfiles; analyzers; buildtransitive
6 | all
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator/Plan/Change.cs:
--------------------------------------------------------------------------------
1 |
2 | // Licensed to the .NET Foundation under one or more agreements.
3 | // The .NET Foundation licenses this file to you under the MIT license.
4 |
5 | namespace Microsoft.DotNet.HotReload.Utils.Generator.Plan;
6 |
7 | /// A plan is just a collection of changes
8 | /// where each change is some identification of the base document and
9 | /// some representation of the update.
10 | ///
11 | /// For live coding, the collection will be an IAsyncEnumerable>,
12 | /// for a scripted plan it will be some parsed immutable list of changes.
13 | ///
14 | /// Initially the changes are just Change, but then DocResolve will
15 | /// change it to a Chamge.
16 | public readonly record struct Change(TDoc Document, TUpdate Update);
17 |
18 | public static class Change {
19 | public static Change Create(TDoc doc, TUpdate update) {
20 | return new Change(doc, update);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator/Runners/LiveRunner.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.IO;
7 | using System.Threading;
8 | using System.Threading.Tasks;
9 | using System.Runtime.CompilerServices;
10 |
11 | namespace Microsoft.DotNet.HotReload.Utils.Generator.Runners;
12 |
13 | /// Generate deltas by watching for changes to the source files of the project
14 | public class LiveRunner : Runner {
15 | public LiveRunner (Config config) : base (config) { }
16 |
17 | protected override Task PrepareToRun (CancellationToken ct = default) => Task.CompletedTask;
18 | public override IAsyncEnumerable SetupDeltas (BaselineArtifacts baselineArtifacts, CancellationToken ct = default)
19 | {
20 | return Livecoding (baselineArtifacts, config.LiveCodingWatchDir, config.LiveCodingWatchPattern, ct);
21 | }
22 |
23 | protected override bool PrepareCapabilitiesCore (out EnC.EditAndContinueCapabilities caps) {
24 | caps = EnC.EditAndContinueCapabilities.None;
25 | return false;
26 | }
27 | private static async IAsyncEnumerable Livecoding (BaselineArtifacts baselineArtifacts, string watchDir, string pattern, [EnumeratorCancellation] CancellationToken cancellationToken= default) {
28 | var last = DateTime.UtcNow;
29 | var interval = TimeSpan.FromMilliseconds(250); /* FIXME: make this configurable */
30 | var docResolver = baselineArtifacts.DocResolver;
31 | var baselineProjectId = baselineArtifacts.BaselineProjectId;
32 |
33 | using var fswgen = new Util.FSWGen (watchDir, pattern);
34 | await foreach (var fsevent in fswgen.Watch(cancellationToken).ConfigureAwait(false)) {
35 | if ((fsevent.ChangeType & WatcherChangeTypes.Changed) != 0) {
36 | var e = DateTime.UtcNow;
37 | Console.WriteLine($"change in {fsevent.FullPath} is a {fsevent.ChangeType} at {e}");
38 | if (e - last < interval) {
39 | Console.WriteLine($"too soon {e-last}");
40 | continue;
41 | }
42 | Console.WriteLine($"more than 250ms since last change");
43 | last = e;
44 | var fp = fsevent.FullPath;
45 | if (!docResolver.TryResolveDocumentId(fp, out var id)) {
46 | Console.WriteLine ($"ignoring change in {fp} which is not in {baselineProjectId}");
47 | continue;
48 | }
49 |
50 | yield return new Delta (Plan.Change.Create(id, fp));
51 | }
52 | }
53 | }
54 |
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/src/Microsoft.DotNet.HotReload.Utils.Generator/Script/Json/Parsing.cs:
--------------------------------------------------------------------------------
1 | // Licensed to the .NET Foundation under one or more agreements.
2 | // The .NET Foundation licenses this file to you under the MIT license.
3 |
4 | using System;
5 | using System.Collections.Generic;
6 | using System.IO;
7 | using System.Linq;
8 | using System.Text.Json;
9 | using System.Threading.Tasks;
10 |
11 | using CancellationToken = System.Threading.CancellationToken;
12 |
13 | namespace Microsoft.DotNet.HotReload.Utils.Generator.Script.Json;
14 |
15 | /// Read a diff script from a json file
16 | public class Parser {
17 |
18 | public readonly string Path;
19 | private readonly string _absDir;
20 | public Parser (string path) {
21 | Path = path;
22 | _absDir = System.IO.Path.GetDirectoryName(System.IO.Path.GetFullPath(path))!;
23 | }
24 | public async ValueTask