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
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,6 @@ Apache-2.0 (consistent with AirStack)
- **Maintainer:** Your Name (your.email@example.com)
- **Contributors:** List additional contributors here

## Changelog

### Version 0.0.1 (YYYY-MM-DD)
- Initial implementation
- TODO: Add changelog entries as the module evolves
<!-- No per-README changelog: change records live in the versioned Release
Notes (docs/release_notes/index.md); this README describes only the
current system. -->
75 changes: 36 additions & 39 deletions .agents/skills/bump-version-and-release/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: bump-version-and-release
description: Bump the AirStack VERSION in .env (semver) before merging a PR that changes Docker image content, and update CHANGELOG. Required to pass the check-version-increment gate and to trigger the docker-build release workflow.
description: Bump the AirStack VERSION in .env (semver) before merging a PR that changes Docker image content, and record the change in the versioned Release Notes (docs/release_notes/index.md). Required to pass the check-version-increment gate and to trigger the docker-build release workflow.
license: BSD-3-Clause-Clear
metadata:
author: AirLab CMU
Expand Down Expand Up @@ -127,16 +127,21 @@ Open `/.env` and change exactly the `VERSION=` line. Keep the surrounding commen

The validator strips surrounding `"` or `'`, so either quoting style works, but match the existing style (double quotes).

### 3. Update `CHANGELOG.md`
### 3. Update the Release Notes

Add an entry under `## [Unreleased]` describing your change (see "CHANGELOG Conventions" below). For a true release (no pre-release suffix), promote `[Unreleased]` to a new dated version section.
All change records live in the versioned Release Notes page,
`docs/release_notes/index.md` (there is no CHANGELOG.md — this page is the
single source). Add your bullets under the current version's `##` section
(see "Release Notes Conventions" below). For a true release (no pre-release
suffix), stamp that section's heading with the release date and open a fresh
`## <next-version> (Unreleased)` section above it.

### 4. Verify locally

```bash
airstack version # prints the new value
grep '^VERSION=' .env # sanity-check the literal line
git diff .env CHANGELOG.md # review the diff
git diff .env docs/release_notes/index.md # review the diff
```

Optional regex preflight (mirrors the CI check):
Expand All @@ -155,19 +160,25 @@ Bump version to 0.18.0-alpha.8

Recent commits in this repo use exactly this phrasing (`Bump version to 0.17.0`, `Bump version to 0.16.1`).

## CHANGELOG Conventions
## Release Notes Conventions

`CHANGELOG.md` follows [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/) and Semantic Versioning. The literal layout in the repo is:
`docs/release_notes/index.md` is the versioned change record rendered on
the docs site — one `##` section per version, newest first, with the current
in-progress version marked `(Unreleased)`. It is also the ONLY place
change-relative language ("changed from", "renamed", "removed", RFC/PR
references) is allowed; feature docs describe only the current system (see
the `write-mkdocs-documentation` skill).

Layout:

```markdown
# Changelog
# Release Notes

All notable changes to this project will be documented in this file.
<standing intro paragraph — do not edit per change>

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).
## <VERSION> (Unreleased)

## [Unreleased]
<optional narrative paragraph for the release theme>

### Added

Expand All @@ -177,50 +188,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- <bullet>

### Fixed
### Removed

- <bullet>

## [1.0.0] - 2024-12-19

First official public release.

### Added

- <bullets>

### Fixed

- <bullets>

### Changed

- <bullets>
- <bullet>

### Removed
## <PREV VERSION> — <YYYY-MM-DD>

- <bullets>
...
```

Rules:

