* Rewrite build-version and all build-zip bash scripts to python * Add executable permissions to python build scripts * Use python build script for kmod in CI * Fix * Enhance kmod build script, add/fix docs, CI edits * Delete remaining build-zip bash scripts * Delete remaining build-zip bash scripts
3.4 KiB
Releasing
Model
VERSIONfile = the last released version onmain. It is only modified byrelease.py.changelog.d/*.md= work in progress. One Markdown file per unreleased entry, accumulated via./scripts/changelog.pyduring normal development. See changelog.md.- Intermediate builds (main, feature branches, local) get a version string derived from
git describe— propagated intomodule.prop/ APKversionNameat build time. See build versions below.
Cutting a release
- Make sure everything you want in the release is merged to
mainandchangelog.d/contains exactly the fragments that should appear in the release notes. - Run the release script with the new version:
Atomically:./scripts/release.py 0.6.2- rotates every fragment under
changelog.d/intohistory[0]withversion: "0.6.2"and deletes the fragment files, - writes
0.6.2toVERSION, - patches
versionName/versionCodein every module.prop, Cargo.toml, andbuild.gradle.kts, - regenerates
CHANGELOG.mdandupdate-json/changelog.md.
- rotates every fragment under
- Commit, tag, push:
git commit -am "chore: release v0.6.2" git tag v0.6.2 git push git push origin v0.6.2 - Wait for CI to finish the build. CI creates a draft GitHub release with all artifacts attached and release notes extracted from
CHANGELOG.md— review it on the Releases page and click Publish release when you're happy. - Generate update-json files pointing at the new release assets:
./scripts/update-json.sh - Commit and push:
git commit -am "chore: update-json for v0.6.2" git push
Why update-json is a separate commit
Update-json must be committed after the GitHub release is published (i.e. after you promote the draft to public). Magisk and KSU fetch these files to decide whether an update is available, then download the zip from the URL inside. Draft releases are private — their asset URLs require auth — so update-json must not point at them.
Notes
versionCodeis derived automatically byrelease.pyasmajor*10000 + minor*100 + patch(e.g.0.6.2→602).- If
changelog.d/is empty when you runrelease.py, it warns but proceeds — useful for version-only bumps. release.pyrefuses to release a version that already exists inhistory[].
Build versions
Every packaging step runs ./scripts/build-version.py to compute the version string stamped into the artifact:
- On a release tag
vX.Y.Z:X.Y.Z - N commits after the nearest tag:
X.Y.Z-N-gSHA(the git describe format) - Working tree dirty: additional
-dirtysuffix - No git / no tags: falls back to the
VERSIONfile
This string goes into:
module.propversion=...(visible in the Magisk/KSU manager app)- APK
versionName(visible in Android Settings → Apps, diagnostic debug zip,BuildConfig.VERSION_NAME) - Inside the zip filenames (only for release tags; dev artifacts in CI keep a stable name)
The committed module.prop files are not modified — build-zip.py stages a copy, patches the version there, and zips. lsposed/app/build.gradle.kts evaluates build-version.py at configure time and sets versionName dynamically.
versionCode stays at the value baked in by the last release.py run (monotonically increasing integer required by Android/Magisk).