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
14 changes: 14 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,17 @@ updates:
update-types:
- "minor"
- "patch"

# git-cliff CLI (used by 'mage changelog'), pinned via a Cargo manifest so the
# version is visible to Dependabot and security scanners.
- package-ecosystem: "cargo"
directory: "/tools/git-cliff"
schedule:
interval: "weekly"
cooldown:
default-days: 7
groups:
dependabot-cargo-tools:
applies-to: version-updates
patterns:
- "*"
50 changes: 50 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Changelog

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Were this file's contents actually generated by git cliff? They look more massaged than that. Won't they get overwritten when git cliff gets run?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it will leave hand-edited content alone.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did just update with a linter directive though.


<!-- markdownlint-disable-file MD013 MD024 -->

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).

## [0.1.0] - 2026-03-18

First tagged preview release of `azldev`, the developer CLI for the
[Azure Linux](https://github.com/microsoft/azurelinux) distro.

### Added

- **Project and metadata management.** Scaffold a project with `azldev project
init` or `project new`, then parse, resolve, and query the TOML metadata
(`azldev.toml`) that defines Azure Linux. Configuration merges built-in
defaults with project and user-level (XDG) files, is fully validated, and is
published as a JSON Schema via `azldev config generate-schema`.
- **Component inspection and locking.** List and inspect components with `azldev
component list` and `component query`, and import new ones with `component
add`. Deterministic component fingerprints and per-component lock files keep
builds reproducible; `component update` refreshes them with `--check-only`,
`--bump`, freshness-based skipping, a progress bar, and upstream-staleness
detection. `component changed` and `component diff-sources` report what moved.
- **Source preparation and spec rendering.** `component prepare-sources` and
`component render` produce build-ready sources and specs through a
`mock`-based batch pipeline, synthesizing the git history that `rpmautospec`
needs and constructing dist-git from lock-file history. A rich overlay system
(spec search/replace, prepend/append lines, remove section or subpackage, file
and source replacement, per-file overlay files, and inline metadata)
customizes specs, with explicit release-calculation modes (`autorelease`,
`static`, and automatic). Source archives are fetched from lookaside caches.
- **Local package and image builds.** Build individual packages with `mock`
using `component build`, emitting RPMs and SRPMs into structured,
publish-channel-aware output directories. `azldev image` builds, customizes,
injects files into, boots, and runs LISA tests against Azure Linux images on a
local QEMU VM.
- **Package and repository queries.** Inspect binary package configuration with
`azldev package list` (including `--rpm-file`, debug-package synthesis, and
separate package/component group columns), and inspect or manage RPM
repositories with `azldev repo query`, backed by repo resources and repo-set
templates.
- **Command-line experience.** Shell completions for bash, zsh, fish, and
PowerShell; actionable hints on errors; global `--quiet`, `--verbose`, and
`--dry-run` flags with `table`, `json`, `csv`, and `markdown` output formats;
an embedded MCP server (`azldev advanced mcp`); and auto-generated CLI
reference documentation.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Azure Linux Dev Tools

[![Go Reference](https://pkg.go.dev/badge/github.com/microsoft/azure-linux-dev-tools.svg)](https://pkg.go.dev/github.com/microsoft/azure-linux-dev-tools)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE)

Azure Linux Dev Tools is a collection of utilities useful for development
of the Azure Linux distro.

Expand Down Expand Up @@ -28,9 +31,12 @@ It supports:
1. Install `azldev`:

```console
go install github.com/microsoft/azure-linux-dev-tools/cmd/azldev@main
go install github.com/microsoft/azure-linux-dev-tools/cmd/azldev@latest
```

To pin a specific release instead of tracking the latest, replace `@latest`
with a version tag, e.g. `@v0.1.0`.

1. To ensure you can build using `mock` you must be a member of the `mock` group, e.g.:

```console
Expand Down Expand Up @@ -62,6 +68,10 @@ Please see our [Contribution Guidelines](./CONTRIBUTING.md) for our project.

For development setup and workflow, please consult our [Developer Guide](./docs/developer).

## Changelog

Notable changes for each release are recorded in the [changelog](./CHANGELOG.md).

## Getting Help

Have questions, found a bug, or need a new feature? Open an issue in our [GitHub repository](https://github.com/microsoft/azure-linux-dev-tools/issues/new/choose). For guidance on how to file an issue, see [how to report issues](https://aka.ms/azurelinux-reportissues).
Expand Down
81 changes: 81 additions & 0 deletions cliff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
#
# git-cliff configuration for generating azldev's CHANGELOG.md from Conventional
# Commits. Run it via `mage changelog`; see docs/developer/how-to/releasing.md.
# Reference: https://git-cliff.org
#
# The generated entries are a *draft*: a human (or Copilot) prunes and rewords
# them into user-facing notes before a release. Internal commit types (docs,
# test, chore, build, ci, style, refactor, and dependency bumps) are skipped so
# the draft starts close to user-facing.

[changelog]
# The markdownlint-disable-file comment scopes two relaxations to CHANGELOG.md
# only (no repo-wide markdownlint config): MD013 because auto-generated entries
# are one line per commit and can exceed the line length, and MD024 because the
# Keep a Changelog format repeats '### Added'/'### Fixed' under every version.
header = """
# Changelog

<!-- markdownlint-disable-file MD013 MD024 -->

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).
"""
# Per-version section in Keep a Changelog style. `version` is unset when
# rendering unreleased commits, which yields an `## [Unreleased]` heading. The
# leading blank line keeps a blank line above each version heading (markdownlint
# MD022) when the section is prepended below the file header or another version.
body = """

{% if version %}\
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
## [Unreleased]
{% endif %}\
{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | striptags | trim | upper_first }}
{% for commit in commits %}
- {{ commit.message | split(pat="\n") | first | upper_first | trim }}\
{% endfor %}
{% endfor %}\
"""
# Collapse any run of 3+ newlines left by the template into a single blank line
# so the rendered changelog has no double blank lines (markdownlint MD012).
postprocessors = [{ pattern = '\n{3,}', replace = "\n\n" }]
trim = true
footer = ""

[git]
conventional_commits = true
# Keep non-conventional commits (e.g. early "README.md committed" bootstrap
# commits) instead of treating them as parse errors. They fall through to the
# catch-all `.*` skip parser below, so they're dropped quietly rather than
# emitting a "commit(s) skipped due to parse error(s)" warning during the
# full-history version bump.
filter_unconventional = false
# Drop commits that don't match a kept parser below (cuts internal noise).
filter_commits = true
# ...but never drop a breaking change, even if its type is skipped above.
protect_breaking_commits = true
# Only consider release tags of the form `vX.Y.Z`.
tag_pattern = '^v[0-9]+\.[0-9]+\.[0-9]+$'
sort_commits = "oldest"
commit_parsers = [
{ message = "^feat", group = "Added" },
{ message = "^fix", group = "Fixed" },
{ message = "^perf", group = "Changed" },
{ message = "^revert", group = "Removed" },
{ message = "^refactor", skip = true },
{ message = "^docs", skip = true },
{ message = "^test", skip = true },
{ message = "^chore", skip = true },
{ message = "^build", skip = true },
{ message = "^ci", skip = true },
{ message = "^style", skip = true },
# Skip anything that didn't match a kept type above.
{ message = ".*", skip = true },
]
12 changes: 12 additions & 0 deletions cmd/azldev/azldev.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

// Command azldev is a developer tool for working on the Azure Linux distro.
//
// It parses, resolves, and queries the TOML-based metadata that defines Azure
// Linux, prepares component sources for building with mock, fetches source
// archives from lookaside caches, and offers convenience utilities for
// locally building individual packages and images.
//
// Install the latest release with:
//
// go install github.com/microsoft/azure-linux-dev-tools/cmd/azldev@latest
//
// Run "azldev --help" for usage information, or see the user guide under docs/user.
package main

import (
Expand Down
1 change: 1 addition & 0 deletions docs/developer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ To get started developing `azldev`, review the [Getting Started guide](./how-to/
* [Submitting Pull Requests](./how-to/pull-requests.md)
* [Configuration management](./how-to/config-management.md)
* [Add go tools](./how-to/add-go-tool.md)
* [Cut a release](./how-to/releasing.md)

## Reference

Expand Down
143 changes: 143 additions & 0 deletions docs/developer/how-to/releasing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# How to: cut a release

This guide covers releasing the `azldev` Go module so that
`go install ...@version` and the [pkg.go.dev][pkgsite] reference page work.

## TL;DR

```console
# One-time: install the changelog generator (git-cliff)
cargo binstall git-cliff # or: cargo install git-cliff --locked, or: brew install git-cliff

# 1. Draft the changelog, curate it into user-facing notes, then PR + merge to main
mage changelog # prepends a draft ## [X.Y.Z] section to CHANGELOG.md

# 2. Tag the release from the changelog version, then publish by pushing the tag
mage release # creates annotated tag vX.Y.Z on HEAD (does not push)

# Undo a local tag created by mistake (before pushing)
git tag -d vX.Y.Z

git push origin vX.Y.Z # pushing the tag is what publishes the release
```

Each step is explained in full under [Cut a release](#cut-a-release) below.

## Versioning policy

We follow [Semantic Versioning][semver] with a `v` prefix on tags
(`vMAJOR.MINOR.PATCH`).

* **`v0.x.y` (current).** The pre-1.0 phase: the CLI and any exported Go API may
change in breaking ways on a *minor* bump. Use this while the surface is still
settling.
* **`v1.0.0` and later.** Commits to SemVer stability: breaking changes require a
major bump.
* **Major versions `>= 2`** require a `/vN` suffix on the module path
(e.g. `github.com/microsoft/azure-linux-dev-tools/v2`). Staying on `v0`/`v1`
avoids that. Don't cut a `v2.0.0` tag without first updating the module path.

## How publishing actually works

There is no separate "upload" step. The public [Go module proxy][proxy] and
pkg.go.dev fetch directly from this repository's Git tags:

* `go install .../cmd/azldev@vX.Y.Z` resolves the tag through the proxy.
* `azldev version` reports the right version automatically for proxy installs —
Go embeds the module version into the binary's build info.
* pkg.go.dev renders the package doc comments plus this repo's `README.md`. Our
`LICENSE` (MIT) marks the module redistributable so docs are shown. Only the
public `cmd/` and `pkg/` packages appear; `internal/` is hidden by design.

## Cut a release

1. Make sure `main` is green and up to date locally.

2. Generate and curate the changelog. Run `mage changelog` to prepend a draft
section for the next version to [`CHANGELOG.md`](../../../CHANGELOG.md), then
edit it down into user-facing notes. See [Changelog](#changelog) below.

3. Tag the release. Once the changelog change is on `main`, run `mage release`:
it reads the version from the top `## [X.Y.Z]` heading in
[`CHANGELOG.md`](../../../CHANGELOG.md) and creates a matching annotated tag
(`vX.Y.Z`), so the tag and the changelog can't disagree. Then push the tag:

```console
mage release
git push origin vX.Y.Z
```

`mage release` creates the tag locally but never pushes — pushing the tag is
what publishes the release. The version lives only in the git tag (there is no
version file); `azldev version` reads it from the build. To sign the tag,
create it manually with `git tag -s` instead.

`mage release` is idempotent: if that version is already tagged it does
nothing, so the same command is safe to automate on every merge to `main`.

4. Warm the proxy and pkg.go.dev so the new version is discoverable promptly.
This is harmless and only triggers indexing of an already-public tag:

```console
GOPROXY=https://proxy.golang.org go list \
-m github.com/microsoft/azure-linux-dev-tools@v0.1.1
```

Then visit
`https://pkg.go.dev/github.com/microsoft/azure-linux-dev-tools@v0.1.1` once to
prompt the docs build.

5. (Optional, recommended) Create a GitHub Release for the tag and paste the new
`CHANGELOG.md` section as the release notes. A GitHub Release is separate from
the Git tag, so you can add notes even to a tag that already exists.

## Changelog

[`CHANGELOG.md`](../../../CHANGELOG.md) at the repo root follows the
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format. New sections are
drafted from the Conventional Commit history with
[git-cliff](https://git-cliff.org) and then curated by hand. Generate a draft
with:

```console
mage changelog
```

This prepends a `## [X.Y.Z]` section (the version is inferred from the commits)
above the previous release, skipping internal commit types — docs, test, chore,
build, ci, style, refactor, and dependency bumps — per
[`cliff.toml`](../../../cliff.toml). The result is a **draft**: git-cliff emits
commit subjects, not release prose, so prune and reword the entries into
user-facing notes before committing.

`mage changelog` is the single changelog flow — it runs identically locally and
in CI (CI just installs git-cliff first), so there is nothing to keep in sync
between the two. It needs git-cliff on your `PATH`; the version is pinned in
[`tools/git-cliff/Cargo.toml`](../../../tools/git-cliff/Cargo.toml) so Dependabot
and security scanners track it. Install it once:

```console
cargo binstall git-cliff # or: cargo install git-cliff --locked, or: brew install git-cliff
```

> Tip: the generated draft is a natural place to let Copilot help rewrite commit
> subjects into concise, user-facing notes before you commit.

## Fixing a bad release

Proxy versions are immutable — you cannot delete or move a published version.
To withdraw one, [retract][retract] it: add a `retract` directive to `go.mod`
describing the bad version(s) and release a new patch. `go get` will then skip
the retracted versions.

```go
// in go.mod
retract (
v0.1.1 // contains a build-breaking bug; use v0.1.2.
)
```

[pkgsite]: https://pkg.go.dev/github.com/microsoft/azure-linux-dev-tools
[semver]: https://semver.org/
[proxy]: https://proxy.golang.org/
[retract]: https://go.dev/ref/mod#go-mod-file-retract
2 changes: 2 additions & 0 deletions magefiles/magefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import (
//mage:import
"github.com/microsoft/azure-linux-dev-tools/magefiles/magecheckfix"
//mage:import
_ "github.com/microsoft/azure-linux-dev-tools/magefiles/magerelease"
//mage:import
_ "github.com/microsoft/azure-linux-dev-tools/magefiles/magemutation"
//mage:import
"github.com/microsoft/azure-linux-dev-tools/magefiles/magescenario"
Expand Down
Loading
Loading