- Use the H2 sections **Added**, **Changed**, **Fixed**, **Removed**, **Deprecated**, **Security** as needed (Keep a Changelog standard set).
- For pre-release bumps (`-alpha.N`, `-beta.N`, `-rc.N`), keep your bullets under `## [Unreleased]`. Do not create a section per alpha.
- For a release bump (no suffix), rename `[Unreleased]` to `## [<VERSION>] - <YYYY-MM-DD>` and add a fresh empty `## [Unreleased]` above it.
- Use ISO date format `YYYY-MM-DD`.
- Write user-facing prose, not commit log dumps. Mention new modules, breaking changes, and notable behavior shifts.
- Use the H3 sections **Added**, **Changed**, **Fixed**, **Removed**, **Deprecated**, **Security** as needed; a release may also open with a short narrative and breaking-changes subsection.
- For pre-release bumps (`-alpha.N`, `-beta.N`, `-rc.N`), keep your bullets under the current `(Unreleased)` section. Do not create a section per alpha.
- For a release bump (no suffix), retitle the section to `## <VERSION> — <YYYY-MM-DD>` and open a fresh `## <next-version> (Unreleased)` above it.
- Write user-facing prose, not commit log dumps. Mention new modules, breaking changes, and notable behavior shifts, with what changed FROM what.

## Common Pitfalls

- **Forgetting the bump.** The `check-version-increment` job fails with `::error::VERSION must be strictly greater than the base branch version.` Bump and force-push the branch.
- **Invalid semver.** Forms like `1.2`, `1.2.3-rc1`, `1.2.3-dev`, `1.2.3+sha.abc`, `v1.2.3`, or empty strings fail with `::error::VERSION '<x>' does not match the required format.` The only allowed pre-release tags are exactly `alpha`, `beta`, `rc`, each followed by a literal dot and an integer (e.g. `-rc.1`, never `-rc1`).
- **Going backwards.** `0.18.0 → 0.18.0-rc.1` looks like progress but is a regression: release > rc. Always move forward in the comparison tuple.
- **Two PRs racing for the same number.** Whichever merges last wins; the loser's `check-version-increment` will start failing the moment the base advances past it. Rebase on the updated base branch and bump again.
- **Bumping but forgetting the CHANGELOG.** No CI gate enforces this, but reviewers will (and the release docs workflow lists what shipped per version, so missing entries become invisible history).
- **Bumping but forgetting the Release Notes.** No CI gate enforces this, but reviewers will (and the versioned docs deploys snapshot the page per release, so missing entries become invisible history).
- **Bumping for pure docs PRs.** Wastes a registry tag. Prefer to keep docs-only changes off `.env` if possible — but if the gate is failing, an alpha bump is the path of least resistance.
- **Editing `VERSION=` quoting.** The extractor regex `^VERSION\s*=\s*["\']?([^"\'#\s]+)` handles double quotes, single quotes, or no quotes, and stops at `#`/whitespace. Don't add inline comments after the value (e.g. `VERSION="0.18.1" # bumped`) — the trailing `# bumped` will be stripped from the value but obscures intent; put comments on their own line above.
- **Touching only sub-compose `.env` files.** The check looks at the **repo-root** `.env` only. `robot/docker/.env` and friends are container env files, not the version source of truth.
- **Force-pushing after merge to fix CHANGELOG.** Don't. Land a follow-up PR with the CHANGELOG correction (and, by the rules above, another tiny VERSION bump).
- **Force-pushing after merge to fix Release Notes.** Don't. Land a follow-up PR with the correction (docs-only, so no VERSION bump needed unless the gate demands one).

## Release Checklist

Expand All @@ -229,8 +227,8 @@ For a normal feature/fix PR:
1. [ ] Confirm the PR changes Docker image content or otherwise warrants a bump (see "When to Use").
2. [ ] Pick the bump type (see "Choosing the Bump Type").
3. [ ] Edit `/.env` — change only the `VERSION=` line.
4. [ ] Update `CHANGELOG.md` under `## [Unreleased]`.
5. [ ] `airstack version` and `git diff .env CHANGELOG.md` to verify.
4. [ ] Add your bullets to `docs/release_notes/index.md` under the current `(Unreleased)` version section.
5. [ ] `airstack version` and `git diff .env docs/release_notes/index.md` to verify.
6. [ ] Commit (`Bump version to <new>` is the established style).
7. [ ] Push and open the PR. Confirm `Check VERSION Increment` passes green.
8. [ ] After review, merge into `develop` (or `main` per branch policy).
Expand All @@ -240,7 +238,7 @@ For a true release (dropping the pre-release suffix):

1. [ ] Land final fixes on `develop` with `-rc.N` bumps.
2. [ ] Open a PR that bumps `VERSION="X.Y.Z-rc.N"` → `VERSION="X.Y.Z"`.
3. [ ] In the same PR, promote `## [Unreleased]` to `## [X.Y.Z] - YYYY-MM-DD` and add a fresh empty `## [Unreleased]`.
3. [ ] In the same PR, retitle the Release Notes section to `## X.Y.Z YYYY-MM-DD` and open a fresh `## <next-version> (Unreleased)` above it.
4. [ ] Merge to `main`.
5. [ ] Wait for `docker-build.yml` to push and sign all images.
6. [ ] Create a GitHub Release with tag `X.Y.Z` (matching `VERSION` exactly). Publishing the release fires `deploy_docs_from_release.yaml`, which runs `mike deploy --push --update-aliases X.Y.Z latest` and updates the versioned docs site.
Expand All @@ -249,13 +247,12 @@ For a true release (dropping the pre-release suffix):
## References

- [`/.env`](../../../.env) — source of truth for `VERSION=`
- [`/CHANGELOG.md`](../../../CHANGELOG.md) — release history
- [`/docs/release_notes/index.md`](../../../docs/release_notes/index.md) — the versioned Release Notes (release history)
- [`/.github/workflows/check-version-increment.yml`](../../../.github/workflows/check-version-increment.yml) — the PR gate (semver regex lives here)
- [`/.github/workflows/docker-build.yml`](../../../.github/workflows/docker-build.yml) — build/push/sign on tag change
- [`/.github/workflows/deploy_docs_from_release.yaml`](../../../.github/workflows/deploy_docs_from_release.yaml) — versioned docs on release
- [`/.github/workflows/deploy_docs_from_main.yaml`](../../../.github/workflows/deploy_docs_from_main.yaml) and [`deploy_docs_from_develop.yaml`](../../../.github/workflows/deploy_docs_from_develop.yaml) — branch-tracking docs aliases
- [`/airstack.sh`](../../../airstack.sh) — defines `airstack version` and `get_VERSION` (used everywhere image tags are built)
- [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/)
- [Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html)

## Related Skills
Expand Down
14 changes: 6 additions & 8 deletions .agents/skills/update-documentation/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -333,14 +333,12 @@ Specify license (typically Apache-2.0 for AirStack).
- **Maintainer:** Name (email)
- **Contributors:** List contributors

## Changelog

### Version X.Y.Z (YYYY-MM-DD)
- Feature: Added new capability
- Fix: Resolved issue with X
- Change: Modified behavior of Y
```

Do not add a per-README "Changelog" section — change records live in the
versioned Release Notes (`docs/release_notes/index.md`), and READMEs
describe only the current system.

**Reference template:** `../add-ros2-package/assets/package_template/README.md`

### 2. Update mkdocs.yml Navigation
Expand Down Expand Up @@ -585,10 +583,10 @@ class YourClass:

If your module introduces breaking changes or deprecations:

**File:** `CHANGELOG.md` (repository root)
**File:** `docs/release_notes/index.md` (the versioned Release Notes — the only place change-relative language belongs; feature docs describe only the current system)

```markdown
## [Unreleased]
## <current version> (Unreleased)

### Added
- New module: your_package for <purpose>
Expand Down
88 changes: 84 additions & 4 deletions .agents/skills/write-mkdocs-documentation/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,76 @@ metadata:

## Core Principles

### 0. Docs Are Standalone Snapshots (read this first)

Documentation describes the system **as it exists now**, for a reader
encountering it fresh — someone with no access to the development history,
the diffs, the RFCs, or the conversations that produced the current design.
It is not a changelog, not a diff annotation, and not a record of decisions.

**Never include change-relative language in docs pages.** Prohibited patterns:

- "changed from X to Y", "updated from X", "previously this was X"
- "renamed from X", "moved from X", "no longer does X"
- "decided by [person]", "pinned by [person]", "per discussion with [person]"
- "as of this PR / this change / this version" framing inside feature docs
- References to RFCs, design discussions, issue/PR numbers, or review
decisions as justification ("per RFC #379", "see discussion #380")
- Any sentence that only makes sense if the reader knows the prior state

