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
25 changes: 24 additions & 1 deletion .github/instructions/agent-skills.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,32 @@ Before shipping any skill/instruction:
`TestOverlaysSkillCoversAllOverlayTypes` extracts the overlay-type enum from the jsonschema tag
on `projectconfig.ComponentOverlay.Type` and fails if the skill omits a type.

## Mode-specific content

azldev has two modes, and the emitted content follows the one it runs in. A `Catalog`
(`NewCatalog(withoutLockfile)`) resolves the skills, instruction wrappers, and templates;
the package-level `Skills`, `Instructions`, `FindSkill`, `SkillDocument`, and `Files`
helpers are the default (lock-file) mode.

- **Shared by default.** Registry entries and templates under `content/` describe the
default mode and are used by both, so most edits need nothing extra.
- **Replace only what differs.** `withoutLockfileSkills` replaces registry entries by the
name of the default-mode skill it supersedes, and `withoutLockfileInstructions` replaces
instruction descriptions. Pointers to a replaced skill are rewritten automatically.
- **Templates layer.** A template under `content/withoutlockfile/` replaces the
same-named default template for that mode; add one only when the document's content
actually differs.

When you add or edit a skill, check whether its content names a command that exists in
only one mode (for example `comp update` versus `comp refresh-upstream-commit`) and, if
so, provide the mode-specific variant. Verify both with
`./out/bin/azldev docs agent show --skill <name>` and
`./out/bin/azldev --without-lockfile docs agent show --skill <name>`.

## Config-resolved bindings

Repo-specific values (lock dir, rendered-specs dir, work dir) are resolved from the target `azldev.toml` in
Repo-specific values (lock dir, generated upstream-commit dir, rendered-specs dir, work
dir) are resolved from the target `azldev.toml` in
[cmds/docs/agent.go](../../internal/app/azldev/cmds/docs/agent.go) and degrade to azldev's defaults
when no config is present. To add a binding, extend `Bindings`, resolve it in `resolveBindings`, and
reference it in a template as `{{ .FieldName }}`.
Expand Down
45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,51 @@ All notable changes to `azldev` are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- **`--without-lockfile` preview mode.** Add a global `--without-lockfile`
flag that opts in to a preview of tracking resolved upstream commits in
generated component configuration instead of per-component lock files. The
flag defaults to off; without it azldev's behavior, command set, and
configuration handling are unchanged. The preview surface is not stable and
may change.
- **Generated upstream commit configuration.** With `--without-lockfile`,
record snapshot-selected upstream commits as normal layered TOML under
`base/upstream-commits`. Generated pin files participate in standard
configuration loading, merging, provenance tracking, and validation, and the
project's `lock-dir` setting is accepted but ignored.
- **Upstream commit refresh command.** With `--without-lockfile`, `azldev
component refresh-upstream-commit` resolves and records upstream commits. It
supports check-only operation, removes obsolete pins for selected
non-upstream components, and prunes orphaned generated files when all
components are selected. Configuration is loaded permissively for this
command so stale generated pins can be removed after a component is deleted
or converted to another source type.

### Changed

- **Mode-specific component commands.** With `--without-lockfile`, `azldev
component update`, `component history`, and `component query` are replaced by
hidden no-op shims, and the lock-file-only `--skip-lock-validation` flag is
not registered. All of them are unchanged in the default mode.
- **Configuration-based component change detection.** With
`--without-lockfile`, `azldev component changed` loads each historical
project configuration independently and compares normalized build inputs
instead of stored fingerprints. It handles added and deleted components,
resolves recursive includes and inherited defaults at each ref, compares
local source and overlay content, and reports rendered `sources` changes
separately.
- **Synthetic source history.** With `--without-lockfile`, synthetic dist-git
history is built from configured upstream commit transitions and walks
first-parent history to the repository root instead of relying on
lock-recorded import commits.
- **Component workflow guidance.** Agent skills, instruction files, and MCP
tools describe the workflow of the mode azldev runs in. The generated CLI
reference continues to document the default mode; the preview mode is
documented in the user guide.

