Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
6909be3
Adopt Nx + @nx/dotnet for affected/cache; replace runtime sample buil…
Redth Apr 30, 2026
bc0797f
Remove redundant project.json files
Redth Apr 30, 2026
1c45276
Replace integration tests project.json with per-platform csprojs
Redth Apr 30, 2026
cd7e01c
Add Nx shadow build workflow
Redth Apr 30, 2026
3cb3981
Self-declared OS buildability via NxBuildableOn + Nx tags plugin
Redth Apr 30, 2026
867ed91
Trial DotnetNx (Maui.BuildHelpers) replacement for Nx plumbing
Redth May 1, 2026
3a139ad
Replace nx wrappers and Nx workflows with DotnetNx composite actions
Redth May 1, 2026
e4d7cd8
Drop vendored @redth/dotnet-nx tarball; install from GitHub Packages
Redth May 1, 2026
cfc16cd
Adopt Maui.BuildHelpers @v0.1 actions and published GH Packages feeds
Redth May 1, 2026
71f2159
Bump Maui.BuildHelpers DotnetNx actions to @v0.2
Redth May 1, 2026
a5a6413
Delegate npm GH Packages auth to actions/setup-node
Redth May 1, 2026
17dd448
Adopt Maui.BuildHelpers v0.3: affected-matrix, setup-cache, doctor
Redth May 1, 2026
b5b4a95
Drop auth-gh-packages composite for stock setup-node + NuGet env-var …
Redth May 1, 2026
cc8e72e
Make nxdn discoverable inside android-emulator-runner script
Redth May 1, 2026
3b93c6d
Switch Android lane to maui-containers/maui-emulator-linux
Redth May 1, 2026
1cd2cba
Consolidate product CI into a single Nx-driven workflow
Redth May 1, 2026
b38ebd9
Use glob pattern instead of integration-test block list
Redth May 1, 2026
48409bb
Tighten emulator-container wait logic in Android lane
Redth May 1, 2026
aca43d6
Update docs for Nx-driven consolidated CI
Redth May 1, 2026
8bd4aca
Switch to tag-based project selection (Maui.BuildHelpers v0.4)
Redth May 1, 2026
438ea98
Merge remote-tracking branch 'origin/main' into redth/monorepo-build-…
Redth May 4, 2026
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
13 changes: 13 additions & 0 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnetnx.tool": {
"version": "0.1.0-alpha.1",
"commands": [
"nxdn"
],
"rollForward": false
}
}
}
100 changes: 47 additions & 53 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ You can also pass a pre-built binary: `./eng/smoke-tests/apple-cli-smoke-test.sh

## CI/CD — New Product Checklist

When adding a new product to this repo you **must** set up two CI surfaces: a GitHub Actions workflow for PR validation and a build job + publish stage in the Azure DevOps official pipeline for signing and NuGet.org publishing.
When adding a new product to this repo you only need to wire it into the **Azure DevOps official pipeline** for signing and NuGet.org publishing. PR validation on GitHub Actions is handled by the consolidated `.github/workflows/ci.yml`, which discovers projects via Nx.

You **must** also provide documentation:

Expand All @@ -192,62 +192,56 @@ You **must** also provide documentation:

### Step 1: GitHub Actions PR / Push Workflow

Create `.github/workflows/ci-{product}.yml`. Use the template below — replace every `{Product}` (PascalCase) and `{product}` (lowercase) placeholder.
**Nothing to create.** `.github/workflows/ci.yml` runs Nx's `affected-matrix` action against every project in `MauiLabs.slnx`. New products are picked up automatically.

```yaml
name: CI - {Product}

on:
push:
branches: [main]
paths:
- 'src/{Product}/**'
# CUSTOMIZE: add paths for cross-product ProjectReference dependencies, e.g.:
# - 'src/OtherProduct/SharedLib/**'
- 'eng/**'
- 'Directory.Build.props'
- 'Directory.Build.targets'
- 'Directory.Packages.props'
- 'global.json'
- 'NuGet.config'
pull_request:
# IMPORTANT: 'edited' is required — without it CI does not run when
# GitHub auto-retargets a PR after a stacked branch merges.
types: [opened, synchronize, reopened, edited]
branches: [main]
paths:
- 'src/{Product}/**'
# CUSTOMIZE: add paths for cross-product ProjectReference dependencies, e.g.:
# - 'src/OtherProduct/SharedLib/**'
- 'eng/**'
- 'Directory.Build.props'
- 'Directory.Build.targets'
- 'Directory.Packages.props'
- 'global.json'
- 'NuGet.config'

jobs:
build:
uses: ./.github/workflows/_build.yml
with:
project-path: src/{Product}/{Product}.slnf # CUSTOMIZE: path to solution filter (.slnf or .slnx)
project-name: {product} # CUSTOMIZE: lowercase, used in artifact names
run-tests: true
pack: true
install-workloads: true # CUSTOMIZE: set false for net10.0-only products (no MAUI TFMs)
# os: '["macos-latest", "windows-latest"]' # CUSTOMIZE: default is macOS + Windows
# native-deps: 'sudo apt-get install ...' # CUSTOMIZE: if Linux-only with native libs
To control which OS legs build the new product, set `<NxBuildableOn>` in the product's `Directory.Build.props` (or per-csproj where finer-grained):

