Two tweaks driven by the same goal — make the artifact list on the CI
run page less ambiguous and give the release step a review gate.
- The APK artifact was named `vpnhide`, which blends in with the other
module-zip artifacts (`vpnhide-kmod-*`, `vpnhide-zygisk`,
`vpnhide-ports`). Rename to `vpnhide-apk` so every entry in the
Artifacts list names the thing you actually get when you download it.
- Release-on-tag job now creates a DRAFT GitHub release instead of
publishing directly. Gives a chance to eyeball the release notes and
attached binaries before they go public, and avoids racing
update-json.sh against the assets becoming reachable.
docs/releasing.md and the release.py post-run hints updated to reflect
the manual Publish step and the fact that update-json still has to
wait for the release to be *published*, not just drafted (draft
release assets sit behind auth).
Add scripts/build-version.sh — a single source of truth for the
effective version string:
* HEAD on tag vX.Y.Z -> "X.Y.Z"
* N commits past tag -> "X.Y.Z-N-gSHA"
* working tree dirty -> additional "-dirty" suffix
* no git / no matching tag -> VERSION file fallback
Wired into every packaging path:
* zygisk/build-zip.sh and portshide/build-zip.sh now stage a copy of
module/ and sed-patch `version=` in the staging copy, so committed
module.prop files stay at the last-released version.
* kmod/build-zip.sh now builds into a staging copy too.
* The kmod CI step runs build-version.sh and sed-patches module.prop
before zipping (git installed in the DDK container).
* lsposed/app/build.gradle.kts exec's build-version.sh at configure
time and assigns the result to `versionName` (versionCode stays
static, still bumped by release.py).
All actions/checkout@v6 gained `fetch-depth: 0` so git describe sees
the full tag history inside CI containers.
Result: a locally built or CI-from-main APK shows up in Android
Settings as e.g. `0.6.1-16-gf86e5e5`, and the zip inside carries the
same string in module.prop; the Magisk/KSU manager displays it in the
update list. Release tag builds are indistinguishable from before —
clean `X.Y.Z`. Diagnostic bug reports now carry the exact commit in
the App version line of device_info.txt.
Rework the changelog and release flow to remove the aspirational
top-level version that made it unclear whether new entries were
landing in an already-released section.
Schema change: `changelog.json` now has an explicit `unreleased`
object instead of hoisting the upcoming version to the top level. The
old `{version, sections, history}` layout becomes
`{unreleased, history}`, with the previously-released version moved
into `history[0]`.
New entries always go into `unreleased` via `changelog.py`. Releasing
is a single atomic operation (`release.py X.Y.Z`) that promotes
`unreleased` into `history[0]` with the target version number,
propagates the version to every source file, and regenerates the
markdown artifacts.
Script renames:
- `_changelog.py` → `changelog_lib.py` (no more underscore-prefixed
module that's imported by two siblings)
- `changelog-add.py` → `changelog.py`
- `update-version.py` → `release.py` (does more than just version
propagation — the name now reflects the full release action)
CHANGELOG.md rendering follows Keep a Changelog: a `## [Unreleased]`
block appears on top only when there are unreleased entries; the
update-json/changelog.md shown in Magisk/KSU popups still skips
Unreleased (only released versions make sense there).
Docs (docs/changelog.md, docs/releasing.md, CONTRIBUTING.md, CLAUDE.md)
updated with the new commands and the clarified model.
CLAUDE.md additionally gains a "read these before doing any work"
section that lists the contributor docs — so future sessions load the
workflow rules into context instead of skipping them as optional.
Split the contributor-facing knowledge that used to live in the local
CLAUDE.md into versioned, public docs:
- CONTRIBUTING.md — PR process, commit conventions, required changelog
entry for user-visible changes, code-style checks.
- docs/development.md — prereqs, keystore setup, per-module build
commands, device install, CI lints.
- docs/releasing.md — VERSION bump → update-version.py → tag → CI →
update-json.sh flow, with the rationale for why update-json is a
separate post-release commit.
- docs/changelog.md — changelog.json as source of truth, how the two
generated markdowns are regenerated, when to add an entry.
Extended kmod/BUILDING.md with a Podman variant of the DDK command,
covering rootless + SELinux (Fedora) where --userns=keep-id and :Z are
required. Kept the kmod build docs next to the code since the GKI /
DDK complexity is kmod-specific.
Component READMEs untouched — they document each module's architecture
and belong next to the code.