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
30 changes: 3 additions & 27 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,33 +92,9 @@ git push origin your-feature-branch

## Troubleshooting common scenarios

### Version collision during feature development
### A Fix Carries No Version

If `main` releases a new version while you're still working on a feature branch:

1. **Sync your feature branch with main first:**
```bash
# First, update your local main to match remote
git checkout main
git pull origin main

# Then merge the updated main into your feature branch
git checkout your-feature-branch
git merge main --no-ff -m "Merge main to stay current"
```

2. **Check your branch's version** in any version files (e.g., `__version__.py` or `debian/changelog`)

3. **If main already released that version**, bump to the next version in your branch:
```bash
# Edit version files to next version
git add path/to/version/file
git commit -m "bump version to X.Y.Z+1"
```

4. **Then follow the normal merge workflow**: open or update your PR against `main`

**Example:** If your feature branch says "2.1.8" but main already released 2.1.8, update your branch to "2.1.9". Unsure? One of the core maintainers will handle release management.
Do not edit `debian/changelog` or `__version__.py` on a fix branch or a feature branch. The branch has no version to bump when `main` releases. If you need commits that landed on `main`, merge `main` into your branch. The release steps are in [Land a Fix and Cut a Release](RELEASING.md).

### Branch divergence recovery

Expand Down Expand Up @@ -160,7 +136,7 @@ If your local branch diverges from its remote (e.g., after a problematic rebase)

Using these prefixes in your PR title makes it easier for maintainers to triage and label incoming work at a glance.

- **Don't manually edit `debian/changelog`** - This is updated separately using `dch` from `devscripts`
- **Do not edit `debian/changelog` or `__version__.py` on a fix.** The release pull request updates the changelog with `dch`. See [Land a Fix and Cut a Release](RELEASING.md) and [Debchange](style/DCH.md).

## Pull requests

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ serves HTTPS, for example with Cloudflare redirect rules or GitHub Pages.
| [Git Workflow Guide](GIT_WORKFLOW.md) | Git fundamentals for beginners |
| [Contributing](CONTRIBUTING.md) | Detailed Git workflow, branch naming, PR guidelines, and code review |
| [Packaging Example](PACKAGING_EXAMPLE.md) | Complete walkthrough of creating a Debian package from scratch |
| [Land a Fix and Cut a Release](RELEASING.md) | Fix branches leave the version alone. The release pull request sets it |

### For Core Team

Expand Down
40 changes: 10 additions & 30 deletions RELEASE_PROCESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ This document covers the release procedures for core WLAN Pi team members. For g
## Overview

`main` is the only long-lived development branch. A release is a pull request into `main`
that bumps the version. When it merges, the deploy workflow builds the package
and uploads it to Packagecloud.
that sets the version. Follow [Land a Fix and Cut a Release](RELEASING.md).

Today, that merge uploads the package to Packagecloud `wlanpi/dev`. Promotion to `wlanpi/main` is still manual. The planned CI is not live yet. When it is, a final version with no `~` uploads to `wlanpi/main` and is tagged `v<version>`, with no manual promote.

## Branch strategy (Quick Reference)

Expand Down Expand Up @@ -38,7 +39,7 @@ General branching strategy. May vary per repo.
**See [Contributing](CONTRIBUTING.md) for detailed workflow**, including:
- Feature branch workflow and keeping branches in sync
- Merge strategy (squash merge into `main`)
- Version collision handling
- A fix branch carries no version ([Land a Fix and Cut a Release](RELEASING.md))
- Branch divergence recovery

## Creating a release
Expand All @@ -56,27 +57,7 @@ git checkout -b release/1.2.3

### 2. Update version and changelog

Update `debian/changelog` with the new version:

```bash
dch -v <version> "Release version <version>"
```

Example:
```bash
dch -v 1.2.3 "Release version 1.2.3"
```

