# ASP.NET Core Engineering and Build Infrastructure: Complete Directory Guide

> Discover the ASP.NET Core engineering and build infrastructure. Find build scripts in eng and CI pipelines in .github/workflows for the aspnetcore repo. Understand the project's core.

- Repository: [.NET Platform/aspnetcore](https://github.com/dotnet/aspnetcore)
- Tags: internals
- Published: 2026-08-01

---

**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`](https://github.com/dotnet/aspnetcore/blob/main/eng/build.sh) (Linux/macOS) and `eng/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.sh`](https://github.com/dotnet/aspnetcore/blob/main/eng/common/tools.sh) and `eng/common/tools.ps1` initialize the .NET Arcade toolset, configure logging, and manage binary log settings through functions like `InitializeToolset`.
- **MSBuild targets**: The `eng/targets/` subdirectory contains specialized target files including `CSharp.Common.targets`, `Node.Common.targets`, and `Helix.targets` that define build steps for managed code, Node.js assets, and test orchestration respectively.
- **Configuration**: Files like `eng/Build.props` and `eng/Version.Details.props` store 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`](https://github.com/dotnet/aspnetcore/blob/main/ci.yml) for standard builds, [`validate-pat-pool.yml`](https://github.com/dotnet/aspnetcore/blob/main/validate-pat-pool.yml) for validation tasks, and [`runtime-sync.yml`](https://github.com/dotnet/aspnetcore/blob/main/runtime-sync.yml) for synchronization with the dotnet/runtime repository. These pipelines invoke `eng/build.cmd` or [`eng/build.sh`](https://github.com/dotnet/aspnetcore/blob/main/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`](https://github.com/dotnet/aspnetcore/blob/main/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:

```bash

# Linux/macOS - Full build with tests

./eng/build.sh --configuration Release --ci --test

```

```powershell

# 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`](https://github.com/dotnet/aspnetcore/blob/main/.github/workflows/ci.yml) demonstrate how the same scripts run in the cloud:

```yaml
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:

```xml
<!-- 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`](https://github.com/dotnet/aspnetcore/blob/main/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.sh`](https://github.com/dotnet/aspnetcore/blob/main/eng/common/tools.sh) and `eng/common/tools.ps1`, ensuring consistent SDK versions across environments.
- **MSBuild targets** in `eng/targets/` (such as `CSharp.Common.targets` and `Helix.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`](https://github.com/dotnet/aspnetcore/blob/main/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`](https://github.com/dotnet/aspnetcore/blob/main/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`](https://github.com/dotnet/aspnetcore/blob/main/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.