mirror of
https://github.com/linux-msm/qdl.git
synced 2026-10-07 06:29:17 -07:00
Describe the kernel-style stable branches (qdl-X.Y.y) agreed for shipping urgent fixes independently of master: cut the branch from the release tag immediately after tagging, backport fixes that landed on master with cherry-pick -x through stable-targeted pull requests (CI runs on those unchanged), and cut point releases (vX.Y.Z) from the branch with the same flow as a normal release. Signed-off-by: Igor Opaniuk <igor.opaniuk@oss.qualcomm.com>
223 lines
7.7 KiB
Markdown
223 lines
7.7 KiB
Markdown
# Releasing QDL
|
|
|
|
This document describes how a new QDL release is cut, from preparing the
|
|
changelog to publishing the GitHub release with prebuilt artifacts.
|
|
|
|
Releases are versioned `vMAJOR.MINOR` (for example `v2.8`). Release
|
|
candidates append an `-rcN` suffix (`v2.8-rc1`, `v2.8-rc2`, ...).
|
|
|
|
The process is, in short:
|
|
|
|
- [1. Populate the changelog](#1-populate-the-changelog)
|
|
- [2. Open the changelog PR and tag a release candidate](#2-open-the-changelog-pr-and-tag-a-release-candidate)
|
|
- [3. Iterate on release candidates](#3-iterate-on-release-candidates)
|
|
- [4. Merge the changelog PR and apply the release tag](#4-merge-the-changelog-pr-and-apply-the-release-tag)
|
|
- [5. Create the GitHub release](#5-create-the-github-release)
|
|
- [Stable branches](#stable-branches)
|
|
|
|
Throughout, export the version once so the commands below can be copied
|
|
verbatim:
|
|
|
|
```bash
|
|
VERSION=v2.8
|
|
```
|
|
|
|
## 1. Populate the changelog
|
|
|
|
`CHANGELOG.md` mirrors the GitHub releases: one section per version, listing
|
|
the pull requests merged since the previous release. Add a new section at the
|
|
top for the upcoming version.
|
|
|
|
GitHub can produce the raw list of merged PRs for the range, which is the same
|
|
content used in the existing entries:
|
|
|
|
```bash
|
|
# Everything merged since the previous release:
|
|
gh api repos/linux-msm/qdl/releases/generate-notes \
|
|
-f tag_name="${VERSION}" -f target_commitish=master \
|
|
-f previous_tag_name="$(git describe --tags --abbrev=0 master)" \
|
|
--jq .body
|
|
```
|
|
|
|
Format the output to match the existing entries (PR references as `#NNN`
|
|
links, a `### What's Changed` and `### New Contributors` subsection, and a
|
|
`**Full Changelog**` compare link), and prepend it to `CHANGELOG.md` under a
|
|
new `## [vX.Y](...) - YYYY-MM-DD` heading.
|
|
|
|
Once the changelog draft is ready, ask people to start testing the current
|
|
`master` so issues are found before the tag is cut.
|
|
|
|
## 2. Open the changelog PR and tag a release candidate
|
|
|
|
Open a pull request with the changelog update. With that PR up, tag the latest
|
|
`master` as the first release candidate so testers have a stable reference
|
|
point to build from:
|
|
|
|
```bash
|
|
git fetch upstream
|
|
git tag "${VERSION}-rc1" upstream/master
|
|
git push upstream "${VERSION}-rc1"
|
|
```
|
|
|
|
Ask testers to exercise the hardware-in-the-loop (HIL) suite against real
|
|
hardware. The suite is skipped by default and only runs when pointed at an
|
|
attached EDL device:
|
|
|
|
```bash
|
|
meson setup build
|
|
QDL_HIL_BUILD=/path/to/build-images \
|
|
QDL_HIL_STORAGE=<emmc|ufs|nvme|...> \
|
|
meson test -C build --suite hil --print-errorlogs
|
|
```
|
|
|
|
The release must be validated across all four supported host/driver
|
|
combinations:
|
|
|
|
- Windows + QUD driver: the official Qualcomm QDLoader 9008 driver
|
|
(`qdl --backend=qud ...`).
|
|
- Windows + WinUSB driver / libusb (`qdl --backend=usb ...`).
|
|
- Linux.
|
|
- macOS.
|
|
|
|
In addition, validate VIP (Validated Image Programming) mode: generate the
|
|
digest tables with `--create-digests`, sign them, and flash a board with
|
|
`--vip-table-path` to confirm secure-boot flashing still works end to end. See
|
|
the VIP section in [README.md](README.md) for the full workflow.
|
|
|
|
## 3. Iterate on release candidates
|
|
|
|
Collect the testing results. If a regression is found, fix it on `master` and
|
|
cut the next candidate (`-rc2`, `-rc3`, ...):
|
|
|
|
```bash
|
|
git fetch upstream
|
|
git tag "${VERSION}-rc2" upstream/master
|
|
git push upstream "${VERSION}-rc2"
|
|
```
|
|
|
|
Repeat until a candidate passes all four configurations (and VIP validation)
|
|
cleanly. That commit becomes the stable release.
|
|
|
|
## 4. Merge the changelog PR and apply the release tag
|
|
|
|
Merge the changelog PR. Then tag the resulting `master` commit with the final,
|
|
immutable release tag.
|
|
|
|
Note on tag type: the history is mixed. `v2.4` is an annotated tag while
|
|
`v2.5`, `v2.6` and `v2.7` are lightweight tags (that is what GitHub's "create
|
|
release" UI produces). Prefer an annotated tag for releases: it records the
|
|
tagger, date and a message, and is what `git describe` expects.
|
|
|
|
```bash
|
|
git fetch upstream
|
|
git tag -a "${VERSION}" -m "qdl ${VERSION}" upstream/master
|
|
git push upstream "${VERSION}"
|
|
```
|
|
|
|
A tag is a ref, not a branch. `git push upstream "${VERSION}"` publishes the
|
|
tag itself; it does not push to the `master` branch. Once pushed, treat the tag
|
|
as immutable: never move or delete it.
|
|
|
|
(If matching the recent lightweight-tag convention is preferred instead, drop
|
|
the `-a`/`-m` flags: `git tag "${VERSION}" upstream/master`.)
|
|
|
|
## 5. Create the GitHub release
|
|
|
|
The `Buildtest` workflow already builds and uploads per-platform binaries for
|
|
every push. Reuse those artifacts for the release rather than rebuilding.
|
|
|
|
Download the artifacts from the green `Buildtest` run for the tagged commit and
|
|
bundle each platform into its own archive:
|
|
|
|
```bash
|
|
# Find the successful Buildtest run that built the tagged commit. Filtering
|
|
# with --commit happens server-side, so it is not limited to the most recent
|
|
# runs (a plain `gh run list` only fetches the latest 20).
|
|
SHA=$(git rev-parse "${VERSION}^{commit}")
|
|
RUN_ID=$(gh run list --workflow build.yml --commit "${SHA}" --status success \
|
|
--json databaseId --jq '.[0].databaseId')
|
|
|
|
# Pull every platform artifact into dist/<artifact-name>/...
|
|
rm -rf dist && gh run download "${RUN_ID}" -D dist
|
|
|
|
# Zip each platform directory into a single release asset
|
|
( cd dist && for d in */; do
|
|
name="${d%/}"
|
|
zip -r "${name}-${VERSION}.zip" "${d}"
|
|
done )
|
|
```
|
|
|
|
Extract this release's notes straight from `CHANGELOG.md` (the block between
|
|
this version's heading and the next `## [` heading) and create the release,
|
|
attaching the zipped artifacts:
|
|
|
|
```bash
|
|
NOTES=$(awk -v v="${VERSION}" '
|
|
$0 ~ ("^## \\[" v "\\]") { found=1; next }
|
|
/^## \[/ && found { exit }
|
|
found { print }
|
|
' CHANGELOG.md | sed '1{/^$/d}')
|
|
|
|
echo "Release notes preview:"
|
|
echo "---"
|
|
echo "${NOTES}"
|
|
echo "---"
|
|
read -r -p "Create GitHub release ${VERSION}? [y/N] " reply
|
|
[ "${reply}" = "y" ] || { echo "GitHub release skipped"; exit 0; }
|
|
|
|
gh release create "${VERSION}" dist/*.zip \
|
|
--title "${VERSION}" \
|
|
--notes "${NOTES}"
|
|
|
|
echo "GitHub release created: $(gh release view "${VERSION}" --json url -q .url)"
|
|
```
|
|
|
|
The release name matches the existing convention (the tag itself, for example
|
|
`v2.8`). After publishing, sanity-check the release page: confirm the notes
|
|
rendered correctly and that every platform archive is attached.
|
|
|
|
## Stable branches
|
|
|
|
After a release, critical fixes reach users through kernel-style stable
|
|
branches named `qdl-X.Y.y` (for `v2.8`: `qdl-2.8.y`). A point release
|
|
(`v2.8.1`, `v2.8.2`, ...) is then cut from the stable branch, so urgent
|
|
fixes never have to wait for - or ship - whatever is in flight on
|
|
`master`.
|
|
|
|
### Cut the branch immediately after the release
|
|
|
|
Right after the normal release flow tags the release on `master`
|
|
(step 4), create the stable branch from the tag:
|
|
|
|
```bash
|
|
git fetch upstream
|
|
git branch "qdl-${VERSION#v}.y" "${VERSION}"
|
|
git push upstream "qdl-${VERSION#v}.y"
|
|
```
|
|
|
|
### Maintain the branch (backports)
|
|
|
|
When a bug affecting the release gets fixed, the fix lands on `master`
|
|
first, through the normal PR flow. Then backport it, with `-x` so the
|
|
commit message records which `master` commit it was cherry-picked from:
|
|
|
|
```bash
|
|
git checkout "qdl-${VERSION#v}.y"
|
|
git cherry-pick -x <sha>
|
|
```
|
|
|
|
Open a pull request targeting the stable branch. CI runs on it
|
|
unchanged, since the workflows trigger on any pull request regardless
|
|
of its base branch.
|
|
|
|
### Cut a point release when warranted
|
|
|
|
When the branch has accumulated fixes worth shipping - or a security
|
|
fix forces one:
|
|
|
|
- Update `CHANGELOG.md` on the stable branch with a section for the
|
|
point release (for example `v2.8.1`).
|
|
- Tag and publish from the stable branch, following the same flow as a
|
|
normal release (steps 2-5) with `VERSION=v2.8.1` and the stable
|
|
branch taking the place of `master`.
|