Skip to content

Releases and documentation publishing

Android releases

.github/workflows/release.yml builds AArch64/ARMv7/x86_64 with NDK r28c/API 26 on v* tags, along with self-update binaries/digests, combined ZIP/TAR, Termux debs, and signed APT snapshots before GitHub Release publication. Manual workflow_dispatch creates a draft; drafts do not update the live site.

Local pack-release.sh / pack-release.ps1 produces the same ZIP layout. Archives include bilingual README website links plus bilingual getting-started Markdown and media, without the deleted 使用说明.md. Termux debs contain both language entry points and use package-manager updates.

Before release review versions, both changelogs, config examples, tool references, scripts, TUR version/source SHA-256, and dependency licenses. Run Rust/frontend/script/docs gates and Android ABI validation. A tag does not prove workflow success; inspect final jobs and assets.

One GitHub Pages site

Documentation and independent Termux APT share https://nl2sh.github.io/nl2sh/. Root dists/, pool/, and nl2sh-repo.gpg paths stay fixed. Documentation-only artifacts must not overwrite them.

Releases publish signed termux-apt-repository.tar.gz. Docs PRs validate only; master, manual triggers, and successful Release completion deploy: build bilingual docs → fetch latest stable Release APT snapshot → verify signatures/SHA-256 → merge → upload Pages artifact → deploy-pages. For older releases without snapshots, fetch and verify the existing signed site repository. Failures stop deployment rather than publishing without APT. Deployment jobs share a concurrency group.

Set Pages Source to GitHub Actions and permit master in github-pages. The existing TERMUX_APT_GPG_PRIVATE_KEY secret is read by Release signing only, never docs builds. Key rotation requires explicitly updating trust configuration instead of disabling verification.

Generated HTML remains a build artifact; do not commit site/ to master. See official GitHub Pages workflows.

Signed compatibility and assets

packaging/runtime-components.json selects independent Bridge/JADX releases and the minimum Helper version. Publish those companion versions first. The release downloads their exact artifacts, validates packaged metadata and the APK signature, then signs nl2sh-runtime-extensions.json before the three native builds embed it. A final nl2sh-runtime.json adds actual native sizes/digests. Both manifests and each native/Bridge/JADX asset have binary SHA-256 detached GPG signatures. Tag and Cargo version must agree.

Signing reuses TERMUX_APT_GPG_PRIVATE_KEY in the github-pages environment, pinned to fingerprint 5230D3A7CCBEED4616D39C51FC6AD1BC63F7D4D8. Bridge uses its existing APK keystore secrets. If companion repositories are private, NL2SH_COMPONENTS_TOKEN must permit reading their releases; otherwise the job uses the repository token. Missing assets, keys, protocol mismatches or invalid APK signatures fail publication. Local production signing may be deferred; unsigned local native builds require explicit offline/custom JADX configuration.

Native and Helper downloads verify the signed manifest before following its asset URLs and verify size, SHA-256 and asset signature before installation. Modern unsigned releases cannot be used for new installation or upgrade. Connecting to a healthy already installed runtime still works without checking releases.

Runtime refactor acceptance (2026-10-07)

All planned protocol, service, Helper, manifest/signature, descriptor, UI lease/audit, static analysis and Web separation changes are implemented. Local verification:

Gate Result
Rust Complete workspace tests, all targets, formatter and package-manager feature check passed; existing ignored tests remain ignored
Android native NDK r28c/API 26 release builds for ARM64, ARMv7 and x86_64 passed
Android projects All three Gradle test/lint/debug/release gates passed; production APK signing deferred locally
Frontend/docs 33 frontend tests and production build; 49 bilingual pages per language, strict build and generated references passed
Release tooling 15 packaging/launcher/Pages tests, workflow parsing, and actual three-ELF/APK/JAR manifest generation passed
API 26 and 35 emulators UID 2000 protocol correlation/malformed requests/app UID denial; all eight static tools; cross-process UI exclusion/read independence/recovery; service idempotence/restart/stop/strict collision/fallback port and embedded HTTP passed
Helper on both emulators Healthy reconnect preserves PID; failed update restores binary and owner; matching explicit update records ownership without restart; companion certificate refusal/in-place install/settings preservation; GPG fixture/tamper/policy drift passed (three device tests each)

The emulator checks use local unsigned native builds, debug APKs and public test-signature fixtures. ARM builds were validated as ELF artifacts, not executed on ARM hardware in this acceptance run. Production GPG/APK signatures and published release bytes must be verified after GitHub Actions runs; no tags or remote releases were created by this implementation.