```xml
<PropertyGroup>
<!-- One or more of: linux, macos, windows. Omit for all three. -->
<NxBuildableOn>macos,windows</NxBuildableOn>
</PropertyGroup>
```

The `@redth/dotnet-nx` plugin emits `os:linux` / `os:macos` / `os:windows` Nx tags from this property; the matrix leg for an OS only runs if at least one affected project carries that tag. Nx's `affected` graph (project + dependency edges + workspace files) replaces the old hand-maintained `paths:` filters — there is **nothing to keep in sync** when you add cross-product `ProjectReference`s.

### Declaring arbitrary Nx tags via `<NxTags>` / `<NxTag>`

Set arbitrary `tag:value` metadata on a project to drive workflow selection without hard-coding project names:

```xml
<PropertyGroup>
<!-- Semicolon/comma/whitespace-separated. -->
<NxTags>type:integration-test;device:android;requires:emulator</NxTags>
</PropertyGroup>

<ItemGroup>
<!-- Or use NxTag items when you want conditions. -->
<NxTag Include="device:android" Condition="'$(TargetFramework)' == 'net10.0-android'" />
</ItemGroup>
```

#### `_build.yml` inputs reference
Workflows then select with `--projects=tag:<key>:<value>` and exclude with `--exclude=tag:<key>:<value>`. Examples in this repo:

- `ci.yml` excludes integration tests and standalone-CI products via `AFFECTED_EXCLUDES: 'tag:type:integration-test,tag:type:standalone-ci'`.
- `devflow-integration.yml` runs each platform variant via `nxdn nx -- run-many --projects=tag:device:<platform> -t test`.

Inferred tags (no MSBuild change required): `os:<host>`, `tfm:<tfm>`, `tfm-platform:<platform>`, `type:test`/`type:packable`/`type:tool`/`type:nuget`, `package-id:<id>`, `sdk:maui`. See the [Maui.BuildHelpers DotnetNx README](https://github.com/Redth/Maui.BuildHelpers/tree/main/DotnetNx#nx-tags-from-msbuild) for the full list.

If a product needs special build prerequisites (native apt deps, additional workloads, extra SDKs) on a specific OS leg, edit `ci.yml` directly. The `build` job already conditionalizes Linux apt deps and Windows/macOS Android SDK installs on `osTag`.

### Step 1b: Products with their own workflow (standalone-CI)

Some products can't fit the consolidated `ci.yml` matrix — for example, EssentialsAI's macOS→Windows Swift xcframework artifact handoff, or MacOS-AppKit's pinned Xcode version. These keep their own `.github/workflows/ci-{product}.yml` calling the reusable `_build.yml`. Tag the product so `ci.yml` skips it:

```xml
<!-- in src/{Product}/Directory.Build.props -->
<PropertyGroup>
<NxTags>type:standalone-ci</NxTags>
</PropertyGroup>
```

| Input | Default | When to change |
|-------|---------|---------------|
| `install-workloads` | `true` | Set `false` if the product targets only `net10.0` (no MAUI TFMs) |
| `os` | `["macos-latest", "windows-latest"]` | Override to `["ubuntu-24.04"]` for Linux-only products |
| `native-deps` | *(empty)* | Provide an `apt-get install` command if the product needs native libraries (e.g., GTK4) |
| `pack` | `false` | Set `true` if the product produces NuGet packages |
| `run-tests` | `true` | Set `false` only if there are no tests yet |
Existing standalone-CI products: `src/AI` (EssentialsAI), `src/AppProjectReference`, `platforms/MacOS`, `platforms/Windows.WPF`.

### Step 2: Azure DevOps Official Pipeline

Expand Down
9 changes: 6 additions & 3 deletions .github/instructions/testing.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,13 @@ dotnet test --logger "console;verbosity=detailed"

## CI Matrix

Tests run on **macOS and Windows** in CI (`.github/workflows/_build.yml`):
Tests run via the consolidated **Nx-driven** workflow `.github/workflows/ci.yml`. The `affected` job computes per-OS project lists from `<NxBuildableOn>` tags; the `build` job fans out across `linux` / `macos` / `windows` legs that have affected work, invoking `nx affected -t test` (via `Redth/Maui.BuildHelpers/DotnetNx/actions/run-affected@v0.3`).

- **macOS**: `./eng/common/cibuild.sh --configuration Release --prepareMachine --projects src/DevFlow/DevFlow.slnf`
- **Windows**: `eng\common\cibuild.cmd -configuration Release -prepareMachine -projects src/DevFlow/DevFlow.slnf`
To run the same selective test pass locally:

```bash
./nx affected -t test
```

Test results are uploaded as artifacts: `artifacts/TestResults/**/*.xml`

Expand Down
40 changes: 0 additions & 40 deletions .github/workflows/ci-cli.yml

This file was deleted.

34 changes: 0 additions & 34 deletions .github/workflows/ci-devflow.yml

This file was deleted.

44 changes: 0 additions & 44 deletions .github/workflows/ci-linux-gtk4.yml

This file was deleted.

Loading
Loading