Bus-factor mitigation document. If the primary maintainer (oviron) goes silent for 60+ days, fork this repo and continue using these instructions.
- Android Gradle Plugin: 8.12.2 (pinned in
build.gradle.kts) - Kotlin: 2.2.10
- Gradle: 8.13 (via wrapper, no system install needed)
- JDK: 17+ (Temurin recommended)
- Android NDK: 28.0.13004108 (pinned via
ndkVersioninbuild.gradle.kts) - CMake: 3.22.1+
- Android SDK: compileSdk 36, minSdk 21
- OS: ubuntu-latest in CI; locally Linux/macOS both fine
src/main/cpp/native-lib.c— our JNI wrapper (~100 LOC, MIT-licensed)src/main/cpp/main.h— declarations from upstream byedpisrc/main/cpp/CMakeLists.txt— native build scriptsrc/main/cpp/byedpi/— git submodule pinned athufrea/byedpiSHAsrc/main/kotlin/io/github/oviron/libbyedpi/ByeDpi.kt— Kotlin stub bundled into the .aarsrc/main/AndroidManifest.xml— empty library manifestbuild.gradle.kts,settings.gradle.kts,gradle.properties— AGP library project config
Tags matching v* trigger the release.yml workflow:
- Checks out source with
submodules: recursive - Builds the
.aarvia./gradlew :assembleRelease; AGP compileslibbyedpi.sofor all three ABIs and bundles them with the Kotlin stub - Renames the artifact to
libbyedpi-android-<tag>.aarand generates SHA-256 - GPG-signs the
.aarwith maintainer key (detached, armored) — public key inoviron-signing.pub.asc - Creates a GitHub Release with 3 files attached (
.aar+.aar.sha256+.aar.asc)
Cut a release manually:
# Verify main is green
gh run list --limit 3
# Update CHANGELOG.md (mandatory)
# Bump version in this MAINTENANCE.md if conventions change
git tag v0.X.Y
git push origin v0.X.Y
gh run watchWhen hufrea/byedpi releases a new tag:
- Update the submodule:
cd src/cpp/byedpi git fetch origin git checkout <new-tag-or-commit> cd ../../.. git add src/cpp/byedpi git commit -m "Bump byedpi to <version>"
- Verify our wrapper still compiles. If
params,clear_params, ormainsignatures changed upstream → patchnative-lib.caccordingly. Bump our0.X.Yminor. - Tag a new release.
ByeDPI changes its public C API rarely (~1-2 times per year). The wrapper is small (~94 LOC) — drift fixes are usually one or two lines.
The maintainer's GPG key is RSA 4096 4A94DA488A4C5033, fingerprint 1139C91B6525883E6783DCF04A94DA488A4C5033. Public key committed at repo root as oviron-signing.pub.asc. Same key is registered on github.com/oviron for commit verification.
CI uses the same key via GitHub Actions secrets GPG_PRIVATE_KEY (armored secret key) and GPG_PASSPHRASE. To rotate:
- Generate new GPG key, e.g.
gpg --full-generate-key - Export armored private:
gpg --armor --export-secret-keys <NEW_KEY_ID> | gh secret set GPG_PRIVATE_KEY --repo oviron/libbyedpi-android - Set new passphrase:
gh secret set GPG_PASSPHRASE --repo oviron/libbyedpi-android - Replace
oviron-signing.pub.ascwith the new public key - Announce in next release notes with cross-signature from old key
After cutting any release, also push the maintainer public key to a keyserver so consumers can fetch independently of the repo:
gpg --keyserver keys.openpgp.org --send-keys 4A94DA488A4C5033A given source tree + the same pinned AGP/Kotlin/NDK toolchain + the same byedpi submodule SHA produces byte-identical artifacts across runs. -Wl,--build-id=sha1 in src/main/cpp/CMakeLists.txt makes the BuildID a content hash, AGP applies zip epoch normalization to the .aar, and LLD does not embed linker timestamps. Stronger reproducibility (across NDK patch revisions or different host platforms) is not claimed.
GitHub Releases is currently the only distribution channel. Mirror to a non-GitHub host (Codeberg / IPFS / other) is deferred until concrete need. If GitHub deletes this repo:
- All consumers downloading via fixed URL lose access
- The git submodule at
hufrea/byedpiis upstream and unaffected - Fork: any third party can clone this repo via local checkout, push to alternative host, continue releases — the build is reproducible per the section above
- Primary maintainer: oviron (@oviron on GitHub)
- Security disclosures: see
SECURITY.md - Issues / questions: GitHub Issues