diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 41f9bba..6da91dd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -190,6 +190,11 @@ jobs: actions: read contents: write steps: + - name: Checkout installer script + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Download package artifacts uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: @@ -197,6 +202,9 @@ jobs: path: release-assets merge-multiple: true + - name: Add hosted Linux installer + run: cp install.sh release-assets/BrightSync-install.sh + - name: Generate SHA-256 manifest env: RELEASE_VERSION: ${{ needs.prepare.outputs.version }} @@ -212,6 +220,7 @@ jobs: "BrightSync-Setup-v${RELEASE_VERSION}-win-arm64.exe" "BrightSync-Setup-v${RELEASE_VERSION}-win-x86.exe" "BrightSync-${RELEASE_VERSION}-linux-portable.tar.gz" + "BrightSync-install.sh" ) for rid in linux-x64 linux-arm64 linux-arm; do for ext in tar.gz deb rpm pkg.tar.zst AppImage; do diff --git a/README.md b/README.md index 7645a8e..17dd446 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,18 @@ Important notes: Download the package for your distribution and CPU from the [latest release](https://github.com/bberka/BrightSync/releases/latest): +Or install (and update later) the latest Linux release with the hosted script: + +```bash +curl -fsSL https://raw.githubusercontent.com/bberka/BrightSync/master/install.sh | bash +``` + +Run the same command again to update. For a system-wide install, pass `--system` and run it with root privileges: + +```bash +curl -fsSL https://raw.githubusercontent.com/bberka/BrightSync/master/install.sh | sudo bash -s -- --system +``` + ```bash sudo apt install ./BrightSync--linux-x64.deb # Debian, Ubuntu, Mint sudo dnf install ./BrightSync--linux-x64.rpm # Fedora, RHEL, openSUSE (zypper) @@ -276,7 +288,7 @@ The config format is identical on both platforms. ## Updates -BrightSync checks GitHub releases for updates. On Windows it can download, verify (SHA-256), and install the matching installer. On Linux it shows an update notice and opens the releases page; install the new package with your package manager. +BrightSync checks GitHub releases for updates. On Windows it can download, verify (SHA-256), and install the matching installer. On Linux it shows an update notice and opens the releases page; rerun the hosted installer command in the Linux section to update. ## Build Locally diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index ffca26a..72a399c 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -28,6 +28,7 @@ App ──► UI ──► Core ──► Abstractions ◄── Windows | Linux src/ every production project: Core, UI, App, Platform.Abstractions, Platform.Windows, Platform.Linux tests/ one xunit v3 project for all of the above, with Linux fakes in tests/Linux packaging/ windows/ (Inno Setup script), linux/ (nfpm, desktop, udev, install.sh), build-linux.sh +install.sh hosted Linux latest-release installer (also included in release assets) tools/ developer tooling, such as linux-vm-test (QEMU distro runs) website/ Astro landing page published to GitHub Pages; independent of the .NET build docs/ guides (Linux, architecture, packaging, roadmap) and the screenshots the README uses diff --git a/docs/LINUX.md b/docs/LINUX.md index 2f305f7..b2b2688 100644 --- a/docs/LINUX.md +++ b/docs/LINUX.md @@ -27,6 +27,16 @@ arm64 and arm builds are cross-published and covered by the same unit tests on t ## Supported systems +### Quick install and updates + +Install the latest release for the current CPU and libc with: + +```bash +curl -fsSL https://raw.githubusercontent.com/bberka/BrightSync/master/install.sh | bash +``` + +Run that command again to update. This installs per-user under `~/.local`; for a system-wide install use `curl -fsSL https://raw.githubusercontent.com/bberka/BrightSync/master/install.sh | sudo bash -s -- --system`. The installer downloads the matching portable release archive and uses its bundled installer. It supports glibc and musl on x64, arm64, and arm. For DDC/CI monitor access without a system-wide install, run `curl -fsSL https://raw.githubusercontent.com/bberka/BrightSync/master/install.sh | sudo bash -s -- --setup-i2c` once. + | Package | Distributions | CPU | |---|---|---| | `.deb` | Debian, Ubuntu, Linux Mint, Pop!_OS, Raspberry Pi OS | x64, arm64, arm (armhf) | diff --git a/docs/PACKAGING.md b/docs/PACKAGING.md index 215fd51..ba997d0 100644 --- a/docs/PACKAGING.md +++ b/docs/PACKAGING.md @@ -24,6 +24,7 @@ The names are a contract: the release workflow's `expected` list, the checksum m | Linux musl | `BrightSync--linux-musl-.` | | Linux portable | `BrightSync--linux-portable.tar.gz` | | Checksums | `BrightSync-SHA256SUMS.txt` (every asset above, one line each) | +| Hosted Linux installer | `BrightSync-install.sh` | The Windows updater only accepts `BrightSync-Setup-*` assets whose name contains `-win-.`; do not rename them. @@ -53,6 +54,7 @@ packaging/build-linux.sh linux-portable 0.19.0 out - `nfpm.yaml`: one definition for deb, rpm, apk, and archlinux. Installs the app to `/opt/brightsync`, links `/usr/bin/brightsync`, and adds the desktop file, icon, udev rule, and modules-load entry. - `postinstall.sh`, `postremove.sh`: best-effort `modprobe i2c-dev`, udev reload, desktop database refresh. They never fail the transaction. - `install.sh`: installer inside the portable tarball (`--system`, `--setup-i2c`, `--uninstall`). +- `../../install.sh`: hosted latest-release installer, also published as `BrightSync-install.sh`. It selects the Linux archive for the current CPU and libc, then invokes the bundled installer; running it again updates the install. - `60-brightsync-i2c.rules`, `brightsync-i2c.conf`, `brightsync.desktop`. `packaging/linux/make-appimage.sh` builds the AppImage (an `AppRun` that launches the bundled binary, packed by `appimagetool`, which needs the `file` command). `build-linux.sh` and the VM test harness both call it. The AppImage cannot install the udev rule; its users run `--setup-i2c` from the tarball or follow [LINUX.md](LINUX.md). diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..284292e --- /dev/null +++ b/install.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# Install or update BrightSync from the latest Linux release. +# curl -fsSL https://raw.githubusercontent.com/bberka/BrightSync/master/install.sh | bash +# curl -fsSL https://raw.githubusercontent.com/bberka/BrightSync/master/install.sh | bash -s -- --system +set -euo pipefail + +repo=bberka/BrightSync +tmp='' +cleanup() { [[ -z "$tmp" ]] || rm -rf -- "$tmp"; } +trap cleanup EXIT + +fail() { printf 'BrightSync installer: %s\n' "$*" >&2; exit 1; } +command -v curl >/dev/null || fail 'curl is required.' +command -v tar >/dev/null || fail 'tar is required.' + +case "$(uname -m)" in + x86_64|amd64) arch=x64 ;; + aarch64|arm64) arch=arm64 ;; + armv7l|armv7*) arch=arm ;; + *) fail "unsupported CPU architecture: $(uname -m). See https://github.com/$repo/releases/latest" ;; +esac + +rid="linux-$arch" +if command -v ldd >/dev/null 2>&1; then + ldd_version=$(ldd --version 2>&1 || true) + case "$ldd_version" in *musl*) rid="linux-musl-$arch" ;; esac +fi + +release_url=$(curl -fsSL -o /dev/null -w '%{url_effective}' "https://github.com/$repo/releases/latest") || fail 'could not find the latest release.' +tag=${release_url##*/} +version=${tag#v} +[[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || fail "could not determine release version from $release_url" +archive="BrightSync-$version-$rid.tar.gz" +url="https://github.com/$repo/releases/download/$tag/$archive" +tmp=$(mktemp -d "${TMPDIR:-/tmp}/brightsync-install.XXXXXX") +curl -fL --retry 3 "$url" -o "$tmp/$archive" || fail "download failed: $url" +tar -xzf "$tmp/$archive" -C "$tmp" +folder="$tmp/BrightSync-$version-$rid" +[[ -x "$folder/install.sh" ]] || fail 'release archive did not contain its installer.' + +# Forward options such as --system, --setup-i2c, and --uninstall to the archive installer. +bash "$folder/install.sh" "$@"