## [0.4.0] - 2026-09-01

### Added
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ It supports:
1. Install `golang` and other prerequisites via your system's package manager, e.g.:

```console
dnf install -y golang mock dnf-utils mock-rpmautospec kiwi
dnf install -y golang mock dnf-utils mock-rpmautospec rpmdevtools kiwi
```

Note: `mock-rpmautospec` plugin hooks `rpmautospec` into mock's build lifecycle. It pulls `rpmautospec` as a dependency which processes `%autorelease` and `%autochangelog` macros in spec files.
Note: `mock-rpmautospec` hooks `rpmautospec` into mock's build lifecycle
and pulls in the host `rpmautospec` command. `rpmdevtools` provides
`rpmdev-bumpspec`; lock-file-free rendering uses both host commands.

1. Install `azldev`:

Expand Down
2 changes: 1 addition & 1 deletion docs/developer/how-to/get-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
tdnf install -y golang ca-certificates glibc-devel

# Install runtime requirements for the azldev tool
tdnf install -y mock dnf-utils mock-rpmautospec
tdnf install -y mock dnf-utils mock-rpmautospec rpmdevtools

git clone <URL>
cd <REPO>
Expand Down
1 change: 1 addition & 0 deletions docs/user/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- [Build a Component](./how-to/build-component.md) — build RPMs from component definitions
- [Build an Image](./how-to/build-image.md) — build and boot Azure Linux images
- [Set Up AI Coding Agents](./how-to/set-up-ai-agents.md) — emit agent skill and instruction files
- [Preview the Lock-File-Free Mode](./how-to/preview-without-lockfile.md) — opt in to `--without-lockfile`

## Explanation