The test: **a first-time reader must be able to parse every sentence without
knowing any previous version, diff, or conversation.** If a sentence fails
that test, it belongs in Release Notes, not in the page.

**Where change context goes: Release Notes.** All change-relative
information coalesces into a single Release Notes page for the current
version (`docs/release_notes/index.md`, one `##` section per version). That
page is the only place where "changed from", "replaces", "deprecated",
"decided in review", and RFC/PR references are appropriate.

When your edit involves a behavioral change, do both:

1. Update the relevant docs pages to describe only the new behavior, written
as if it had always been that way.
2. Add an entry to the current version's Release Notes page describing what
changed, from what, and (if relevant) why or who drove the decision.

If a Release Notes page for the current version does not exist, create one.
Never scatter per-page "changelog"/"migration" sections across the docs.

**Motivation before mechanics.** Every page (and every major section) starts
with a brief motivation: why this component exists and why it is built the
way it is — one short paragraph. Only then the details (API, configuration,
usage, internals). A reader should be able to answer "why would I use this,
and why does it look like this?" before the first code block or parameter
table.

❌ **Bad opening:**

> AirStack builds are defined in `docker-compose.yaml` with per-module
> Dockerfiles. The following build arguments are supported: ...

✅ **Good opening:**

> AirStack targets both x86 workstations and Jetson/Orin robots from a
> single codebase, so its build system is organized around per-module Docker
> images rather than one monolithic environment. This keeps modules
> independently buildable and lets each one pin platform-specific
> dependencies without breaking the others. Builds are defined in
> `docker-compose.yaml` with per-module Dockerfiles: ...

**Standalone-snapshot checklist** (verify before finalizing any docs edit):

- [ ] No sentence requires knowledge of a previous version, a diff, an RFC,
or a conversation to parse.
- [ ] All change-relative content has been moved to the current version's
Release Notes page.
- [ ] The page/section opens with motivation (why it exists, why this
design) before details.
- [ ] A first-time reader could use the page without any other context.
- [ ] Names, defaults, and behaviors described match the current code, not
an intermediate state.

### 1. Progressive Disclosure

**Organize for newcomers first, depth second:**
Expand Down Expand Up @@ -921,11 +991,14 @@ airstack up robot-desktop # Start robot container
grep -r "old_topic_name" docs/
```

2. **Update all references**
2. **Update all references** — rewrite each page to describe only the new
behavior, as if it had always been that way (no "renamed from",
"no longer", "previously")
3. **Update diagrams** (if architecture changed)
4. **Add migration notes** (if breaking change)
5. **Update CHANGELOG.md**
6. **Verify all links still work**
4. **Record the change in Release Notes** (`docs/release_notes/index.md`,
under the current version's section) — the only place change-relative
language belongs
5. **Verify all links still work**

### Periodic Reviews

Expand All @@ -941,6 +1014,13 @@ airstack up robot-desktop # Start robot container

When creating or updating documentation:

- [ ] No change-relative language (no "previously", "renamed from",
"no longer", RFC/PR/discussion references) — pages are standalone
snapshots of the current system
- [ ] Behavioral changes recorded in `docs/release_notes/index.md` under
the current version's section, not as per-page migration notes
- [ ] Page and major sections open with motivation (why it exists, why this
design) before mechanics
- [ ] Content follows progressive disclosure (concept → example → depth)
- [ ] All lists have blank line before them
- [ ] Code blocks have language tags
Expand Down
7 changes: 7 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"permissions": {
"allow": [
"Bash(docker compose * config*)"
]
}
}
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ PROJECT_NAME="airstack"
# If you've run ./airstack.sh setup, then this will auto-generate from the git commit hash every time a change is made
# to a Dockerfile or docker-compose.yaml file. Otherwise this can also be set explicitly to make a release version.
# auto-generated from git commit hash
VERSION="0.20.0-alpha.8"
VERSION="0.20.0-alpha.9"
# Image-tag discriminator ONLY (appears in the image tag suffix, e.g. ..._robot-x86-64_dev).
# No Dockerfile consumes it: "prebuilt" does NOT bake the built ros_ws into the image today —
# a real prebuilt (workspace-baked) stage is future work. Keep "dev" (mounted code, built live).
Expand Down
Loading
Loading