ASP.NET Core Engineering and Build Infrastructure: Complete Directory Guide
The engineering and build infrastructure for ASP.NET Core resides primarily in the eng/ directory for build scripts and MSBuild targets, and .github/workflows/ for continuous integration pipeline definitions.
The dotnet/aspnetcore repository consolidates all build automation, toolset configuration, and CI orchestration within these two locations. Whether you are compiling the framework locally or investigating a failed GitHub Actions run, understanding the engineering and build infrastructure for ASP.NET Core requires familiarity with the shell scripts, PowerShell wrappers, and YAML pipelines that drive the development workflow.
Build Infrastructure Locations
The repository organizes its engineering systems into two distinct areas that handle different stages of the build lifecycle.
The eng/ Directory
The eng/ folder at the repository root contains the core build scripts and shared MSBuild logic used across all ASP.NET Core projects. This directory houses the primary entry points for local development:
- Shell scripts:
eng/build.sh(Linux/macOS) andeng/build.ps1(Windows) serve as the main entry points that parse command-line arguments and construct the final MSBuild command. - Common helpers:
eng/common/tools.shandeng/common/tools.ps1initialize the .NET Arcade toolset, configure logging, and manage binary log settings through functions likeInitializeToolset. - MSBuild targets: The
eng/targets/subdirectory contains specialized target files includingCSharp.Common.targets,Node.Common.targets, andHelix.targetsthat define build steps for managed code, Node.js assets, and test orchestration respectively. - Configuration: Files like
eng/Build.propsandeng/Version.Details.propsstore global build properties and dependency versioning information.
CI Pipeline Definitions
Continuous integration logic lives in .github/workflows/, where YAML workflow files orchestrate the same build scripts used locally. Key workflows include ci.yml for standard builds, validate-pat-pool.yml for validation tasks, and runtime-sync.yml for synchronization with the dotnet/runtime repository. These pipelines invoke eng/build.cmd or eng/build.sh with flags like --ci, --configuration Release, and --test to ensure parity between local and cloud builds.
Build Execution Flow
Understanding how the pieces connect helps diagnose build failures and extend the system with custom steps.
Entry-Point Script Execution
When you run ./eng/build.sh --configuration Release --ci --test on Linux or macOS, the script parses these options, sets environment variables such as ci=true, and constructs MSBuild arguments including -p:Test=true. The Windows equivalent, eng/build.ps1, performs the same argument processing for PowerShell environments. Both scripts ultimately invoke MSBuild with accumulated properties that control compilation, testing, and packaging.
Arcade Toolset Initialization
Before MSBuild executes, the entry scripts source their respective common tool files. eng/common/tools.sh (for Bash) and eng/common/tools.ps1 (for PowerShell) import the .NET Arcade SDK, ensuring the correct .NET SDK version is installed and available. This initialization step configures the binary log output paths and establishes the logging infrastructure used throughout the build.
MSBuild Target Resolution
The actual build work happens through targets defined in eng/targets/. For example, CSharp.Common.targets handles compilation for managed projects, while Node.Common.targets processes JavaScript and TypeScript assets. The Helix test harness is configured through Helix.targets, which coordinates distributed testing across multiple machines. All project files in the repository import these shared targets through properties defined in eng/Build.props, ensuring consistent build behavior across Blazor, MVC, SignalR, and other components.
Practical Build Commands
Local Development Builds
To compile the repository on your development machine, use the platform-specific wrapper scripts:
# Linux/macOS - Full build with tests
./eng/build.sh --configuration Release --ci --test
# Windows - Full build with tests
.\eng\build.cmd -c Release -ci -test
These commands trigger the full pipeline: Arcade initialization, compilation of all projects, and execution of the test suite using the Helix configuration when applicable.
GitHub Actions Integration
The CI pipelines in .github/workflows/ci.yml demonstrate how the same scripts run in the cloud:
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: Set up .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 8.x
- name: Build
run: .\eng\build.cmd -c Release -ci -test
This ensures that Pull Request validation uses identical build logic to local development, preventing "works on my machine" discrepancies.
Extending Build Targets
To add custom build steps, create new target files in eng/targets/ and import them through eng/Build.props or existing common property files:
<!-- eng/targets/MyCustom.targets -->
<Project>
<Target Name="MyCustomStep" AfterTargets="Build">
<Message Text="Running custom validation…" Importance="high" />
</Target>
</Project>
Projects automatically pick up these targets when they import the standard build properties, allowing you to inject steps like static analysis or asset generation into the standard build flow.
Summary
- The engineering and build infrastructure for ASP.NET Core is centralized in
eng/for scripts and MSBuild logic, and.github/workflows/for CI definitions. - Entry-point scripts (
eng/build.sh,eng/build.ps1,eng/build.cmd) handle argument parsing and invoke MSBuild with the correct properties. - Arcade toolset initialization occurs through
eng/common/tools.shandeng/common/tools.ps1, ensuring consistent SDK versions across environments. - MSBuild targets in
eng/targets/(such asCSharp.Common.targetsandHelix.targets) define the actual compilation and testing steps. - CI pipelines reuse the same entry-point scripts, guaranteeing that local builds and GitHub Actions builds execute identical logic.
Frequently Asked Questions
Where are the main build scripts located in the ASP.NET Core repository?
The primary build scripts are located in the eng/ directory at the repository root. You will find eng/build.sh for Linux and macOS, eng/build.ps1 for Windows PowerShell, and eng/build.cmd as a Windows command wrapper. These scripts serve as the single entry point for all local and CI builds.
What is the purpose of the eng/common/ directory?
The eng/common/ directory contains shared tooling scripts that initialize the .NET Arcade build system. Files like eng/common/tools.sh and eng/common/tools.ps1 handle SDK installation, binary logging configuration, and toolset restoration, ensuring that every build uses the exact same toolchain versions regardless of the host machine.
How does the ASP.NET Core CI system use these build scripts?
The GitHub Actions workflows in .github/workflows/ directly invoke the scripts from eng/. For example, ci.yml calls .\eng\build.cmd with specific flags like -ci and -test, executing the same MSBuild targets that developers run locally. This design ensures build reproducibility across local development machines and cloud runners.
Where should I add custom MSBuild targets for the entire repository?
Add custom targets as .targets files in the eng/targets/ directory, then import them through eng/Build.props or one of the existing common property files like eng/targets/CSharp.Common.targets. This makes your targets available to all projects that reference the standard build properties, allowing you to extend the build without modifying individual project files.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →