Skip to content
Draft
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
88 changes: 88 additions & 0 deletions .agents/skills/azldev-add-component/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
name: azldev-add-component
description: Read this before adding or importing a component; follow the workflow instead of guessing. Explains how to add a new component to an azldev distro, covering inspecting the upstream spec, the inline-versus-dedicated-file decision, and validating with render, diff-sources, and build. Triggers include add component, new package, import package, create comp.toml, new component.
---

# Add a component

## Before you start

Confirm the component does not already exist:

```sh
azldev comp list -p <name> -q -O json
```

### Inspect the upstream spec first

The reliable way to see what you are importing (direct web fetches of upstream
dist-git often fail bot detection):

1. Add a bare entry so azldev can resolve the component: run `azldev comp add <name>`
(it appends `[components.<name>]` to the root config file), or hand-add
`[components.<name>]` to an included config file if you want it to live elsewhere.
A bare root entry is *perfect* for initial testing, but real distros will usually
segment the configuration into included files. Once the initial pass is done,
ensure the component is in the right place and remove the root entry.

2. Pull the sources without overlays into a scratch dir under the work dir:

```sh
azldev comp prep-sources -p <name> --skip-overlays --force -o base/build/work/scratch/<name> -q
```

3. Read the spec and plan any overlays.

## Inline vs dedicated file

- **Inline** — a bare upstream import with no changes stays in a shared config file:

```toml
[components.jq]
```

- **Dedicated** — anything that needs overlays, build config, or a local spec gets its
own `<name>/<name>.comp.toml`. Rule of thumb: more than `[components.<name>]` earns a
dedicated file. An `includes = ["**/*.comp.toml"]` glob picks it up automatically.

`azldev comp add <name> [<name>...]` adds bare `[components.<name>]` entries that inherit
the distro defaults; it writes to the **root** config file and does not scaffold spec or
source files. If your distro keeps components in included or dedicated files, move the
entry there afterward.

## Customize

For spec source types and overlays, read the `azldev-comp-toml` and `azldev-overlays` skills. Key
points when adding a component:

- Prefer **overlays** over forking the spec — overlays get upstream updates for free.
Forking a spec is a last resort and a long-term maintenance commitment. Get explicit
user sign-off first, document every change, and keep the delta minimal.
- Every overlay needs a `description` explaining why it is needed.
- Keep `%check` enabled. Disable it only as a last resort via `build.check.skip = true`
with a required `build.check.skip_reason` (see the `azldev-build-component` skill).

## Validate

A new upstream component has no lock yet, and `render`, `diff-sources`, and `build` all
resolve it first — which fails lock validation until the lock exists. Create the lock,
then validate:

```sh
azldev comp update -p <name> # resolve the upstream commit and write the lock
azldev comp render -p <name> # apply overlays and write the rendered spec
azldev comp diff-sources -p <name> # see exactly what the overlays change
azldev comp build -p <name> # build the RPMs
```

Inspect the rendered spec under `specs/`. A new component always needs a
smoke test — see the `azldev-build-component` and `azldev-mock` skills.

After all component inputs are final, run `azldev comp update -p <name>` again and
re-render. Stage the component definition and sources, `locks/<name>.lock`, and
the rendered output before committing. Then re-render, stage
`specs/<first-char>/<name>/`, and amend the commit so `%changelog` and
`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.1.0`.
60 changes: 60 additions & 0 deletions .agents/skills/azldev-build-component/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
name: azldev-build-component
description: Read this before building a component or diagnosing a build failure; do not guess build flags or the inner loop. Explains how to build, iterate on, and debug an azldev component, covering comp build flags (local-repo, preserve-buildenv), the render/build/test inner loop, diff-sources, and disabling a failing %check via check.skip. Triggers include build component, build failed, build error, inner loop, preserve buildenv, local repo, disable check.
---

# Build and debug a component

**Never install built RPMs on your host** — they target the distro, not your dev
machine. Test them in a chroot with the `azldev-mock` skill. Building and testing are separate
steps: `azldev comp build` produces RPMs; it does not test them.

## Build

```sh
azldev comp build -p <name> # one component
azldev comp build -p <a> -p <b> --local-repo-with-publish <dir> # chain deps via a local repo
azldev comp build -p <name> --local-repo <dir> # rebuild against a populated repo
```

Build foundational packages before their dependents. RPMs land in the project's
configured output directory (`out` by default). `-q` quiets output but hides build
progress — use it only for inner-loop builds you expect to succeed.

## The inner loop

investigate → modify → render → build → test → inspect