For a first-party package the changelog version is `major.minor.patch` with
no Debian revision (`1.2.3`, not `1.2.3-1`). Set the same `major.minor.patch`
and pre-release in `__version__.py` (see [Version gate](#version-gate) and
[Source Format and Version](architecture/PACKAGING.md#source-format-and-version)).

Commit these changes:
```bash
git add debian/changelog path/to/__version__.py
git commit -m "Bump version to 1.2.3"
```
Follow [Publish a Release](RELEASING.md#publish-a-release). Use `dch -v <version>` with no Debian revision, then `dch -a` once per subject, then `dch -r ""`. Do not use `dch -i` while the changelog still has a Debian revision. Set `__version__.py` to the same `major.minor.patch` (see [Version gate](#version-gate) and [Source Format and Version](architecture/PACKAGING.md#source-format-and-version)).

### 3. Open and Merge the Release PR

Expand All @@ -93,8 +74,8 @@ deployment workflow. Pushing the version tag does not trigger it.
2. Uploaded to [wlanpi/dev](https://packagecloud.io/wlanpi/dev). Packagecloud
receives that `.deb` unchanged.
3. Test the package
4. After that test, the maintainer promotes the package by hand from
`wlanpi/dev` to `wlanpi/main`. See
4. After that test, ask a maintainer with Packagecloud access to copy the
package from `wlanpi/dev` to `wlanpi/main`. See
[Deploy to Packagecloud](#deploy-to-packagecloud).

The `~gha<UTC timestamp>` suffix is only on the GitHub Actions artifact
Expand Down Expand Up @@ -152,12 +133,11 @@ Maintained by:
`get-formatted-version-string`, `tag-release`)
- Workflow files in each repo, which call the reusable workflows above

Promotion from Packagecloud `wlanpi/dev` to `wlanpi/main` is a manual step.
The maintainer does it after testing. Deploy workflows upload to `wlanpi/dev`
only. `wlanpi-desktop` is the only repo with `promote-to-main.yml`, and that
Promotion from Packagecloud `wlanpi/dev` to `wlanpi/main` is still a manual step.
Deploy workflows upload to `wlanpi/dev` only. `wlanpi-desktop` is the only repo with `promote-to-main.yml`, and that
workflow runs only on `workflow_dispatch`. It builds the package and pushes
the `.deb` to `wlanpi/main`. See
[REPOS.md](REPOS.md#packagecloud-promotion).
[REPOS.md](REPOS.md#packagecloud-promotion). The planned replacement is [Publish a Release](RELEASING.md#publish-a-release).

### Version gate

Expand Down
94 changes: 94 additions & 0 deletions RELEASING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Land a Fix and Cut a Release

A fix does not change the package version. The release pull request does.

## What Is Live

Live now:

- The fix steps and the release steps on this page.
- A `debian/changelog` push to `main` uploads to [wlanpi/dev](https://packagecloud.io/wlanpi/dev).
- Promotion to [wlanpi/main](https://packagecloud.io/wlanpi/main) is done by hand. [Release Process](RELEASE_PROCESS.md#4-deploy-to-packagecloud) is that step.

Planned, and not live yet:

- The dev stamp.
- An upload to `wlanpi/main` when the release pull request merges.
- An automatic tag.

## Scope

This page covers first-party packages that use `debian/changelog`. A repackaged third-party package that uses `3.0 (quilt)` keeps its Debian revision. See [Source Format and Version](architecture/PACKAGING.md#source-format-and-version).

**pi-gen** and the **kernel** follow their own rules. They are out of scope.

WLAN Pi OS image versions are `YY.MM[.point][-type.sequence]-CODENAME`. The git tag is that string with no `v` prefix, for example `26.08-Cortado`. A dispatched build publishes a GitHub pre-release, and a maintainer promotes a final build to the latest stable release by hand. See [Release a WLAN Pi OS image](https://github.com/WLAN-Pi/pi-gen/blob/trixie64/docs/RELEASING.md).

The kernel has no `debian/changelog`. The next 2712 kernel is `7.3.1` or later. Planned CI maps an upstream `-rcN` to `~rcN`, and it refuses an upload that does not sort above the top version on both `wlanpi/dev` and `wlanpi/main`.

The first native version of a package that is still published with a Debian revision is the next upstream version. Do not reuse the `-1` version. Those first native versions are core `2.4.13`, webui `1.21.19`, fpms `1.4.26`, profiler `2.1.9`, and mcp `0.7.1`.

## Land a Fix

1. Branch from `main`.
2. Change the package. Do not edit `debian/changelog`. Do not edit `__version__.py`. Do not run `dch`.
3. In the pull request, write one line that says what changed for the person installing the package.
4. Squash-merge to `main`. Use that line as the merge subject, and keep the pull request number. [Contributing](CONTRIBUTING.md#merging-for-maintainers) says squash merge is the default.

That subject is the release note. A fix branch has no version. If `main` moves, merge `main` into the branch. Do not add a version.

## Where a Dev Build Goes

When the stamp is live, a push to `main` that is not a release builds in the CI workspace and uploads the `.deb` to `wlanpi/dev`. Git stays on the last release. CI does not tag that build.

The deb version is the next patch, then `~dev<YYYYMMDD>.<run_id>.<run_attempt>+g<sha>`. Strip a Debian revision before adding 1 to the patch, so `2.4.12-1` yields `2.4.13~dev<YYYYMMDD>.<run_id>.<run_attempt>+g<sha>`.

In that `.deb`, `__version__.py` is `X.Y.Z.dev<YYYYMMDD>` in PEP 440. For the same build the deb version is `X.Y.Z~dev<YYYYMMDD>.<run_id>.<run_attempt>+g<sha>`.

`dpkg` 1.22.6 sorts `2.4.12-1` below `2.4.13~dev20261024.1842.1+gabcdef1`, below `2.4.13~rc1`, below `2.4.13`.

## Choose the Next Release Version

The stamp uses the next patch (once the stamp is live). The release pull request can ship that patch, or a higher minor or major.

After `2.4.13` is the committed version, dev builds are `2.4.14~dev...` (once the stamp is live). A release of `2.5.0` sorts above `2.4.14~dev20261024.1842.1+gabcdef1`. The next push then stamps `2.5.1~dev...` (once the stamp is live).

To put dev builds on `2.5.0` before that release, commit changelog `2.5.0~rc1` and set `__version__.py` to `2.5.0rc1`. Later pushes stamp `2.5.0~rc1+dev<YYYYMMDD>.<run_id>.<run_attempt>+g<sha>` (once the stamp is live). That sorts above `2.5.0~rc1` and below `2.5.0`. `dpkg` 1.22.6 also sorts `2.4.14~dev20261024.1842.1+gabcdef1` below `2.5.0~rc1`.

`2.4.12` sorts below `2.4.12-1`. Do not drop a Debian revision from a version that is already published. The version form is in [Source Format and Version](architecture/PACKAGING.md#source-format-and-version).

## Publish a Release

Skip the release when every subject since the last final release is docs-only or CI-only.

1. On current `main`, before the release commit exists, list the subjects since the last final release. Use its `v<last>` tag when that tag exists.

```bash
git log --first-parent --reverse --format='%s' v2.4.12..HEAD
```

Core's last final tag is `v2.4.12`. After `2.4.13` is released, start at `v2.4.13`. When the last final release has no tag, use that release's commit in place of the tag. An rc commit is not a valid start. A fix that edited `debian/changelog` is not a valid start.

Check [wlanpi/dev](https://packagecloud.io/wlanpi/dev) and [wlanpi/main](https://packagecloud.io/wlanpi/main). Pick a version that sorts above every version of this package on both repos. Treat a version on either repo as already used. Packagecloud rejects a duplicate filename, so after `2.5.0~rc1` is uploaded the next candidate is `2.5.0~rc2`.

2. Branch `release/<version>` from `main`. Drop docs-only subjects and CI-only subjects. Write the stanza with no Debian revision. `dch -v` adds one placeholder bullet. Delete that bullet, or keep it on purpose. Run `dch -a` once for each remaining subject.

```bash
dch -v 2.4.13 "Release version 2.4.13"
dch -a "Fix the capture timeout (#431)"
dch -r ""
```

On a changelog that still says `2.4.12-1`, `dch -i` writes `2.4.12-2`. Do not use `dch -i` for this release. On the first native cut, `dch` warns `New package version is Debian native whilst previous version was not`. That warning is expected. [Debchange](style/DCH.md) covers `DEBFULLNAME` and `DEBEMAIL`.

Rewrite a bullet when the subject is unclear. Add a reference only when the commit body already has it.

3. Set `__version__.py` to the same `major.minor.patch` in repos that have the file. For changelog `2.4.13~rc1`, set `__version__.py` to `2.4.13rc1`.

4. On the first native release, set `debian/source/format` to `3.0 (native)` in that same commit.

5. Open one pull request and merge it.

When the planned CI is live, that merge uploads a final version with no `~` to `wlanpi/main` and tags `v<version>`. A version that contains `~` uploads to `wlanpi/dev` and is not tagged. Repos whose deploy workflow does not call `tag-release` still use [Tag the Release](RELEASE_PROCESS.md#5-tag-the-release).

6. After the deploy, check both `wlanpi/dev` and `wlanpi/main` before you call it released. While promotion is by hand, call it released only once that version is on both, which is after the copy.
10 changes: 3 additions & 7 deletions style/DCH.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,11 @@ You can run debchange from the root of the repository as debchange will climb th
(venv) wlanpi@wlanpi:[~/dev/wlanpi-app]: debchange
```

### Update an existing version entry
### Add a Release Entry

Use `dch -i` when adding a changelog entry for a new upload. On a native
package, `-i` increments the upstream version (`1.2.3` becomes `1.2.4`).
On a package whose version still has a Debian revision, `-i` increments
that revision. First-party WLAN Pi packages are native; the version form
is in [Source Format and Version](../architecture/PACKAGING.md#source-format-and-version).
A fix does not run `dch`. A release uses `dch -v <version>` with no Debian revision, then `dch -a` once per subject, then `dch -r ""`. On a changelog that still says `2.4.12-1`, `dch -i` writes `2.4.12-2`. Do not use `dch -i` for a first-party release. The procedure is [Land a Fix and Cut a Release](../RELEASING.md). The version form is in [Source Format and Version](../architecture/PACKAGING.md#source-format-and-version).

If you want to edit the changelog without changing the version or adding a new entry, use `-e` instead of `-i`.
Use `dch -e` to edit the current stanza without adding a version or a bullet.

## debchange - versions

Expand Down
14 changes: 5 additions & 9 deletions style/WORKFLOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@

## Releases

Each release should contain appropriate git tagging and versioning.
A fix does not change `debian/changelog`. Do not push a changelog change until the release is ready to deploy. The procedure is [Land a Fix and Cut a Release](../RELEASING.md).

CI/CD will be setup and triggered by pushes to `{repo}/debian/changelog`.

So, this means you should have some hope that your hotfix or feature works as intended. It would be a good idea to format, lint, and test the code at this stage.

Thus, do not push changes to the `changelog` until you are ready to deploy.
Today, a push of `debian/changelog` to `main` starts the deploy. Format, lint, and test before that push.

## Setup development environment

Expand All @@ -34,7 +30,7 @@ pip install .[testing]

## Debchange from devscripts

Create a changelog entry for a new release: `dch -i`
Create a changelog entry for a release with `dch -v <version>`, then `dch -r ""`. Do not use `dch -i` while the version still has a Debian revision.

Describe what you changed, fixed, or enhanced.

Expand All @@ -44,15 +40,15 @@ See the [DCH](DCH.md) page for further reading.

## Versioning

Each release requires versions to be updated in two locations:
A fix updates neither file below. The release pull request updates both:

1. `debian/changelog` via `debchange`
2. The Python package version file (e.g. `wlanpi_yourapp/__version__.py`) via manual update

Deploy workflows for Python repos fail unless `debian/changelog` and
`__version__.py` have the same `major.minor.patch` and the same pre-release
(`a`, `b`, or `rc` and its number). The Debian revision, `~dev` snapshots, and
`.postN` are not compared. Bump both in the same change.
`.postN` are not compared. The release pull request changes both files together.

Please note that Python package versioning should follow PEP 440. https://www.python.org/dev/peps/pep-0440/

Expand Down