Expand Down
2 changes: 2 additions & 0 deletions docs/user/explanation/config-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ Component definitions are merged additively. If the same component name (e.g., `

> **Note:** Slice fields (like `overlays`) are **appended**, not replaced, following the same merge behavior used by component configuration inheritance.

> **Preview:** With the global `--without-lockfile` flag, component definitions merge with override semantics instead, and component validation runs only after every included file has been merged, so an individual file may hold a partial component definition. See [Preview the Lock-File-Free Mode](../how-to/preview-without-lockfile.md).

### Component Groups and Images

These are strict-union maps: each name may appear in exactly one config file across the entire include tree. If two files both define `[component-groups.my-group]` or `[images.my-image]`, azldev reports an error. This prevents accidental shadowing and makes it clear where each definition lives.
Expand Down
122 changes: 122 additions & 0 deletions docs/user/how-to/preview-without-lockfile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# How To: Preview the Lock-File-Free Mode

`--without-lockfile` is a **preview** global flag. It selects an alternative way of
tracking a component's resolved upstream commit: instead of per-component lock
files, azldev records the commit in generated component TOML that the project
includes like any other config file.

The flag is opt-in and defaults to off. Without it, azldev behaves exactly as it
always has — lock files, `component update`, `component history`, and
`component query` are unchanged. Nothing in the preview mode is stable yet; both
the command surface and the generated file layout may change.

```bash
# Default behavior: lock files.
azldev component render -p curl

# Preview behavior: generated upstream-commit config.
azldev --without-lockfile component render -p curl
```

Pass the flag on every invocation that should use the preview mode, before the
command name. `--without-lockfile=false` explicitly selects the default mode.

## What Changes

| Area | Default | `--without-lockfile` |
|------|---------|----------------------|
| Resolved commit storage | `locks/<name>.lock` | `base/upstream-commits/<name>.toml` |
| Refresh command | `azldev component update` | `azldev component refresh-upstream-commit` |
| Inspecting resolved state | `azldev component history`, `azldev component query` | read the generated TOML; no equivalent commands |
| Lock consistency checks | On, with `--skip-lock-validation` to opt out | Not applicable; the flag is not registered |
| `component changed` | Compares stored input fingerprints | Compares project configuration resolved at each ref |
| `component render` history | Synthetic commits derived from lock-file fingerprint changes | No synthetic commits; generated TOML history is not inspected |
| Agent skills and MCP tools | Describe the lock-file workflow | Describe the upstream-commit workflow |

`component update`, `component history`, and `component query` remain registered
in preview mode as hidden no-ops so that existing scripts report clearly that the
commands do nothing, rather than failing with "unknown command".

## Configure the Project

Include the generated directory **before** the component-specific TOML, so that a
component definition can still override the generated pin:

```toml
includes = [
"base/upstream-commits/*.toml",
"base/components/*.toml",
]
```

Generated files hold only `spec.upstream-commit`; the component's own TOML
supplies the source type and everything else. Because a single file may hold a
partial component definition in this mode, component validation runs after all
config files have been merged.

An existing `[project] lock-dir` setting is accepted and ignored in preview mode,
so the same project config works in both modes.

## Refresh a Component

```bash
# Resolve and record the upstream commit for one component.
azldev --without-lockfile component refresh-upstream-commit -p curl

# Refresh everything and prune generated files for components that no longer exist.
azldev --without-lockfile component refresh-upstream-commit -a

# CI gate: exit 1 when any generated file is out of date.
azldev --without-lockfile component refresh-upstream-commit -a --check-only -q
```

Refresh after changing a commit pin, upstream distro or version, or snapshot.
Overlay, build-config, and metadata changes do not affect the resolved commit, so
they need only a re-render.

Commit the refreshed TOML together with the rendered output. In lock-file-free
mode, `component render` does not inspect the generated TOML's git history or
create synthetic commits. Release and changelog handling is instead based on
the component source type and `release.calculation`:

- Local components preserve their `Release` and changelog. `static` is not
supported; `auto` preserves `%autorelease` and otherwise behaves as `manual`.
- Upstream `manual` components preserve their `Release` and changelog.
- Upstream `autorelease` components, including `auto` components whose
`Release` uses `%autorelease`, are initialized only when their rendered
dist-git dir is absent from `HEAD`. Initialization writes the output of
`rpmautospec generate-changelog` to `changelog` and sets the spec's `%changelog`
body to `%autochangelog`.
- Upstream `auto` components without `%autorelease` are updated with
`rpmdev-bumpspec`.

The `rpmautospec` and `rpmdev-bumpspec` commands run directly on the host, never in
mock. Explicit `static` calculation is unsupported in lock-file-free render.

## Detect Changed Components

```bash
azldev --without-lockfile component changed --from main -a -q -O json
```

In preview mode this loads the project configuration independently at both refs
and compares the resolved component build inputs: normalized component
configuration, upstream commit or local spec-directory contents, overlay source
filenames and contents, and the effective distro release version. Documentation,
publishing, test-selection, scheduling-hint, snapshot-time, and checkout-path-only
fields do not mark a component as changed.

## Emit Agent Files for the Preview Mode

`azldev docs agent install` emits the content for the mode it runs in, so pass the
flag when the target repository uses the preview workflow:

```bash
azldev --without-lockfile docs agent install
```

## Reference Documentation

The generated CLI reference under [reference/cli/](../reference/cli/azldev.md)
documents azldev's default mode. Use `azldev --without-lockfile <command> --help`
to see the preview mode's command surface and help text.
1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_advanced.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_advanced_mcp.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_advanced_mock.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_advanced_mock_build-rpms.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_advanced_mock_shell.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_advanced_wget.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_completion.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_completion_bash.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_completion_fish.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_completion_powershell.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_completion_zsh.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion docs/user/reference/cli/azldev_component.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component_add.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component_build.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/user/reference/cli/azldev_component_changed.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading