diff --git a/.agents/skills/azldev-add-component/SKILL.md b/.agents/skills/azldev-add-component/SKILL.md index c9174cbd324..6d100cb1445 100644 --- a/.agents/skills/azldev-add-component/SKILL.md +++ b/.agents/skills/azldev-add-component/SKILL.md @@ -90,4 +90,4 @@ the rendered output before committing. Then re-render, stage `Release:` reflect it. See the `azldev-update-component` skill for the complete finalization workflow. -Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.3.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.4.0`. diff --git a/.agents/skills/azldev-build-component/SKILL.md b/.agents/skills/azldev-build-component/SKILL.md index 1f98b133391..a7a6e2d0288 100644 --- a/.agents/skills/azldev-build-component/SKILL.md +++ b/.agents/skills/azldev-build-component/SKILL.md @@ -57,4 +57,4 @@ Finalize with `azldev comp update -p ` before opening a PR (see the Per-component build tweaks (`build.defines`, `build.without`) live in the `.comp.toml` — see the `azldev-comp-toml` skill. -Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.3.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.4.0`. diff --git a/.agents/skills/azldev-comp-toml/SKILL.md b/.agents/skills/azldev-comp-toml/SKILL.md index bc1c888a416..2ea091cfb3b 100644 --- a/.agents/skills/azldev-comp-toml/SKILL.md +++ b/.agents/skills/azldev-comp-toml/SKILL.md @@ -138,4 +138,4 @@ Add a TOML comment explaining *why* a non-obvious field is set (a version pin, a workaround), and link the upstream commit or bug when the change is based on one. For overlays, use the overlay `metadata` table instead (see the `azldev-overlays` skill). -Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.3.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.4.0`. diff --git a/.agents/skills/azldev-image/SKILL.md b/.agents/skills/azldev-image/SKILL.md index c1ab0882ec2..399bfc4841f 100644 --- a/.agents/skills/azldev-image/SKILL.md +++ b/.agents/skills/azldev-image/SKILL.md @@ -23,7 +23,9 @@ Images are selected by their **name as a positional argument** (not `-p`). | Customize a pre-built image | `azldev image customize` | `azldev image build` takes `--local-repo` / `--remote-repo` to add package sources and -`--arch` to target an architecture. `azldev image boot` takes a built image name, or an +`--arch` to target an architecture. When the selected distro version defines +`kiwi-config-override`, azldev passes it to KIWI with `--config`. These top-level +overrides have highest precedence. `azldev image boot` takes a built image name, or an explicit `--image-path` / `--iso`. Confirm current flags with `azldev image --help` (there are more subcommands, e.g. `inject-files`). @@ -57,4 +59,4 @@ The `.kiwi` file is upstream KIWI NG XML — azldev does not own its schema. It image type (container vs. VM), package lists, repositories, and boot configuration. See the [KIWI NG documentation](https://osinside.github.io/kiwi/) for the format and elements. -Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.3.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.4.0`. diff --git a/.agents/skills/azldev-mock/SKILL.md b/.agents/skills/azldev-mock/SKILL.md index ad4caab52a5..a54a7d6b134 100644 --- a/.agents/skills/azldev-mock/SKILL.md +++ b/.agents/skills/azldev-mock/SKILL.md @@ -89,4 +89,4 @@ react to output between commands. - **One mock session per terminal.** Running `azldev adv mock shell` while a terminal is already inside a mock shell fails — run `exit` first. -Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.3.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.4.0`. diff --git a/.agents/skills/azldev-overlay-metadata/SKILL.md b/.agents/skills/azldev-overlay-metadata/SKILL.md new file mode 100644 index 00000000000..6c1c54f9dce --- /dev/null +++ b/.agents/skills/azldev-overlay-metadata/SKILL.md @@ -0,0 +1,178 @@ +--- +name: azldev-overlay-metadata +description: "Read this before adding or reviewing an overlay `metadata` table; do not guess the category or upstream status from memory. Explains the overlay metadata schema that documents why an overlay exists and when it can be dropped, covering the required category and upstream-status values, commit/bug URL references, and the per-file overlay metadata block. Triggers include overlay metadata, category, upstream-status, upstream-backport, azl-pruning, azl-branding-policy, needs-upstream-hook, why overlay." +--- + +# Overlay metadata — pick a category and annotate + +Every overlay documents *why* it exists (`description`, **required**) and *what class +of change* it is (`metadata`). When a `[metadata]` block is present it **requires** both +a `category` and an `upstream-status`. This skill covers how to pick the right values, +attach provenance, and write the TOML at the moment you author or review an overlay. + +Metadata is **pure documentation** — it never changes the rendered spec and is excluded +from component fingerprints, so adding or editing it never invalidates build caches or +locks. For overlay *types* and the render-and-inspect loop, read the `azldev-overlays` +skill; this skill is only about the `metadata` table. + +## One `[metadata]` block = one logical change + +A single logical change (a CVE backport, a feature disablement, a Fedora cherry-pick) +may need **several overlays** — e.g. remove a sub-package *and* drop the configure flags +that went with it. The per-file overlay format (`overlay-files`) captures exactly this: +one top-level `[metadata]` table and one or more `[[overlays]]` entries it applies to. +Per-overlay `metadata` inside an overlay file is **rejected** — the file-level block is +the single source of truth. + +So: if you find yourself stamping the *same* metadata on several inline overlays, that is +a signal they are one logical change — move them into a single overlay file with one +`[metadata]` block. + +## When to add metadata + +- **New overlay** (any inline `[[components..overlays]]` block or `[[overlays]]` + entry in an overlay file): add `metadata` with both a `category` and an `upstream-status`. +- **An overlay's intent changed** (e.g. a prune becomes a backport): update the `category` + and `upstream-status` to match the new intent. + +## Step 1 — Pick the category + +Choose exactly one `category` from this closed set (authoritative — matches +`metadata.category` in the schema): + +| `category` | Use when the overlay… | Extra required/expected fields | +|------------|-----------------------|--------------------------------| +| `upstream-backport` | Backports a fix from an upstream source (Fedora dist-git or the component's OSS project) that AZL will inherit once it bumps past the fix. Self-resolves on version bump. | `commits` (≥1 upstream commit URL) — **required**. `upstream-status` must be `upstreamed` or `upstreamable`. | +| `azl-pruning` | Removes content for AZL: unshipped deps, unneeded features, sub-packages, or files. | — | +| `azl-compatibility` | Adapts a component to *how Azure Linux is built and shipped* — build tooling, buildroot, infrastructure, runtime ecosystem — when upstream builds/behaves incorrectly for AZL-specific reasons that are **not** branding, a missing dependency, architecture, or tests (e.g. `azldev` downloader quirks, `rpmdiff` reproducibility, buildroot gaps, Fedora version-skew). | — | +| `azl-temp-workaround` | Temporary workaround explicitly intended to be dropped once an upstream or environmental fix lands. Covers a dependency not yet imported into AZL (or unavailable on a target) **and** any other transient workaround waiting on an external change. | — | +| `azl-branding-policy` | Fedora→Azure Linux identity differences: intentional name/path/vendor conventions **and** spec fixes for upstream code that hard-codes Fedora identity strings (e.g. `_vendor=redhat`, `-redhat-linux[-gnu]` triples, `redhat-linux-build` dirs). Also covers repointing a `Source`/`URL` tag from a Fedora mirror to an Azure Linux one (e.g. `azurelinux-rpm-config`, `golang`). | — | +| `azl-disable-flaky-tests` | Skips tests that fail intermittently / due to environmental flakiness, not a real component bug. | — | +| `azl-disable-unsupported-tests` | Skips tests that cannot meaningfully run in AZL's build/runtime env (need network, root, or unavailable hardware in mock). | — | +| `azl-security-compliance` | Makes FIPS or crypto-policy changes. | — | +| `azl-release-management` | Adjusts release-tag / changelog mechanics. | — | +| `azl-platform-adaptation` | Makes architecture-specific adjustments. | — | + +### Disambiguation tips + +- **Backport vs. compatibility/pruning:** if the exact change exists as a commit in Fedora + dist-git or the upstream project, it is `upstream-backport` (supply `commits`, with + `upstream-status` of `upstreamed` or `upstreamable`). Use an `azl-*` category only when + the change is AZL-specific with no upstream equivalent. +- **Pruning vs. temp-workaround:** removing a dependency we deliberately don't ship is + `azl-pruning`; temporarily working around a dep that *should* exist but hasn't been + imported yet (or any transient workaround waiting on an external fix) is + `azl-temp-workaround`. +- **Flaky vs. unsupported tests:** flaky = the test *could* pass but is intermittent; + unsupported = the test *cannot* run in mock (network/root/hardware). Require evidence of + the limitation before choosing `azl-disable-unsupported-tests`; investigate or ask when + the failure mode is unclear. +- **Compatibility vs. platform-adaptation:** reserve `azl-platform-adaptation` for + architecture-specific (`%ifarch`-style) changes; general toolchain/mock/build-env fixes + are `azl-compatibility`. + +## Step 2 — Set `upstream-status` + +Required whenever `[metadata]` is present. It classifies the overlay's relationship to +upstream — "why are we carrying this?" and "what would it take to drop it?" Pick exactly one: + +| Value | Meaning | +|-------|---------| +| `upstreamed` | Already in Fedora; carried only until AZL bumps past it. | +| `upstreamable` | The patch we carry is itself upstream-shaped (or already in the OSS project but not in Fedora yet); the same diff could be sent upstream and plausibly accepted. Link the upstream PR when you can. | +| `needs-upstream-hook` | AZL-specific change that upstream wouldn't take as-is, but upstream could add a `bcond`/`%if`/config knob so we could drop the overlay. | +| `inapplicable` | Permanent AZL-only deviation with no upstream story (branding, deliberate pruning, enterprise policy). | +| `unknown` | Not yet assessed. Prefer a definite value; reviewers should push back on `unknown` before approving. | + +On an `upstream-backport` overlay only `upstreamed` and `upstreamable` are allowed — any +other value is a validation error. + +**`upstreamable` vs. `needs-upstream-hook`:** `upstreamable` means the patch we carry is +itself upstream-shaped (send the same diff upstream); `needs-upstream-hook` means the +change is AZL-specific and would *not* be accepted as-is, but upstream could add a hook +that makes patching unnecessary. + +## Step 3 — Add provenance (`commits`, `bugs`) + +- `commits` — list of `{ url = "..." }` tables pointing at upstream commits (absolute + http(s) URLs). **Required for `upstream-backport`**; optional elsewhere but valuable + whenever a change traces to a specific commit. For one logical change spanning several + commits, list them all. Verify each SHA actually exists upstream before recording it — a + discovered-and-verified URL is not "inventing" metadata; an unverified guess is. +- `bugs` — list of `{ url = "..." }` tables referencing tracker entries. Never fabricate one. + +## Step 4 — Write the metadata (TOML forms) + +**Prefer the per-file layout (an overlay file loaded via `overlay-files`) for all new +work — even a component with a single overlay.** It keeps `category`/`commits`/`bugs` on +their own lines (no inline-table one-line limit) and means a change never has to be +reshuffled when it grows a second overlay. One top-level `[metadata]` table applies to +every `[[overlays]]` entry in the file. + +Multi-overlay change (one logical change, several overlays): + +```toml +# One logical change: drop the devel sub-package AZL does not ship. +[metadata] +category = "azl-pruning" +upstream-status = "inapplicable" + +[[overlays]] +description = "Remove the devel sub-package — AZL ships no -devel for this component" +type = "spec-remove-subpackage" +package = "devel" + +[[overlays]] +description = "Drop the BuildRequires only the devel sub-package needed" +type = "spec-remove-tag" +tag = "BuildRequires" +value = "some-devel-only-dep" +``` + +### Inline forms + +Use inline `metadata` only when the component is already inline and you are not +restructuring it. A single-line inline table must fit on one line (no lists), so it is +limited to one or two scalar fields: + +```toml +[[components.rpm.overlays]] +description = "Customize RPM vendor to Azure Linux" +type = "spec-search-replace" +regex = "RPM_VENDOR=redhat" +replacement = "RPM_VENDOR=azurelinux" +metadata = { category = "azl-branding-policy", upstream-status = "inapplicable" } +``` + +Use the sub-table form whenever you need a list (`commits`, `bugs`) or more than a couple +of fields: + +```toml +[[components.xclock.overlays]] +description = "Pass --force to autoreconf so the build survives newer autotools" +type = "spec-search-replace" +regex = "autoreconf -i" +replacement = "autoreconf -fi" + +[components.xclock.overlays.metadata] +category = "upstream-backport" +upstream-status = "upstreamed" +commits = [{ url = "https://src.fedoraproject.org/rpms/xclock/c/1e407488" }] +``` + +## Step 5 — Verify + +Adding or editing metadata must be a no-op on the rendered spec. Re-render and confirm +there is no diff: + +```sh +azldev comp render -p +git diff specs/ +``` + +If you also moved overlays into files, prove the apply order was preserved with +`azldev comp diff-sources -p ` before and after — any difference means an overlay +changed or the sequence shifted. Metadata-only edits need no rebuild or lock refresh; if +you also changed an overlay's behavior, finalize with the `azldev-update-component` skill. + +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.4.0`. diff --git a/.agents/skills/azldev-overlays/SKILL.md b/.agents/skills/azldev-overlays/SKILL.md index 74381c85004..70c4a243648 100644 --- a/.agents/skills/azldev-overlays/SKILL.md +++ b/.agents/skills/azldev-overlays/SKILL.md @@ -148,6 +148,9 @@ It also requires `upstream-status`: `upstreamed`, `upstreamable`, overlays share one provenance, put them in a per-file overlay document (`overlay-files`) with a single file-level `[metadata]`. +For how to choose the right `category` and `upstream-status`, disambiguation tips, and +the TOML forms, read the `azldev-overlay-metadata` skill. + ## Full reference The tables above are the working subset. For the exhaustive field rules, metadata @@ -155,4 +158,4 @@ constraints, and the per-file overlay format, generate the machine-readable sche with `azldev config generate-schema` (see the `ComponentOverlay` definition), or read azldev's overlays configuration reference. -Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.3.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.4.0`. diff --git a/.agents/skills/azldev-remove-component/SKILL.md b/.agents/skills/azldev-remove-component/SKILL.md index dd33ba64aa4..120866d0a5e 100644 --- a/.agents/skills/azldev-remove-component/SKILL.md +++ b/.agents/skills/azldev-remove-component/SKILL.md @@ -78,4 +78,4 @@ and test the affected outputs according to the repository's normal validation po component you are dropping, remove it in the same change to keep the tree consistent. -Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.3.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.4.0`. diff --git a/.agents/skills/azldev-update-component/SKILL.md b/.agents/skills/azldev-update-component/SKILL.md index c7dfd668ccb..27051d4b535 100644 --- a/.agents/skills/azldev-update-component/SKILL.md +++ b/.agents/skills/azldev-update-component/SKILL.md @@ -80,4 +80,4 @@ post-render amend: 5. `azldev comp render -p ` — `%changelog` / `Release:` now reflect the new lock. 6. `git add specs///`, then `git commit --amend --no-edit` so the source change and rendered output land together. -Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.3.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.4.0`. diff --git a/.agents/skills/azldev/SKILL.md b/.agents/skills/azldev/SKILL.md index 1a567f4e021..7e023ab87dc 100644 --- a/.agents/skills/azldev/SKILL.md +++ b/.agents/skills/azldev/SKILL.md @@ -69,6 +69,7 @@ mock helpers; it is intentionally omitted from normal help. - Add a new component — read the `azldev-add-component` skill. - Edit or review a component's TOML — read the `azldev-comp-toml` skill. - Add or change overlays — read the `azldev-overlays` skill. +- Annotate an overlay's intent (category, upstream status, provenance) — read the `azldev-overlay-metadata` skill. - Build, iterate, and debug a component — read the `azldev-build-component` skill. - Build, boot, and register images — read the `azldev-image` skill. - Refresh a lock and finalize for a PR — read the `azldev-update-component` skill. @@ -83,4 +84,4 @@ mock helpers; it is intentionally omitted from normal help. the whole component config, and lock / rendered-spec CI checks run on committed state. - **Every overlay needs a `description`** explaining why the change is needed. -Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.3.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.4.0`. diff --git a/.azldev-version b/.azldev-version index 5373d6700cc..d979e4288c8 100644 --- a/.azldev-version +++ b/.azldev-version @@ -1 +1 @@ -261ae7471a4421377d557c51aaae70add8bc9caf +faaa0f4e6f4a59b3ccdd723be0802520a67db9c8 diff --git a/.github/instructions/azldev.instructions.md b/.github/instructions/azldev.instructions.md index aaa3b290fe9..3213f20aca2 100644 --- a/.github/instructions/azldev.instructions.md +++ b/.github/instructions/azldev.instructions.md @@ -14,4 +14,4 @@ version-matched source for this file type. - You MUST read the `azldev` skill for how to use the azldev CLI. -Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.3.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.4.0`. diff --git a/.github/instructions/comp-toml.instructions.md b/.github/instructions/comp-toml.instructions.md index b9d17435428..8b6a4eb7b1a 100644 --- a/.github/instructions/comp-toml.instructions.md +++ b/.github/instructions/comp-toml.instructions.md @@ -17,7 +17,8 @@ Load only the additional workflow skill required by the task: - Read the `azldev-add-component` skill to add a new component. - Read the `azldev-overlays` skill to add or change overlays. +- Read the `azldev-overlay-metadata` skill to annotate an overlay's category and upstream status. - Read the `azldev-update-component` skill to refresh a component's lock. - Read the `azldev-remove-component` skill to remove a component. -Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.3.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.4.0`. diff --git a/.github/instructions/rendered-specs.instructions.md b/.github/instructions/rendered-specs.instructions.md index 57776623a26..8d9eee6a3b8 100644 --- a/.github/instructions/rendered-specs.instructions.md +++ b/.github/instructions/rendered-specs.instructions.md @@ -18,4 +18,4 @@ Load only the additional workflow skill required by the task: - Read the `azldev-overlays` skill to change generated output via overlays. - Read the `azldev-update-component` skill to refresh and finalize a component. -Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.3.0`. +Generated by `azldev docs agent`; do not hand-edit. Generated for azldev version `v0.4.0`. diff --git a/external/schemas/azldev.schema.json b/external/schemas/azldev.schema.json index 5f5542a201b..9195abd5110 100644 --- a/external/schemas/azldev.schema.json +++ b/external/schemas/azldev.schema.json @@ -162,6 +162,11 @@ "$ref": "#/$defs/ComponentPublishConfig", "title": "Publish settings", "description": "Component-level publish channel settings" + }, + "tests": { + "$ref": "#/$defs/ComponentTestsConfig", + "title": "Tests", + "description": "Per-component test or test-group references" } }, "additionalProperties": false, @@ -346,6 +351,20 @@ "additionalProperties": false, "type": "object" }, + "ComponentTestsConfig": { + "properties": { + "tests": { + "items": { + "$ref": "#/$defs/TestRef" + }, + "type": "array", + "title": "Tests", + "description": "Per-component test or test-group references" + } + }, + "additionalProperties": false, + "type": "object" + }, "ConfigFile": { "properties": { "$schema": { @@ -431,6 +450,22 @@ "type": "object", "title": "Test Suites", "description": "Definitions of test suites for this project" + }, + "tests": { + "additionalProperties": { + "$ref": "#/$defs/TestDefinition" + }, + "type": "object", + "title": "Tests", + "description": "Definitions of individual tests" + }, + "test-groups": { + "additionalProperties": { + "$ref": "#/$defs/TestGroup" + }, + "type": "object", + "title": "Test Groups", + "description": "Definitions of named bundles of tests" } }, "additionalProperties": false, @@ -547,6 +582,11 @@ "title": "Mock config file", "description": "Path to the aarch64 mock config file for this version" }, + "kiwi-config-override": { + "type": "string", + "title": "KIWI config override", + "description": "Path to KIWI configuration overrides for this version" + }, "inputs": { "$ref": "#/$defs/DistroVersionInputs", "title": "Inputs", @@ -638,6 +678,26 @@ "type": "boolean", "title": "Runtime package management", "description": "Whether the image supports installing or removing packages at runtime" + }, + "wsl": { + "type": "boolean", + "title": "WSL", + "description": "Whether the image runs under the Windows Subsystem for Linux runtime" + }, + "installer-media": { + "type": "boolean", + "title": "Installer media", + "description": "Whether the image is installer media that installs another OS rather than a directly runnable end-state image" + }, + "fips-enabled": { + "type": "boolean", + "title": "FIPS enabled", + "description": "Whether the image is built or configured to run in FIPS mode" + }, + "cvm": { + "type": "boolean", + "title": "Confidential VM", + "description": "Whether the image supports running as a Confidential VM (CVM)" } }, "additionalProperties": false, @@ -729,6 +789,14 @@ "type": "array", "title": "Test Suites", "description": "List of test suite references that apply to this image" + }, + "tests": { + "items": { + "$ref": "#/$defs/TestRef" + }, + "type": "array", + "title": "Tests", + "description": "List of test or test-group references that apply to this image" } }, "additionalProperties": false, @@ -1385,6 +1453,235 @@ "subpath" ] }, + "TestDefinition": { + "allOf": [ + { + "if": { + "properties": { + "type": { + "const": "pytest" + } + } + }, + "then": { + "not": { + "anyOf": [ + { + "required": [ + "lisa" + ] + }, + { + "required": [ + "tmt" + ] + } + ] + }, + "required": [ + "pytest" + ] + } + }, + { + "if": { + "properties": { + "type": { + "const": "lisa" + } + } + }, + "then": { + "not": { + "anyOf": [ + { + "required": [ + "pytest" + ] + }, + { + "required": [ + "tmt" + ] + } + ] + }, + "required": [ + "lisa" + ] + } + }, + { + "if": { + "properties": { + "type": { + "const": "tmt" + } + } + }, + "then": { + "not": { + "anyOf": [ + { + "required": [ + "pytest" + ] + }, + { + "required": [ + "lisa" + ] + } + ] + }, + "required": [ + "tmt" + ] + } + } + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "pytest", + "lisa", + "tmt" + ], + "title": "Type", + "description": "Test framework type" + }, + "description": { + "type": "string", + "title": "Description", + "description": "Description of this test" + }, + "kind": { + "type": "string", + "enum": [ + "functional", + "performance" + ], + "title": "Kind", + "description": "Kind hint for the test" + }, + "long-running": { + "type": "boolean", + "title": "Long running", + "description": "Hints that this test may run for hours" + }, + "metrics-enabled": { + "type": "boolean", + "title": "Metrics enabled", + "description": "Hints to the test execution environment/validation service whether metrics from this test should be collected and stored" + }, + "required-capabilities": { + "items": { + "type": "string" + }, + "type": "array", + "title": "Required capabilities", + "description": "Capability tokens the image must declare" + }, + "lisa": { + "type": "object", + "title": "LISA config", + "description": "LISA-specific configuration" + }, + "tmt": { + "type": "object", + "title": "TMT config", + "description": "TMT-specific configuration" + }, + "pytest": { + "type": "object", + "title": "Pytest config", + "description": "pytest-specific configuration" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "type" + ] + }, + "TestGroup": { + "properties": { + "description": { + "type": "string", + "title": "Description", + "description": "Description of this test group" + }, + "tests": { + "items": { + "not": { + "required": [ + "group" + ] + }, + "properties": { + "name": { + "type": "string", + "minLength": 1, + "pattern": "^\\S", + "description": "Name of a test" + } + }, + "type": "object", + "required": [ + "name" + ] + }, + "type": "array", + "title": "Tests", + "description": "Ordered test references for this group (name only)" + } + }, + "additionalProperties": false, + "type": "object" + }, + "TestRef": { + "oneOf": [ + { + "not": { + "required": [ + "group" + ] + }, + "required": [ + "name" + ] + }, + { + "not": { + "required": [ + "name" + ] + }, + "required": [ + "group" + ] + } + ], + "properties": { + "name": { + "type": "string", + "minLength": 1, + "pattern": "^\\S", + "title": "Name", + "description": "Name of a test (mutually exclusive with group)" + }, + "group": { + "type": "string", + "minLength": 1, + "pattern": "^\\S", + "title": "Group", + "description": "Name of a test group (mutually exclusive with name)" + } + }, + "additionalProperties": false, + "type": "object" + }, "TestSuiteConfig": { "properties": { "description": {