Skip to content

Latest commit

 

History

History
222 lines (168 loc) · 7.66 KB

File metadata and controls

222 lines (168 loc) · 7.66 KB

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:

Throughout, export the version once so the commands below can be copied verbatim:

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:

# 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:

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:

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

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.

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:

# 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:

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:

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:

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.