Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 106 additions & 18 deletions docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,36 @@

These instructions will get you ready to contribute to this project. If you just want to use Aspire, see [using-latest-daily.md](/docs/using-latest-daily.md).

## Contents

- [Prepare the machine](#prepare-the-machine)
- [Build the repo](#build-the-repo)
- [Using the `dotnet` CLI](#using-the-dotnet-cli)
- [Run TestShop](#run-testshop)
- [Using VS Code](#using-vs-code)
- [Building the VS Code extension](#building-the-vs-code-extension)
- [Using Visual Studio](#using-visual-studio)
- [Native build](#native-build)
- [View Dashboard](#view-dashboard)
- [Localization](#localization)
- [Testing](#testing)
- [Contributing with AI assistance](#contributing-with-ai-assistance)
- [Integrations](#integrations)
- [Generating local NuGet packages](#generating-local-nuget-packages)
- [Creating a local Aspire build with `localhive`](#creating-a-local-aspire-build-with-localhive)
- [Tips and known issues](#tips-and-known-issues)

## Prepare the machine

See [machine-requirements.md](/docs/machine-requirements.md).

## Build the repo

`./build.sh` (macOS and Linux) or `.\build.cmd` (Windows)
First run `./restore.sh` (macOS and Linux) or `.\restore.cmd` (Windows) to install the repo-local .NET SDK. Then build with `./build.sh` (macOS and Linux) or `.\build.cmd` (Windows).

## Using the `dotnet` CLI

In building and testing, never use the global `dotnet` copy. Use `./dotnet.sh` on Unix, `.\dotnet.cmd` on Windows.
After restore, `dotnet` commands run from this repo use the repo-local SDK because `global.json` includes `.dotnet` in the SDK search path. Use `./dotnet.sh` on Unix or `.\dotnet.cmd` on Windows when you need to force the repo-local SDK explicitly.

## Run TestShop

Expand All @@ -20,21 +40,41 @@ This will confirm that you're all set up.
In your shell or in VS Code:

```shell
# Replace "dotnet" with "./dotnet.sh" or ".\dotnet.cmd", as appropriate
dotnet restore playground/TestShop/TestShop.AppHost/TestShop.AppHost.csproj
dotnet run --project playground/TestShop/TestShop.AppHost/TestShop.AppHost.csproj
```

Or, if you are using Visual Studio:

1. Open `Aspire.slnx`
1. Set the Startup Project to be the `AppHost` project (it's under `\playground\TestShop`). Make sure the launch profile is set to "http".
1. <kbd>F5</kbd> to debug, or <kbd>Ctrl+F5</kbd> to launch without debugging.
2. Set the Startup Project to be the `AppHost` project (it's under `\playground\TestShop`). Make sure the launch profile is set to "http".
3. <kbd>F5</kbd> to debug, or <kbd>Ctrl+F5</kbd> to launch without debugging.

## Using VS Code

Make sure you [build the repo](#build-the-repo) from command line at least once. Then use `./start-code.sh` (macOS and Linux) or `.\start-code.cmd` to start VS Code.

## Building the VS Code extension

The Aspire VS Code extension lives under `extension/`. To build the extension through the repo build, make sure Node.js, yarn, and `vsce` are on your PATH, then run:

```bash
./build.sh --build-extension # macOS/Linux
.\build.cmd --build-extension # Windows
Comment thread
davidfowl marked this conversation as resolved.
Outdated
```

This runs the `extension/Extension.proj` build, installs extension dependencies with the checked-in `yarn.lock`, compiles the extension, and creates the VSIX artifacts under `artifacts/packages/Debug/vscode`.

For extension inner-loop development, you can work directly in the extension folder:

```bash
cd extension
yarn install --frozen-lockfile --non-interactive
yarn compile
```

Use `yarn watch` while editing TypeScript. When adding or changing user-facing extension text, keep the strings localized in both `extension/package.nls.json` and `extension/src/loc/strings.ts`. For VSIX signing and release packaging details, see [extension-signing.md](/docs/extension-signing.md).

## Using Visual Studio

Make sure you [build the repo](#build-the-repo) from command line at least once using `.\build.cmd` (Windows). Then use `.\startvs.cmd` to start Visual Studio with the correct environment setup.
Expand All @@ -43,9 +83,9 @@ Make sure you [build the repo](#build-the-repo) from command line at least once

The default build includes native builds for `Aspire.Cli` which produces Native AOT binaries for some platforms. These projects are in `eng/clipack/Aspire.Cli.*`.

By default it builds the cli native project for the current Runtime Identifier. A specific RIDs can be specified too by setting `$(TargetRids)` to a colon separated list like `/p:TargetRids=osx-x64:osx-arm64`.
By default it builds the CLI native project for the current Runtime Identifier. Specific RIDs can be specified by setting `$(TargetRids)` to a colon separated list like `/p:TargetRids=osx-x64:osx-arm64`.

Native build can be disabled with `/p:SkipNativeBuild=true`. And to only the native bits use `/p:SkipManagedBuild=true`.
Native build can be disabled with `/p:SkipNativeBuild=true`. To build only the native bits, use `/p:SkipManagedBuild=true`.

## View Dashboard

Expand All @@ -56,7 +96,7 @@ Otherwise if you are using the command line, when you have the Aspire app runnin
## Localization

If you are contributing to Aspire.Dashboard, please ensure that all strings are localized. If necessary,
create a new resx file under `Aspire.Dashboard\Resources`. To reference a string, ensure the `IStringLocalizer` for the resx file is
create a new resx file under `src/Aspire.Dashboard/Resources`. To reference a string, ensure the `IStringLocalizer` for the resx file is
injected. An example is below:

```xml
Expand All @@ -68,6 +108,8 @@ injected. An example is below:
Note that injection doesn't happen until a component's `OnInitialized`, so if you are referencing a string from codebehind, you must wait to do that
until `OnInitialized`.

The `*.Designer.cs` files are checked in with the matching `*.resx` files. If you add, remove, or rename resources, update the matching designer file too. If the project has an `xlf` directory, run `dotnet build /t:UpdateXlf <path-to-project.csproj>` to update localization files instead of editing `*.xlf` files manually.

## Testing

### Running Tests
Expand All @@ -76,40 +118,52 @@ To run tests, use the build script:

```bash
./build.sh --test # Linux/macOS
./build.cmd -test # Windows
.\build.cmd --test # Windows
```

### Quarantined Tests

Flaky tests may be marked as quarantined to prevent them from blocking CI while being investigated and fixed. See [quarantined-tests.md](/docs/quarantined-tests.md) for more information on working with quarantined tests.

When running tests locally or in automated environments, use the quarantine filter to exclude known flaky tests:
Long-running or resource-intensive tests may be marked as outerloop. See [outerloop-tests.md](/docs/outerloop-tests.md) for more information.

When running tests locally or in automated environments, use the test filters to exclude known flaky and outerloop tests:

```bash
# Replace "dotnet" with "./dotnet.sh" or ".\dotnet.cmd", as appropriate
dotnet test --filter-not-trait "quarantined=true"
dotnet test --no-launch-profile -- \
--filter-not-trait "quarantined=true" \
--filter-not-trait "outerloop=true"
```

### Testing Pull Request Changes

To test changes from a specific pull request locally, see [dogfooding-pull-requests.md](/docs/dogfooding-pull-requests.md) for instructions on installing Aspire CLI and NuGet packages built by that PR's CI run.

## Integrations (Formerly Components)
## Contributing with AI assistance

Aspire uses GitHub Copilot automatic code review on pull requests. We expect Copilot review comments to be reviewed and addressed before merging, either by making the requested change or by explaining why a suggested change is not needed.

The Aspire repository also includes custom Copilot skills that team members and automation may run on PRs, even when the PR author is not using an AI coding agent. Contributors can get a head start by running the key skills before requesting review:

- [`code-review`](/.github/skills/code-review/SKILL.md) reviews a PR for high-confidence problems only, such as bugs, security issues, correctness errors, performance regressions, missing boundary error handling, concurrency or resource issues, flaky test patterns, and repository convention violations. It avoids style nits and duplicate review comments.
- [`pr-testing`](/.github/skills/pr-testing/SKILL.md) installs the Aspire CLI and packages from a PR's dogfood build, verifies the installed CLI matches the PR head commit, analyzes changed areas, proposes targeted happy-path and negative test scenarios, runs the selected scenarios locally or in the repo container runner, captures evidence, and can produce a PR testing report.

Other repo skills can help with specialized work, but these two are the main skills the Aspire team uses to evaluate PR quality and dogfoodability.

## Integrations

Please check the [Aspire integrations contribution guidelines](/src/Components/README.md) if you intend to make contributions to a new or existing Aspire integration.

## Generating local NuGet packages

If you want to try local changes on a separate Aspire based project or solution it can be useful to generate the NuGet packages
in a local folder and use it as a package source.
If you only need package outputs, it can be useful to generate the NuGet packages in a local folder and use it as a package source from a separate Aspire-based project or solution. If you want to validate a complete locally-built Aspire product, including the CLI, templates, package hive, and bundle payload, use [`localhive`](#creating-a-local-aspire-build-with-localhive) instead.

To do so simply execute:
`./build.sh -pack` (macOS and Linux) or `.\build.cmd -pack` (Windows)
`./build.sh --pack` (macOS and Linux) or `.\build.cmd --pack` (Windows)

This will generate all the packages in the folder `./artifacts/packages/Debug/Shipping`. At this point from your solution folder run:

```shell
# Replace "dotnet" with "./dotnet.sh" or ".\dotnet.cmd", as appropriate
dotnet nuget add source my_aspire_folder/artifacts/packages/Debug/Shipping
```

Expand All @@ -119,6 +173,40 @@ Or edit the `NuGet.config` file and add this line to the `<packageSources>` list
<add key="aspire-dev" value="my_aspire_folder/artifacts/packages/Debug/Shipping" />
```

## Creating a local Aspire build with `localhive`

Use `localhive` when you want a fully usable Aspire product from your local source tree, not just a folder of NuGet packages. The script builds and packs the Aspire packages, creates an Aspire hive, builds the bundle payload, and installs a locally-built Aspire CLI. The CLI then discovers the hive as a channel, so commands like `aspire new`, `aspire add`, and `aspire init` use the packages produced by your custom build.

Prefer using an explicit output directory so your custom build stays isolated and does not overwrite the default Aspire install under `$HOME/.aspire`:

```bash
./localhive.sh -c Release -n my-feature -o ./artifacts/localhive/my-feature
export PATH="$PWD/artifacts/localhive/my-feature/bin:$PATH"
aspire --version
```

On Windows:

```powershell
.\localhive.ps1 -c Release -n my-feature -o .\artifacts\localhive\my-feature
$env:PATH = "$(Resolve-Path .\artifacts\localhive\my-feature\bin);$env:PATH"
aspire --version
```

To create a standalone portable build that can be copied to another machine, add a target RID and the archive flag:

```bash
./localhive.sh -c Release -n my-feature -o ./artifacts/localhive/linux-x64 -r linux-x64 --archive
```

On Windows:

```powershell
.\localhive.ps1 -c Release -n my-feature -o .\artifacts\localhive\win-x64 -r win-x64 -Archive
```

The archive contains the CLI, local package hive, and bundle payload needed for that build. After extracting it on the target machine, run the `aspire` binary from the extracted `bin` directory.

## Tips and known issues

Make sure you have started Docker before trying to run an Aspire app.
Expand All @@ -132,7 +220,7 @@ See the [tips and known issues](/docs/tips-and-known-issues.md) page.
When creating a new integration, package validation will automatically try to download a previous version of the package to ensure you didn't break compat. As a result you might get the following build error:

```shell
error NU1101: Unable to find package [NEW PACKAGE NAME]. No packages exist with this id in source(s): dotnet-eng, dotnet-public, dotnet9, dotnet9-transport. PackageSourceMapping is enabled, the following source(s) were not considered: dotnet-libraries.
error NU1101: Unable to find package [NEW PACKAGE NAME]. No packages exist with this id in source(s): dotnet-eng, dotnet-public, dotnet9, dotnet10, dotnet9-transport. PackageSourceMapping is enabled, the following source(s) were not considered: dotnet-libraries.
```

To prevent this the new package needs this line to be added to the `.csproj`:
Expand Down
Loading