Commit graph

7 commits

Author SHA1 Message Date
okhsunrog
5350f8e2f6 ci: shave another ~80s off lint/lsposed jobs
Profiling the warm-cache run on PR #105 showed three remaining hot spots
in the Gradle phase:

  installUniffiBindgen          52s   ← cargo install on every CI build
  cargoBuildAndroidArm64Debug   30s   ← Rust crate compile
  lintAnalyze* (3 variants)     43s   ← AGP Lint × main + unit + androidTest

This PR cuts the first one entirely and trims the third.

  - Dockerfile: pre-install uniffi-bindgen 0.29.x in the CI image so
    Gobley's :app:installUniffiBindgen task finds it ready instead of
    rebuilding it from sources on every run. Triggers a ci-image
    rebuild on merge — wait for that workflow to finish before merging
    consumers (or the first lint/lsposed run will still hit the old
    image and behave as before).
  - lsposed/gradle.properties: enable build cache + configuration
    cache. Verified locally: `./gradlew :app:assembleDebug
    --configuration-cache` reports "Configuration cache entry stored"
    cleanly with Gobley 0.3.7 + AGP 8.9.3 + Kotlin 2.1.20.
  - lsposed/app/build.gradle.kts: `lint { checkTestSources = false }`.
    Skips lintAnalyzeDebugUnitTest / lintAnalyzeDebugAndroidTest. Test
    sources here are pure JVM unit-test logic — functional bugs caught
    by :app:testDebugUnitTest, no Android-lifecycle code to lint.
    Deliberately leave `checkReleaseBuilds` at its default so ad-hoc
    `./gradlew :app:lint` still catches R8/ProGuard issues.
  - .github/workflows/ci.yml: `:app:lint` -> `:app:lintDebug`. Lints
    the debug variant only on PRs; release-variant Lint stays
    available locally / for future tag-time CI.
  - docs/development.md: refresh local-lint snippet.

Expected effect on warm cache (cumulative on top of PR #105):
  lint     286s -> ~190s  (3m10s, -32%)
  lsposed  227s -> ~130s  (2m10s, -42%)
2026-04-27 00:28:25 +03:00
okhsunrog
91013acb54 ci+chore: add ruff (format + lint) for python scripts
Repo had ~1800 lines of Python (kmod/build.py, scripts/*, zygisk/build.py,
portshide/build-zip.py) with no formatter or linter. Long-lived scripts
like scripts/release.py and scripts/codegen-interfaces.py benefit from
catching unused-import / undefined-name / outdated-syntax issues early.

  pyproject.toml — ruff config, target-py312, line-length 100,
                   rules E F W I B UP SIM. Excludes zygisk/third_party,
                   target/, .claude/.
  ci.yml — astral-sh/ruff-action@v4 for `format --check` and `check`,
           ahead of the slow Rust/Gradle steps so it fails fast.
  docs/development.md — add `uvx ruff …` to the local-lint snippet.

Cleanup applied (`ruff format` + `ruff check --fix`):
  - reformat: kmod/build.py, scripts/{changelog_lib,codegen-interfaces,
    release,stats}.py, zygisk/build.py
  - I001: split multi-name imports onto separate lines after the
    sys.path.insert prelude (kmod/build.py, zygisk/build.py)
  - E501 manual: wrap one console.print line in scripts/release.py

Stdlib-only invariant from scripts/build_lib.py is preserved — ruff is
a dev/CI tool, not imported at runtime.
2026-04-26 23:48:37 +03:00
okhsunrog
35b3dcdf50 build: align native cdylib on 16 KiB; unify kmod/zygisk build scripts
Two related changes that ship together because they touch the same
build-script + docs surface and were verified together on-device.

16 KiB alignment
  - zygisk/build.rs: pass `-Wl,-z,max-page-size=16384` to lld so the
    cdylib's LOAD segments line up on 16 KiB pages. NDK r28+ already
    does this by default, but the flag keeps r27 builds compatible.
  - lsposed/native/build.rs: new file, same flag, for libvpnhide_checks.so.
  - docs/development.md: bumped the NDK requirement to r28+ and noted
    the 16 KiB rationale.

Verified via `llvm-readelf -l`: both libvpnhide_zygisk.so and
libvpnhide_checks.so now show `Align 0x4000` on every LOAD segment.

Unified build entry points
  - kmod/build.py replaces kmod/build-zip.py. Single script that
    auto-detects whether to build natively (we're inside the DDK image
    or `--kdir` was passed) or to spawn `ghcr.io/ylarod/ddk-min` via
    podman/docker. CI uses the same script with `--inside-container`.
  - zygisk/build-zip.py renamed to zygisk/build.py for symmetry; logic
    unchanged.
  - kmod/BUILDING.md rewritten — local build is now one command:
    `./kmod/build.py --kmi android14-6.1` (or `--all`). The old
    hand-rolled podman/docker recipes are gone.
  - .github/workflows/ci.yml updated to call the new entry points.
    The DDK image tag in CI now has a comment pointing at
    `DDK_IMAGE_TAG` in kmod/build.py as the source of truth.
  - README.{md,en.md}, kmod/README.md, zygisk/README.md, docs/releasing.md,
    scripts/build_lib.py: reference updates.
  - README.en.md: also fixes a "bacame" typo and tightens the Windows
    zygisk-build note (the aux.rs / libgit2 issue is still real).

Verified end-to-end on Pixel 8 Pro (husky, android14-6.1, Android 16):
APK installs, kmod + zygisk modules load, all 26 self-checks PASS in
Enforcing, 22/26 PASS in Permissive (the same 4 by-design FAILs as
before — kmod doesn't cover those paths in Permissive).
2026-04-26 23:26:30 +03:00
okhsunrog
8025be14cc docs: align README and dev guide with current code and CI
Six unrelated drift fixes that accumulated since they were last
synced. Each is independent of the rest:

* README{.en,}.md — kmod claim "filters /proc/net/*" trimmed to
  /proc/net/route. The other /proc/net files are SELinux-blocked
  for untrusted apps and the coverage table already says so.

* kmod/README.md — hook table and architecture note updated from
  dev_ifconf to sock_ioctl. dev_ifconf gets inlined by Clang LTO
  on GKI 5.10 so the kretprobe silently never fires; sock_ioctl
  has been the actual hook target since the vpnhide_kmod.c fix.

* zygisk/README.md — five inline hooks now, not four (recv was
  added separately because bionic's recv tail-calls recvfrom).
  Also clarified pre_app_specialize runs in the forked child, not
  zygote, matching the lifecycle block in lib.rs.

* docs/development.md — JDK requirement matches CI image (17, not
  21); document ANDROID_NDK_ROOT quirk for Gobley; CI lint list
  expanded to match what ci.yml actually runs.

* docs/development.md + lsposed/README.md — explain Gobley (the
  Gradle plugin pair that builds lsposed/native/ and bundles the
  .so + UniFFI Kotlin bindings into the APK). Previously absent
  from all *.md.
2026-04-26 15:32:30 +03:00
Horizon
cf4e72fa01
fix(build): port build scripts to Python to allow Windows contributors to build subprojects (#83)
* 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
2026-04-25 19:53:15 +03:00
okhsunrog
3fc735572a build: stamp git-describe build version into every artifact
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.
2026-04-17 14:42:40 +03:00
okhsunrog
876829d9ad docs: add CONTRIBUTING.md and docs/ with build/release/changelog guides
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.
2026-04-17 13:51:33 +03:00