CtrlK
BlogDocsLog inGet started
Tessl Logo

skill-build-component

[Skill] Build and test Azure Linux components using azldev. Use when building packages, debugging build failures, inspecting mock chroots, preparing sources, or working with the build inner loop. Triggers: build component, build failed, mock shell, prepare sources, debug build, build error.

78

Quality

100%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

SKILL.md
Quality
Evals
Security

Build & Debug Components

Never install built RPMs on the host. They target Azure Linux, not your dev machine. Use skill-mock for testing.

Mandatory Testing

A successful build is NOT the finish line. If your change could affect the built RPMs, smoke-test before reporting success. See skill-mock.

Pure organizational changes (moving definitions between files, editing comments/descriptions) don't need a rebuild. When in doubt, test.

Build Output Directories

Build output paths are configured in base/project.toml (output-dir, log-dir, work-dir). Default layout:

project.toml keyDefault valueResolves toContents
output-diroutbase/out/Built RPMs and SRPMs
log-dirbuild/logsbase/build/logs/Build logs
work-dirbuild/workbase/build/work/Per-component working dirs (<name>/)

Paths are relative to the project root (base/). Don't edit anything in these dirs — they are generated output.

prep-sources output is separate. comp prep-sources -o <dir> writes to a user-specified directory, NOT to the project's configured output dirs. Don't look in base/out/ for prep-sources results.

Build Sequence

# Build a single component
azldev comp build -p <name>

# Build multiple components, auto-publishing RPMs to local repo for chained deps
azldev comp build --local-repo-with-publish ./base/out -p <dep1> -p <dep2>

# Rebuild a single component against an already-populated local repo
azldev comp build -p <name> --local-repo ./base/out

NOTE: -q (silent) can be used with all commands for cleaner logs, but will limit visibility into build progress. Only use -q for inner-loop builds when you know the build will run to completion without infrastructure issues.

Build foundational packages first (e.g., azurelinux-rpm-config), then dependents. See scripts/demo-build.sh for a working example.

Dev Inner Loop

The standard cycle for investigating, modifying, and verifying components:

investigate → modify → render → build → test → inspect

Finalize with azldev comp update -p <name> before opening a PR — lock fingerprints are computed from the full component config, so any TOML change can invalidate them. The Update Locks CI check enforces this. After committing your change, re-render and amend so %changelog / Release: track the new commit (rpmautospec walks git log every render). See skill-update-component for the full finalize-and-amend pattern, plus the pin-bump variant.

StepCommandWhat to check
InvestigateRead specs/<first-char>/<name>/<name>.spec or prep-sources --skip-overlays --force -o base/build/work/scratch/<name>-preUpstream spec/sources as-is
Compareprep-sources --force -o base/build/work/scratch/<name>-post + diff -r ...-pre ...-postCurrent overlay effect (deep debug)
ModifyEdit *.comp.toml (overlays, defines, without)
Verifycomp render -p <name> + inspect specs/<first-char>/<name>/Overlay applies cleanly (fast path)
Buildcomp build -p <name>RPMs appear in base/out/
Testadv mock shell --add-package base/out/<name>*.rpmPackage installs, binary runs, basic functionality works
Inspectcomp build --preserve-buildenv always + adv mock shellBUILDROOT contents, file lists

Prefer comp render for quick verification. It's faster than prep-sources since it skips downloading source tarballs. Use prep-sources when you need the full source tree or want to diff pre/post overlay output for debugging.

Use a temp dir for prep-sources output. Use --force to overwrite an existing output dir.

Package builds are often very long, so adjust command timeouts accordingly when using shell tools to run builds, or use background mode if available.

Debugging Build Failures

0. Release calculation errors

If render fails with non-standard Release tag value ... does not start with an integer, or if %autorelease is incorrectly expanded to a hardcoded integer (common with conditional %autorelease specs), see Release Configuration.

1. Render and inspect the spec

The fastest way to verify overlays applied correctly:

azldev comp render -p <name>
# Inspect the result
cat specs/<first-char>/<name>/<name>.spec

2. Diff sources pre/post overlay (deep debug)

When you need to understand exactly what upstream provides vs. what overlays change:

azldev comp prep-sources -p <name> --skip-overlays --force -o base/build/work/scratch/<name>-pre -q
azldev comp prep-sources -p <name> --force -o base/build/work/scratch/<name>-post -q
diff -r base/build/work/scratch/<name>-pre base/build/work/scratch/<name>-post

This reveals whether overlays apply as intended or whether upstream changed.

3. Preserve build environment on failure

azldev comp build -p <name> --preserve-buildenv on-failure -q
# Use `always` to inspect even successful builds

4. Enter mock shell (deep debug)

For testing built RPMs or inspecting the chroot, see the skill-mock skill. Quick reference:

# Non-interactive (preferred for agents)
azldev adv mock shell --add-package /path/to/rpm <<'CMDS'
rpm -q <name>
exit
CMDS

# Interactive (requires user cooperation — see skill-mock for agent workflow)
azldev adv mock shell --add-package /path/to/rpm --enable-network

⚠️ Don't mix -p <name> with --add-package for the same package. -p is shorthand for --add-package, so -p cowsay --add-package ./cowsay.rpm installs two conflicting builds. Use one or the other. See skill-mock for details.

Inside the chroot: rpmbuild, find, dnf5 — standard RPM tooling. BUILDROOT is at builddir/build/BUILD/<pkg>-<ver>-build/BUILDROOT/.

Per-Component Build Overrides

Use build.defines (macros) and build.without (disable conditionals) in the component's .comp.toml. See comp-toml.instructions.md for syntax and examples.

Verify with prep-sources before doing a full build.

Disabling %check (test suites)

Disabling %check (via build.without = ["check"]) is an absolute last resort. Always attempt to fix failing tests first — investigate the root cause, check upstream for patches or known issues, and try targeted fixes. If disabling is truly unavoidable, the component's skip_reason field MUST clearly explain:

  • What tests fail and how
  • Why the failures cannot be fixed (e.g., upstream bug with link, environment limitation, missing test infrastructure)
  • Whether this is expected to be temporary (and if so, what would unblock re-enabling)

Reference

  • CLI help: azldev comp build --help, azldev advanced mock --help
  • azldev advanced (alias adv) is hidden from azldev --help but contains mock shell, mock build-rpms, mcp, and wget.
  • schema reference (or azldev config generate-schema > base/build/work/scratch/schema.json for latest changes)
Repository
microsoft/azurelinux
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.