| Step | Command |
| --- | --- |
| Investigate | read the rendered spec under `specs/`, or `azldev comp diff-sources -p <name>` |
| Modify | edit the component's `.comp.toml` (see the `azldev-overlays` and `azldev-comp-toml` skills) |
| Verify | `azldev comp render -p <name>` (fast — skips source tarballs) |
| Build | `azldev comp build -p <name>` |
| Test | `azldev adv mock shell --add-package <rpm>` (see the `azldev-mock` skill) |
| Inspect | `azldev comp build -p <name> --preserve-buildenv always`, then a mock shell |

Prefer `comp render` for quick overlay verification; use `comp diff-sources` to see the
exact overlay effect (it fetches sources once, applies overlays to a copy, and diffs the
two trees). Builds can be slow — set generous timeouts.

Finalize with `azldev comp update -p <name>` before opening a PR (see the
`azldev-update-component` skill).

## Debugging build failures

1. **Render error mentioning a non-standard `Release` tag** — a release-calculation
issue; see the `azldev-comp-toml` skill.
2. **Overlay did not apply as expected** — `azldev comp diff-sources -p <name>` shows
what the overlays actually change.
3. **Inspect the build environment** — `azldev comp build -p <name> --preserve-buildenv
on-failure` (values `on-failure`, `always`, `never`), then enter a mock shell.
4. **Failing `%check`** — fix the tests first (root cause, upstream patches, targeted
fixes). Only as a last resort, disable with `build.check.skip = true` and a required
`build.check.skip_reason` explaining what fails, why it cannot be fixed, and whether it
is temporary. A transient `--no-check` build flag exists for one-off local builds.

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.1.0`.
141 changes: 141 additions & 0 deletions .agents/skills/azldev-comp-toml/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
---
name: azldev-comp-toml
description: Read this before authoring, editing, or reviewing a *.comp.toml file; do not work from memory. Explains the azldev component definition format and review workflow, covering component structure, spec sources, build config, release calculation, render options, file organization, overlay hygiene, stale files, disabled tests, and testing verification. Triggers include comp.toml, component config, review component, component hygiene, spec source, upstream-distro, build defines, release calculation, includes.
---

# Component definition files (`*.comp.toml`)

A component definition tells azldev where a package's spec comes from and how to
customize it for your distro. Every component lives under `[components.<name>]`.

Get the authoritative, always-current field list from the schema:

```sh
azldev config generate-schema
```

## Structure

A bare entry inherits everything from your distro's defaults — most upstream packages
need nothing more:

```toml
[components.curl]
```

Add sub-tables only for what you change. The fields you will reach for most:

| Field | Purpose |
| --- | --- |
| `spec` | where the spec comes from (see below) |
| `overlays` / `overlay-files` | targeted spec/source edits (see the `azldev-overlays` skill) |
| `build.defines` / `build.with` / `build.without` | RPM macro and bcond build tweaks |
| `release.calculation` | how the `Release` tag is managed |
| `render.skip-file-filter` | rendering edge-case escape hatch |

## Spec source

The `spec` field selects where the spec is fetched from. When omitted, the component
inherits the distro default (normally an upstream import).

```toml
# Upstream import (the usual case) — inherits the distro's upstream version
[components.curl]

# Upstream, but pinned to a specific upstream distro/version
[components.curl]
spec = { type = "upstream", upstream-distro = { name = "fedora", version = "rawhide" } }

# Upstream package whose name differs from the component name
[components.mydistro-rpm-config]
spec = { type = "upstream", upstream-name = "redhat-rpm-config" }

# Local spec that lives in your repo (not imported from an upstream distro)
[components.mydistro-release]
spec = { type = "local", path = "mydistro-release.spec" }
```

## Build configuration

```toml
[components.mypackage.build]
defines = { rhel = "11" } # override RPM macros
with = ["feature_x"] # enable %bcond_with conditionals
without = ["plugin_rhsm"] # disable %bcond_with conditionals
```

## Release calculation

`release.calculation` controls the `Release:` tag. There are four modes:

- `auto` (default) — auto-detect whether the spec uses `%autorelease` or a static
release and handle it accordingly. Correct for most packages.
- `autorelease` — force `%autorelease` handling (use when auto-detection misreads a
spec that wraps `%autorelease` in a conditional).
- `static` — force static-integer handling and bump the integer on render (the
inverse of `autorelease`).
- `manual` — you own the `Release:` value. Use this only when render fails with a
"non-standard Release tag" error. **A `manual` component is not bumped by the
render/commit/amend cycle, so increment its release yourself in the same change**
(see the `azldev-update-component` skill).

```toml
[components.mypackage.release]
calculation = "manual"
```

## Render configuration

`render.skip-file-filter = true` keeps all source and patch files during render.
azldev normally prunes files not referenced by the rendered spec; set this only for
the rare spec whose `Source`/`Patch` filenames use macros the filter cannot expand.

## File organization

- **Inline** — put simple, customization-free components directly in a shared config
file (e.g. `[components.jq]`).
- **Dedicated** — give a component its own `<name>/<name>.comp.toml` once it needs
overlays, build config, or a local spec. Rule of thumb: anything more than
`[components.<name>]` earns a dedicated file.
- A parent config picks up dedicated files through an `includes` glob, for example
`includes = ["**/*.comp.toml"]`.

## Review checklist

Start with `azldev comp list -p <name> -q -O json`, then use
`azldev comp query -p <name> -q -O json` when the review needs parsed spec details.
For a change review, focus on the diff while checking enough surrounding context to
ensure it fits the component and repository conventions.

- **Organization:** The component follows the repository's inline-versus-dedicated-file
convention; its name matches upstream or sets `spec.upstream-name`; no stale or
orphaned component files remain.
- **Spec source:** The default upstream source is preferred. Pins explain why they are
needed, and local specs are used only when overlays cannot express the change.
- **Overlays:** Every overlay explains why it exists. Prefer structured overlay types
over regex; scope unavoidable `spec-search-replace` expressions by section and, when
applicable, package, and use TOML literal strings. `spec-search-replace` cannot span
lines. Remove overlays that upstream has made unnecessary. See the `azldev-overlays` skill.
- **Build config:** Defines and bcond overrides are necessary and correspond to the
spec. If `build.check.skip = true`, require a specific `build.check.skip_reason` and
verify that fixing the tests is impractical; skipped `%check` is a last resort.
- **Release mode:** `auto` is the default. Force `autorelease` or `static` only when
auto-detection is wrong. Use `manual` only for a non-standard release tag, and verify
the component increments its release itself.
- **Generated state:** The lock matches the final component inputs, and rendered output
contains the intended changes without unrelated drift.
- **Testing:** Changes that can affect RPM output were built and smoke-tested in a mock
chroot. Organization, comment, or documentation-only metadata edits do not require a
rebuild when the resolved component inputs are unchanged.

Report findings by severity: errors for correctness or required-policy violations,
warnings for maintainability risks, and info for optional improvements. Prefer small,
actionable fixes over unrelated cleanup.

## Documenting changes

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.1.0`.
60 changes: 60 additions & 0 deletions .agents/skills/azldev-image/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
name: azldev-image
description: Read this before building, booting, or configuring an azldev image. Explains the azldev image commands (list, build, boot, test, customize) and the [images.<name>] config (kiwi definition, capabilities, tests, publish); the kiwi XML format itself is upstream KIWI NG. Triggers include image build, image boot, kiwi, container image, VM image, images.toml.
---

# Build and boot images

An image assembles built RPMs into a deliverable — a container or a bootable VM.
azldev drives the build from a kiwi-ng definition; the `.kiwi` file itself is
**upstream KIWI NG** ([docs](https://osinside.github.io/kiwi/)) and azldev does not
own its schema.

## Commands

Images are selected by their **name as a positional argument** (not `-p`).

| Task | Command |
| --- | --- |
| List images | `azldev image list` |
| Build an image (kiwi-ng) | `azldev image build <name>` |
| Boot an image in a QEMU VM | `azldev image boot <name>` |
| Run an image's tests | `azldev image test <name>` |
| 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
explicit `--image-path` / `--iso`. Confirm current flags with
`azldev image <command> --help` (there are more subcommands, e.g. `inject-files`).

## Registering an image

Images are declared under `[images.<name>]` (conventionally in an `images.toml`):

```toml
[images.container-base]
description = "Container base image"
definition = { type = "kiwi", path = "container-base/container-base.kiwi", profile = "core" }

[images.container-base.capabilities]
container = true
systemd = false

[images.container-base.tests]
test-suites = ["smoke"]
```

- `definition.type` is `kiwi` (the only type today); `path` points at the `.kiwi` file;
`profile` selects a kiwi profile (optional).
- `capabilities` are tri-state flags describing the image — `machine-bootable`,
`container`, `systemd`, `runtime-package-management`. Set only the ones that apply.
- `tests.test-suites` lists the test suites `azldev image test` runs.
- `publish.channels` lists the channels the image publishes to.

## The kiwi definition

The `.kiwi` file is upstream KIWI NG XML — azldev does not own its schema. It selects the
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.1.0`.
Loading
Loading