Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 2 additions & 0 deletions purview-build.json → .config/purview-build.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"$schema": "https://raw.githubusercontent.com/purview-dev/build/main/purview-build.schema.json",
"Build": {
"Solution": "src/Build.slnx",
"TestRoot": "src/tests",
Expand All @@ -18,6 +19,7 @@
"purview.build": [
"tools/**/Purview.Build.dll",
"tools/**/appsettings.json",
"tools/**/purview-build.schema.json",
"README.md",
"purview-logo-light.png"
]
Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This file is the primary instruction set for human and AI agents working in this
- `docs/wiki/Local-Development.md` — `just` recipes, `release-explain`, simulation, and the local rehearsal.
- `docs/wiki/Migration-*.md` — per-consumer migration guides.
- `README.md` — user-facing overview and minimal consumer setup.
- `purview-build.json` — this repository's own pipeline configuration.
- `.config/purview-build.json` — this repository's own pipeline configuration.
- `Justfile` — developer recipes (`just --list`).

## Build, test, lint
Expand Down Expand Up @@ -82,4 +82,4 @@ When changing release behaviour, grep the consuming repositories' `docs/wiki/Rel

- "The workflow does not publish to NuGet" — `release-mode: NuGet` runs `PublishNuGetModule` and pushes to `NuGet:FeedUrl`.
- "The shared pipeline does not mark the GitHub release with the prerelease flag" — `Release:MarkPrerelease` defaults to `true`.
- "…and attaches the package artifacts" — assets are attached only when the caller passes `upload-artifacts: true`, which no consumer currently does.
- "…and attaches the package artifacts" — assets are attached only when the caller passes `upload-artifacts: true`, which no consumer currently does.
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="$(RoslynVersion)" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="$(RoslynVersion)" />
<PackageVersion Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="$(RoslynVersion)" />
<PackageVersion Include="JsonSchema.Net" Version="9.4.0" />
<PackageVersion Include="Microsoft.Testing.Extensions.VSTestBridge" Version="2.5.0" />
<PackageVersion Include="ModularPipelines" Version="$(ModularPipelinesVersion)" />
<PackageVersion Include="ModularPipelines.DotNet" Version="$(ModularPipelinesVersion)" />
Expand Down
9 changes: 8 additions & 1 deletion Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ pipeline-dogfood *args:
dotnet tool install Purview.Build --tool-path "{{ dogfood_tool_path }}" \
--add-source "{{ dogfood_artifacts }}" --version "{{ current_version }}"
echo "Running the freshly packed tool against this repository..."
"{{ dogfood_tool_path }}/purview-build" {{ args }}
"{{ dogfood_tool_path }}/.config/purview-build" {{ args }}

# Explain the release decision for the working tree, without running any module or mutating anything
[group('Release')]
Expand Down Expand Up @@ -126,6 +126,13 @@ release-explain-golden:
--treenode-filter "/*/*/ReleaseExplainGoldenTests/*"
git --no-pager diff -- src/tests/fixtures/release-explain.golden.json

# Regenerate purview-build.schema.json from the settings types, then show what changed
[group('Build and Test')]
schema:
PURVIEW_BUILD_UPDATE_SCHEMA=1 dotnet test {{ golden_test_project }} -c Release \
--treenode-filter "/*/*/ConfigSchemaTests/Schema_MatchesTheGeneratedFile"
git --no-pager diff -- purview-build.schema.json

# Build the tool in Release so the scenario matrices can run the real binary
[private]
scenario-build:
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ Add `purview-build.json`. Everything is optional; defaults are baked into the to

The file is found at the repository root, or at `.config/`, `.build/`, `build/`, `.purview/` or `.github/` beneath it — first match wins, and any lower-priority file that also exists is reported as shadowed rather than merged. Select one explicitly with `--config <path>` or `PURVIEW_BUILD_CONFIG`. Relative paths inside the file always anchor to the repository root, wherever the file itself lives. Run `purview-build --help` to print the probe order and the path that resolved. See the [configuration reference](docs/wiki/Configuration-Reference.md#where-the-configuration-file-lives).

`purview-build.json` is validated against a JSON Schema as it loads, so an unknown key, a wrong type or an invalid enum value fails the run instead of being silently ignored. Add `"$schema": "https://raw.githubusercontent.com/purview-dev/build/main/purview-build.schema.json"` to the file for editor completion and validation; see [validation](docs/wiki/Configuration-Reference.md#validation).

The pipeline is dotnet-first but supports **Web** projects (Bun/JS/TS, e.g. the Astro/Starlight `purview-dev` portal) by setting `Build:ProjectType=Web`: restore/build/lint/test then run the repository's root `package.json` scripts (`bun install`, `bun run build`, `bun run format:check`/`bun run lint`, `bun run test`), and the pack step zips `Build:WebBuildOutput` (default `src/dist`) into `Build:ArtifactsFolder` for the GitHub release. Every Web command is overridable via the `Web*` settings below.

```json
Expand Down
2 changes: 2 additions & 0 deletions docs/wiki/Architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ The eligibility layer is the one worth being precise about. Before this split, t

`purview-build.json` is resolved before the pipeline is built: an explicit `--config` / `PURVIEW_BUILD_CONFIG` location, or the first hit from a documented probe list held as data. Relative paths inside the file always anchor to the repository root, never to the file's own directory, so moving the file changes nothing else. See [Configuration Reference](Configuration-Reference.md#where-the-configuration-file-lives).

The resolved file is parse-checked and then validated against a JSON Schema generated from the settings types, so a key the tool cannot bind fails the run instead of being silently ignored. The schema is embedded in the tool for validation and shipped alongside `appsettings.json` for editors; `just schema` regenerates it and the test suite fails when it drifts from the types. See [Validation](Configuration-Reference.md#validation).

Because configuration is composed before any module (and therefore any pipeline context) exists, the locality check that gates opt-in machine-local user configuration is a first-party helper rather than `ctx.IsRunningLocally()`.

## Module ordering
Expand Down
24 changes: 24 additions & 0 deletions docs/wiki/Configuration-Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,30 @@ It is also a reproducibility hazard — a machine-local file silently altering a
- **Lower precedence than the repository configuration**, higher than `appsettings.json`.
- When active, the resolved path is logged at `Information`.

## Validation

`purview-build.json` is validated against a JSON Schema when it is loaded, before any module runs. The schema is generated from the tool's settings types, so it describes exactly the keys the tool can bind, and it ships with the tool (embedded for validation, and alongside `appsettings.json` in the package).

- A key the tool cannot bind — a typo, or a setting that has been renamed — is an **error**, not a silently ignored line. So is a value of the wrong type and an enum value outside its allowed set.
- `$`-prefixed keys are reserved for metadata and ignored, so `$schema` and `$comment` are accepted.
- Property names use the canonical casing shown in this reference (`"Build"`, not `"build"`).
- `//` comments and trailing commas are tolerated, as they are by the configuration binder.

A failure names the file and every offending key, then exits 1 — exactly as malformed JSON does.

### Editor support

Add the schema to the file and editors (VS Code, Rider, Visual Studio) complete keys and flag unknown ones as you type:

```json
{
"$schema": "https://raw.githubusercontent.com/purview-dev/build/main/purview-build.schema.json",
"Build": { "Solution": "src/MyProduct.slnx" }
}
```

The schema is generated from the settings types: `just schema` regenerates it after a deliberate settings change, and the test suite fails when the committed file drifts from the types.

## Precedence

```text
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "purview-build",
"version": "0.4.0",
"version": "0.5.1",
"private": true,
"homepage": "https://purview.dev/projects/build/",
"bugs": {
Expand Down
Loading
Loading