diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2a7aceb..48e2334 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,10 +41,11 @@ jobs: # which the final "publish" job then attaches to the Release. # # runner → target mapping: - # ubuntu-22.04 → x86_64-unknown-linux-gnu (older glibc for wider compat) - # macos-latest → x86_64-apple-darwin (ARM runner, cross-compiled) - # macos-latest → aarch64-apple-darwin (Apple Silicon runner, native) - # windows-latest → x86_64-pc-windows-msvc (native) + # ubuntu-22.04 → x86_64-unknown-linux-gnu (older glibc for wider compat) + # ubuntu-22.04 → aarch64-unknown-linux-musl (static, cross-compiled; runs on Termux) + # macos-latest → x86_64-apple-darwin (ARM runner, cross-compiled) + # macos-latest → aarch64-apple-darwin (Apple Silicon runner, native) + # windows-latest → x86_64-pc-windows-msvc (native) build: name: Build · ${{ matrix.target }} needs: ci @@ -60,6 +61,14 @@ jobs: binary: omny archive: omny-x86_64-unknown-linux-gnu.tar.gz + # Statically linked aarch64 Linux build. The musl runtime is bundled + # into the binary so it runs anywhere with a Linux kernel — including + # Termux on Android, which does not ship glibc. + - target: aarch64-unknown-linux-musl + runner: ubuntu-22.04 + binary: omny + archive: omny-aarch64-unknown-linux-musl.tar.gz + - target: x86_64-apple-darwin runner: macos-latest binary: omny @@ -92,8 +101,19 @@ jobs: restore-keys: | ${{ matrix.target }}-cargo- + # Cross-linker for the aarch64-musl target. Rust bundles the musl libc + # itself; gcc-aarch64-linux-gnu only supplies the ELF linker. + - name: Install aarch64 cross linker + if: matrix.target == 'aarch64-unknown-linux-musl' + run: | + sudo apt-get update + sudo apt-get install -y gcc-aarch64-linux-gnu + # Build the release binary (optimized, stripped) - name: Build release binary + env: + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER: aarch64-linux-gnu-gcc + CC_aarch64_unknown_linux_musl: aarch64-linux-gnu-gcc run: cargo build --release --locked --target ${{ matrix.target }} # Package for Unix (tar.gz) @@ -176,6 +196,7 @@ jobs: fail_on_unmatched_files: true files: | artifacts/omny-x86_64-unknown-linux-gnu.tar.gz + artifacts/omny-aarch64-unknown-linux-musl.tar.gz artifacts/omny-x86_64-apple-darwin.tar.gz artifacts/omny-aarch64-apple-darwin.tar.gz artifacts/omny-x86_64-pc-windows-msvc.zip diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a65151..7a0e943 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ Versions follow [Semantic Versioning](https://semver.org/). --- +## 1.0.3 — 2026-05-21 + +### Features +- **Termux / Android support**: Releases now include a statically linked `aarch64-unknown-linux-musl` build that runs on Termux. `install.sh` detects Termux via `$TERMUX_VERSION` / `$PREFIX` and installs the binary into `$PREFIX/bin` (and the man page into `$PREFIX/share/man/man1`) without `sudo`. + +--- + ## 1.0.2 — 2026-05-16 ### Features diff --git a/Cargo.lock b/Cargo.lock index 7f20a5e..c66482d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1669,7 +1669,7 @@ dependencies = [ [[package]] name = "omnyssh" -version = "1.0.2" +version = "1.0.3" dependencies = [ "anyhow", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index e71f4a6..5d826fc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "omnyssh" -version = "1.0.2" +version = "1.0.3" edition = "2021" description = "TUI SSH dashboard & server manager" license = "Apache-2.0" diff --git a/doc/omny.1 b/doc/omny.1 index 83af793..9f76382 100644 --- a/doc/omny.1 +++ b/doc/omny.1 @@ -1,6 +1,6 @@ .ie \n(.g .ds Aq \(aq .el .ds Aq ' -.TH omny 1 "omny 1.0.2" +.TH omny 1 "omny 1.0.3" .SH NAME omny \- TUI SSH dashboard & server manager .SH SYNOPSIS @@ -28,4 +28,4 @@ Print help (see a summary with \*(Aq\-h\*(Aq) \fB\-V\fR, \fB\-\-version\fR Print version .SH VERSION -v1.0.2 +v1.0.3 diff --git a/install.sh b/install.sh index 64389cf..bd3cf4e 100644 --- a/install.sh +++ b/install.sh @@ -36,27 +36,40 @@ print_warning() { detect_platform() { OS="$(uname -s)" ARCH="$(uname -m)" - - case "$OS" in - Linux*) - PLATFORM="unknown-linux-gnu" - INSTALL_DIR="/usr/local/bin" - ;; - Darwin*) - PLATFORM="apple-darwin" - INSTALL_DIR="/usr/local/bin" - ;; - MINGW*|MSYS*|CYGWIN*) - PLATFORM="pc-windows-msvc" - INSTALL_DIR="$HOME/bin" - EXT=".exe" - print_warning "Windows detected. Manual PATH configuration may be required." - ;; - *) - print_error "Unsupported OS: $OS" - exit 1 - ;; - esac + IS_TERMUX=0 + + # Termux reports OS=Linux from uname but uses Bionic libc and a + # non-standard prefix. Detect it first so we pick a static musl build + # and install into $PREFIX/bin instead of /usr/local/bin. + if [ -n "${TERMUX_VERSION:-}" ] || \ + { [ -n "${PREFIX:-}" ] && [ -d "${PREFIX}/bin" ] && \ + [ "${PREFIX#*/com.termux/}" != "${PREFIX}" ]; }; then + IS_TERMUX=1 + PLATFORM="unknown-linux-musl" + INSTALL_DIR="$PREFIX/bin" + print_info "Termux detected" + else + case "$OS" in + Linux*) + PLATFORM="unknown-linux-gnu" + INSTALL_DIR="/usr/local/bin" + ;; + Darwin*) + PLATFORM="apple-darwin" + INSTALL_DIR="/usr/local/bin" + ;; + MINGW*|MSYS*|CYGWIN*) + PLATFORM="pc-windows-msvc" + INSTALL_DIR="$HOME/bin" + EXT=".exe" + print_warning "Windows detected. Manual PATH configuration may be required." + ;; + *) + print_error "Unsupported OS: $OS" + exit 1 + ;; + esac + fi case "$ARCH" in x86_64|amd64) @@ -161,6 +174,10 @@ download_and_install() { if [ -w "$INSTALL_DIR" ]; then mv "$BINARY_PATH" "$INSTALL_DIR/$BINARY_NAME${EXT}" chmod +x "$INSTALL_DIR/$BINARY_NAME${EXT}" + elif [ "$IS_TERMUX" = "1" ]; then + # Termux has no sudo; $PREFIX/bin should already be writable. + print_error "Install directory $INSTALL_DIR is not writable" + exit 1 else # Need sudo for system directories print_warning "Installing to system directory requires sudo privileges" @@ -217,7 +234,11 @@ install_man_page() { print_info "Installing man page..." MAN_URL="https://raw.githubusercontent.com/$REPO/main/doc/omny.1" - MAN_DIR="/usr/local/share/man/man1" + if [ "$IS_TERMUX" = "1" ]; then + MAN_DIR="$PREFIX/share/man/man1" + else + MAN_DIR="/usr/local/share/man/man1" + fi # Try to install man page if we can if [ -d "$MAN_DIR" ] || mkdir -p "$MAN_DIR" 2>/dev/null; then