From a6451ece639d24b46b11e16dac4b0ee0d9d1b8bb Mon Sep 17 00:00:00 2001 From: jarvis Date: Sat, 29 Aug 2026 14:24:34 -0400 Subject: [PATCH 01/10] feat(install): add pinned pre-Webi installers --- scripts/install-realmroot.ps1 | 82 ++++++++++++++++++++++++++++++ scripts/install-realmroot.sh | 94 +++++++++++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 scripts/install-realmroot.ps1 create mode 100755 scripts/install-realmroot.sh diff --git a/scripts/install-realmroot.ps1 b/scripts/install-realmroot.ps1 new file mode 100644 index 0000000..dd4fb01 --- /dev/null +++ b/scripts/install-realmroot.ps1 @@ -0,0 +1,82 @@ +#!/usr/bin/env pwsh + +param( + [string]$Version = $Env:REALMROOT_VERSION +) + +$ErrorActionPreference = 'Stop' +$ProgressPreference = 'SilentlyContinue' + +if ([string]::IsNullOrWhiteSpace($Version) -or $Version -eq 'stable') { + $release = Invoke-RestMethod -Uri 'https://api.github.com/repos/realmroot/cli/releases/latest' + $Version = $release.tag_name.TrimStart('v') +} else { + $Version = $Version.TrimStart('v') +} +if ($Version -notmatch '^[0-9A-Za-z.+-]+$') { + throw "Invalid Realmroot version: $Version" +} + +$architecture = $Env:PROCESSOR_ARCHITEW6432 +if ([string]::IsNullOrWhiteSpace($architecture)) { + $architecture = $Env:PROCESSOR_ARCHITECTURE +} +switch ($architecture) { + 'AMD64' { $arch = 'amd64' } + 'ARM64' { $arch = 'arm64' } + default { throw "Unsupported Windows architecture: $architecture" } +} + +$filename = "realmroot_${Version}_windows_${arch}.zip" +$releaseUrl = "https://github.com/realmroot/cli/releases/download/v${Version}" +$tempDir = Join-Path ([System.IO.Path]::GetTempPath()) ("realmroot-install-" + [guid]::NewGuid()) +$archivePath = Join-Path $tempDir $filename +$checksumsPath = Join-Path $tempDir 'checksums.txt' +New-Item $tempDir -ItemType Directory | Out-Null + +try { + Invoke-WebRequest -Uri "$releaseUrl/$filename" -OutFile $archivePath + Invoke-WebRequest -Uri "$releaseUrl/checksums.txt" -OutFile $checksumsPath + + $escapedFilename = [regex]::Escape($filename) + $checksumPattern = "^(?[0-9a-fA-F]{64})\s+\*?${escapedFilename}$" + $checksumMatches = @( + Get-Content -Path $checksumsPath | ForEach-Object { + if ($_ -match $checksumPattern) { + $Matches['hash'].ToLowerInvariant() + } + } + ) + if ($checksumMatches.Count -ne 1) { + throw "Expected one SHA-256 checksum for $filename" + } + + $actualChecksum = (Get-FileHash -Path $archivePath -Algorithm SHA256).Hash.ToLowerInvariant() + if ($actualChecksum -ne $checksumMatches[0]) { + throw "Checksum mismatch for $filename" + } + + Expand-Archive -Path $archivePath -DestinationPath $tempDir -Force + + $versionDir = Join-Path $Env:USERPROFILE ".local\opt\realmroot-v$Version" + $sourceBin = Join-Path $versionDir 'bin' + $destinationBin = Join-Path $Env:USERPROFILE '.local\bin' + $sourceCommand = Join-Path $sourceBin 'realmroot.exe' + $destinationCommand = Join-Path $destinationBin 'realmroot.exe' + + New-Item $sourceBin -ItemType Directory -Force | Out-Null + New-Item $destinationBin -ItemType Directory -Force | Out-Null + Move-Item -Path (Join-Path $tempDir 'realmroot.exe') -Destination $sourceCommand -Force + Copy-Item -Path $sourceCommand -Destination $destinationCommand -Force + + $userPath = [Environment]::GetEnvironmentVariable('Path', 'User') + $pathEntries = @($userPath -split ';' | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }) + if ($pathEntries -notcontains $destinationBin) { + [Environment]::SetEnvironmentVariable('Path', (($destinationBin) + ';' + $userPath).TrimEnd(';'), 'User') + } + + Write-Output "Installed Realmroot v$Version at $destinationCommand" + Write-Output 'Open a new PowerShell session before running realmroot.' +} finally { + Remove-Item -Path $tempDir -Recurse -Force -ErrorAction Ignore +} diff --git a/scripts/install-realmroot.sh b/scripts/install-realmroot.sh new file mode 100755 index 0000000..0e5bec2 --- /dev/null +++ b/scripts/install-realmroot.sh @@ -0,0 +1,94 @@ +#!/bin/sh + +set -e +set -u + +requested_version="${1:-${REALMROOT_VERSION:-stable}}" +case "$requested_version" in + stable) + latest_url="$(curl -fsSLo /dev/null -w '%{url_effective}' https://github.com/realmroot/cli/releases/latest)" + version="${latest_url##*/}" + version="${version#v}" + ;; + v*) version="${requested_version#v}" ;; + *) version="$requested_version" ;; +esac + +case "$version" in + '' | *[!0-9A-Za-z.+-]*) + echo "invalid Realmroot version: $version" >&2 + exit 1 + ;; +esac + +case "$(uname -s)" in + Darwin) os="darwin" ;; + Linux) os="linux" ;; + *) + echo "unsupported operating system: $(uname -s)" >&2 + exit 1 + ;; +esac + +case "$(uname -m)" in + x86_64 | amd64) arch="amd64" ;; + arm64 | aarch64) arch="arm64" ;; + *) + echo "unsupported architecture: $(uname -m)" >&2 + exit 1 + ;; +esac + +filename="realmroot_${version}_${os}_${arch}.tar.gz" +release_url="https://github.com/realmroot/cli/releases/download/v${version}" +tmp_dir="$(mktemp -d -t realmroot-install.XXXXXXXX)" +trap 'rm -rf "$tmp_dir"' EXIT HUP INT TERM + +curl -fsSL "$release_url/$filename" -o "$tmp_dir/$filename" +curl -fsSL "$release_url/checksums.txt" -o "$tmp_dir/checksums.txt" + +if ! expected_checksum="$( + awk -v filename="$filename" ' + $2 == filename { count++; checksum = $1 } + END { + if (count != 1 || checksum !~ /^[0-9a-fA-F]{64}$/) exit 1 + print tolower(checksum) + } + ' "$tmp_dir/checksums.txt" +)"; then + echo "expected one SHA-256 checksum for $filename" >&2 + exit 1 +fi + +if command -v sha256sum > /dev/null 2>&1; then + actual_checksum="$(sha256sum "$tmp_dir/$filename" | awk '{ print $1 }')" +elif command -v shasum > /dev/null 2>&1; then + actual_checksum="$(shasum -a 256 "$tmp_dir/$filename" | awk '{ print $1 }')" +else + echo "SHA-256 verification requires sha256sum or shasum" >&2 + exit 1 +fi + +if test "$actual_checksum" != "$expected_checksum"; then + echo "checksum mismatch for $filename" >&2 + exit 1 +fi + +tar -xzf "$tmp_dir/$filename" -C "$tmp_dir" realmroot + +version_dir="$HOME/.local/opt/realmroot-v$version" +bin_dir="$version_dir/bin" +mkdir -p "$bin_dir" "$HOME/.local/bin" "$HOME/.config/envman" +mv "$tmp_dir/realmroot" "$bin_dir/realmroot" +chmod a+x "$bin_dir/realmroot" +ln -sfn "$bin_dir/realmroot" "$HOME/.local/bin/realmroot" + +path_line='export PATH="$HOME/.local/bin:$PATH"' +path_file="$HOME/.config/envman/PATH.env" +touch "$path_file" +if ! grep -Fqx "$path_line" "$path_file"; then + echo "$path_line" >> "$path_file" +fi + +echo "Installed Realmroot v$version at $HOME/.local/bin/realmroot" +echo "Open a new shell or run: source ~/.config/envman/PATH.env" From 7f352cb6092697398c56f731e18ffea2818b1bdf Mon Sep 17 00:00:00 2001 From: jarvis Date: Sat, 29 Aug 2026 14:31:07 -0400 Subject: [PATCH 02/10] feat(release): add Webi package contract --- .github/workflows/ci.yml | 6 ++ README.md | 65 +++++++++++++++++++ packaging/webi/README.md | 12 ++++ packaging/webi/realmroot/README.md | 58 +++++++++++++++++ packaging/webi/realmroot/install.ps1 | 86 ++++++++++++++++++++++++++ packaging/webi/realmroot/install.sh | 74 ++++++++++++++++++++++ packaging/webi/realmroot/releases.conf | 1 + scripts/verify-release-assets.sh | 78 +++++++++++++++++++++++ specs/cli.feature | 2 + 9 files changed, 382 insertions(+) create mode 100644 packaging/webi/README.md create mode 100644 packaging/webi/realmroot/README.md create mode 100644 packaging/webi/realmroot/install.ps1 create mode 100755 packaging/webi/realmroot/install.sh create mode 100644 packaging/webi/realmroot/releases.conf create mode 100755 scripts/verify-release-assets.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1d9bf60..f98406c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,3 +25,9 @@ jobs: distribution: goreleaser version: v2.17.1 args: check + - uses: goreleaser/goreleaser-action@v7 + with: + distribution: goreleaser + version: v2.17.1 + args: release --snapshot --clean + - run: ./scripts/verify-release-assets.sh dist diff --git a/README.md b/README.md index 0a38529..d42770f 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,71 @@ Users install one command and do not need a separate plugin or runtime. ## Install +Webi installs the prebuilt binary on macOS, Linux, or Windows without Go, npm, +Homebrew, or another language toolchain. On macOS or Linux: + +```console +curl -sS https://webi.sh/realmroot | sh +``` + +On Windows, from PowerShell: + +```powershell +curl.exe -fsSA "MS" https://webi.ms/realmroot | powershell +``` + +Open a new shell after installation, or load Webi's environment in the current +POSIX shell with `source ~/.config/envman/PATH.env`. Confirm the installed build +with `realmroot version`. + +To upgrade to the latest stable release or select an explicit released version: + +```console +webi realmroot@stable +webi realmroot@0.4.2 +``` + +Webi selects the release archive for the current operating system and +architecture and verifies it against that release's `checksums.txt` before +extracting it. Supported targets are macOS, Linux, and Windows on amd64 and +arm64. + +The `webi.sh/realmroot` and `webi.ms/realmroot` URLs become available only +after the Realmroot package is merged into +[`webinstall/webi-installers`](https://github.com/webinstall/webi-installers) +and deployed by Webi. Until then, automation can use the Realmroot-owned bridge +installer from the immutable commit below. Pin both the installer commit and +the CLI release version; `stable` intentionally follows future releases. + +On macOS or Linux: + +```console +curl -fsSLo /tmp/install-realmroot.sh \ + https://raw.githubusercontent.com/realmroot/cli/a6451ece639d24b46b11e16dac4b0ee0d9d1b8bb/scripts/install-realmroot.sh +echo '96c47a9d9295654c6110446a42194af47f22f8c9a6606689749bc0a50acb31c6 /tmp/install-realmroot.sh' \ + | shasum -a 256 -c - +REALMROOT_VERSION=0.4.2 sh /tmp/install-realmroot.sh +``` + +On Windows PowerShell: + +```powershell +$installer = "$Env:TEMP\install-realmroot.ps1" +Invoke-WebRequest ` + https://raw.githubusercontent.com/realmroot/cli/a6451ece639d24b46b11e16dac4b0ee0d9d1b8bb/scripts/install-realmroot.ps1 ` + -OutFile $installer +if ((Get-FileHash $installer -Algorithm SHA256).Hash.ToLowerInvariant() -ne ` + '8eebe604e181d27ec0425b76ab949386174b3af9db493ebf8ab17bc0a6dbbaa0') { + throw 'Realmroot installer checksum mismatch' +} +& $installer -Version 0.4.2 +``` + +These bridge installers use the same `~/.local` versioned layout as Webi and +fail before extraction unless the archive matches the selected GitHub +release's `checksums.txt`. They are not aliases for the pending Webi package; +switch automation to the canonical Webi URLs after the upstream deployment. + Homebrew installs a prebuilt macOS or Linux binary and does not require Go: ```console diff --git a/packaging/webi/README.md b/packaging/webi/README.md new file mode 100644 index 0000000..68af027 --- /dev/null +++ b/packaging/webi/README.md @@ -0,0 +1,12 @@ +# Webi upstream package + +The `realmroot/` directory is the package contribution for +[`webinstall/webi-installers`](https://github.com/webinstall/webi-installers). +Copy it to the upstream repository root and add `realmroot` alphabetically to +the three package lists in `test/install.sh`, as required by upstream's +contribution guide. + +The public `https://webi.sh/realmroot` and `https://webi.ms/realmroot` URLs do +not consume these files from the Realmroot repository. They become available +only after the package is merged upstream and Webi refreshes its deployed +release cache. diff --git a/packaging/webi/realmroot/README.md b/packaging/webi/realmroot/README.md new file mode 100644 index 0000000..d04854e --- /dev/null +++ b/packaging/webi/realmroot/README.md @@ -0,0 +1,58 @@ +--- +title: Realmroot Toolbox +homepage: https://realmroot.dev +tagline: | + Realmroot is an Agent-native toolbox for approved access to private resources. +--- + +To update to the latest stable release, run `webi realmroot@stable`. To install +an explicit release, run `webi realmroot@0.4.2` with the required version. + +### Files + +These files are created or modified by this installer: + +```text +~/.config/envman/PATH.env +~/.local/bin/realmroot +~/.local/opt/realmroot-vVERSION/bin/realmroot +``` + +## Cheat Sheet + +> Realmroot gives Agents one stable identity and lets them discover and invoke +> private capabilities with controller-approved authority. + +### Inspect the Agent identity + +```sh +realmroot agent whoami +``` + +### Discover available Resource Servers + +```sh +realmroot toolbox +realmroot toolbox github +``` + +### Request task-scoped authority + +```sh +realmroot agent request \ + --resource-server github \ + --context realmroot \ + --scope contents:read +``` + +### Run an authenticated native command + +```sh +realmroot exec github -- gh repo view realmroot/cli +``` + +### Inspect the installed version + +```sh +realmroot version +``` diff --git a/packaging/webi/realmroot/install.ps1 b/packaging/webi/realmroot/install.ps1 new file mode 100644 index 0000000..e6238f7 --- /dev/null +++ b/packaging/webi/realmroot/install.ps1 @@ -0,0 +1,86 @@ +#!/usr/bin/env pwsh + +$pkg_cmd_name = "realmroot" + +$pkg_dst_cmd = "$Env:USERPROFILE\.local\bin\realmroot.exe" +$pkg_dst_bin = "$Env:USERPROFILE\.local\bin" +$pkg_dst = "$pkg_dst_cmd" + +$pkg_src_cmd = "$Env:USERPROFILE\.local\opt\realmroot-v$Env:WEBI_VERSION\bin\realmroot.exe" +$pkg_src_bin = "$Env:USERPROFILE\.local\opt\realmroot-v$Env:WEBI_VERSION\bin" +$pkg_src_dir = "$Env:USERPROFILE\.local\opt\realmroot-v$Env:WEBI_VERSION" +$pkg_src = "$pkg_src_cmd" + +function Get-RealmrootFile { + param( + [string]$Url, + [string]$Path + ) + + if (Test-Path -Path $Path) { + Write-Output "Found $Path" + return + } + + $partialPath = "${Path}.part" + Remove-Item -Path $partialPath -Force -ErrorAction Ignore + & curl.exe -A "$Env:WEBI_UA" -fsSL $Url -o $partialPath + if ($LASTEXITCODE -ne 0) { + Remove-Item -Path $partialPath -Force -ErrorAction Ignore + throw "Failed to download $Url" + } + Move-Item -Path $partialPath -Destination $Path +} + +$pkg_download_dir = "$Env:USERPROFILE\Downloads\webi\realmroot\$Env:WEBI_VERSION" +New-Item $pkg_download_dir -ItemType Directory -Force | Out-Null +$pkg_download = "$pkg_download_dir\$Env:WEBI_PKG_FILE" +$checksums_file = "$pkg_download_dir\checksums.txt" +$checksums_url = "https://github.com/realmroot/cli/releases/download/v$Env:WEBI_VERSION/checksums.txt" + +Get-RealmrootFile -Url $Env:WEBI_PKG_URL -Path $pkg_download +Get-RealmrootFile -Url $checksums_url -Path $checksums_file + +$escaped_filename = [regex]::Escape($Env:WEBI_PKG_FILE) +$checksum_pattern = "^(?[0-9a-fA-F]{64})\s+\*?${escaped_filename}$" +$checksum_matches = @( + Get-Content -Path $checksums_file | ForEach-Object { + if ($_ -match $checksum_pattern) { + $Matches['hash'].ToLowerInvariant() + } + } +) +if ($checksum_matches.Count -ne 1) { + throw "Expected one SHA-256 checksum for $Env:WEBI_PKG_FILE" +} + +$actual_checksum = (Get-FileHash -Path $pkg_download -Algorithm SHA256).Hash.ToLowerInvariant() +if ($actual_checksum -ne $checksum_matches[0]) { + Remove-Item -Path $pkg_download -Force + throw "Checksum mismatch for $Env:WEBI_PKG_FILE" +} +Write-Output "Verified SHA-256 checksum for $Env:WEBI_PKG_FILE" + +if (!(Test-Path -Path $pkg_src_cmd)) { + Write-Output "Installing realmroot" + Push-Location .local\tmp + + Remove-Item -Path ".\realmroot.exe" -Force -ErrorAction Ignore + + Write-Output "Unpacking $pkg_download" + & tar xf $pkg_download + if ($LASTEXITCODE -ne 0) { + throw "Failed to unpack $pkg_download" + } + + Write-Output "Install Location: $pkg_src_cmd" + New-Item $pkg_src_bin -ItemType Directory -Force | Out-Null + Move-Item -Path ".\realmroot.exe" -Destination $pkg_src_cmd + + Pop-Location +} + +Write-Output "Copying into '$pkg_dst_cmd' from '$pkg_src_cmd'" +Remove-Item -Path $pkg_dst_cmd -Force -ErrorAction Ignore +New-Item $pkg_dst_bin -ItemType Directory -Force | Out-Null +Copy-Item -Path $pkg_src -Destination $pkg_dst diff --git a/packaging/webi/realmroot/install.sh b/packaging/webi/realmroot/install.sh new file mode 100755 index 0000000..8c5f87d --- /dev/null +++ b/packaging/webi/realmroot/install.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +# shellcheck disable=SC2034 + +__init_realmroot() { + set -e + set -u + + pkg_cmd_name="realmroot" + + pkg_dst_cmd="$HOME/.local/bin/realmroot" + pkg_dst="$pkg_dst_cmd" + + pkg_src_cmd="$HOME/.local/opt/realmroot-v$WEBI_VERSION/bin/realmroot" + pkg_src_dir="$HOME/.local/opt/realmroot-v$WEBI_VERSION" + pkg_src="$pkg_src_cmd" + + pkg_pre_install() { + webi_check_installed + webi_check_available + webi_download \ + "$WEBI_PKG_URL" \ + "$WEBI_PKG_PATH/$WEBI_PKG_FILE" + + my_checksums_url="https://github.com/realmroot/cli/releases/download/v$WEBI_VERSION/checksums.txt" + my_checksums_file="$WEBI_PKG_PATH/checksums.txt" + webi_download "$my_checksums_url" "$my_checksums_file" "realmroot checksums" + + if ! my_expected_checksum="$( + awk -v filename="$WEBI_PKG_FILE" ' + $2 == filename { count++; checksum = $1 } + END { + if (count != 1 || checksum !~ /^[0-9a-fA-F]{64}$/) exit 1 + print tolower(checksum) + } + ' "$my_checksums_file" + )"; then + echo >&2 " Error: expected one SHA-256 checksum for $WEBI_PKG_FILE" + return 1 + fi + + if command -v sha256sum > /dev/null 2>&1; then + my_actual_checksum="$(sha256sum "$WEBI_PKG_PATH/$WEBI_PKG_FILE" | awk '{ print $1 }')" + elif command -v shasum > /dev/null 2>&1; then + my_actual_checksum="$(shasum -a 256 "$WEBI_PKG_PATH/$WEBI_PKG_FILE" | awk '{ print $1 }')" + else + echo >&2 " Error: SHA-256 verification requires sha256sum or shasum" + return 1 + fi + + if test "$my_actual_checksum" != "$my_expected_checksum"; then + rm -f "$WEBI_PKG_PATH/$WEBI_PKG_FILE" + echo >&2 " Error: checksum mismatch for $WEBI_PKG_FILE" + return 1 + fi + + echo " Verified SHA-256 checksum for $WEBI_PKG_FILE" + webi_extract + } + + pkg_install() { + mkdir -p "$(dirname "$pkg_src_cmd")" + mv ./realmroot "$pkg_src_cmd" + } + + pkg_get_current_version() { + realmroot version 2> /dev/null | + head -n 1 | + cut -d ' ' -f 2 | + sed 's:^v::' + } +} + +__init_realmroot diff --git a/packaging/webi/realmroot/releases.conf b/packaging/webi/realmroot/releases.conf new file mode 100644 index 0000000..6e94b10 --- /dev/null +++ b/packaging/webi/realmroot/releases.conf @@ -0,0 +1 @@ +github_releases = realmroot/cli diff --git a/scripts/verify-release-assets.sh b/scripts/verify-release-assets.sh new file mode 100755 index 0000000..3dd8b15 --- /dev/null +++ b/scripts/verify-release-assets.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash + +set -euo pipefail + +dist_dir="${1:-dist}" +checksums_file="$dist_dir/checksums.txt" + +if [[ ! -f "$checksums_file" ]]; then + echo "missing release checksums: $checksums_file" >&2 + exit 1 +fi + +version="$( + find "$dist_dir" -maxdepth 1 -type f -name 'realmroot_*_darwin_amd64.tar.gz' -print | + sed -n 's|.*/realmroot_\(.*\)_darwin_amd64\.tar\.gz$|\1|p' +)" +if [[ -z "$version" || "$version" == *$'\n'* ]]; then + echo "could not determine one release version from $dist_dir" >&2 + exit 1 +fi + +sha256_file() { + if command -v sha256sum >/dev/null 2>&1; then + sha256sum "$1" | awk '{ print $1 }' + return + fi + if command -v shasum >/dev/null 2>&1; then + shasum -a 256 "$1" | awk '{ print $1 }' + return + fi + echo "sha256sum or shasum is required" >&2 + exit 1 +} + +verify_archive() { + local os="$1" + local arch="$2" + local extension="tar.gz" + local binary="realmroot" + if [[ "$os" == "windows" ]]; then + extension="zip" + binary="realmroot.exe" + fi + + local filename="realmroot_${version}_${os}_${arch}.${extension}" + local pathname="$dist_dir/$filename" + if [[ ! -f "$pathname" ]]; then + echo "missing release archive: $filename" >&2 + return 1 + fi + + local checksum_lines + checksum_lines="$(awk -v filename="$filename" '$2 == filename { print $1 }' "$checksums_file")" + if [[ -z "$checksum_lines" || "$checksum_lines" == *$'\n'* || ! "$checksum_lines" =~ ^[0-9a-fA-F]{64}$ ]]; then + echo "expected one SHA-256 checksum for $filename" >&2 + return 1 + fi + + local actual_checksum + actual_checksum="$(sha256_file "$pathname")" + if [[ "${actual_checksum,,}" != "${checksum_lines,,}" ]]; then + echo "checksum mismatch for $filename" >&2 + return 1 + fi + + if [[ "$extension" == "zip" ]]; then + unzip -Z1 "$pathname" | grep -Fxq "$binary" + else + tar -tzf "$pathname" | grep -Fxq "$binary" + fi + echo "verified $filename" +} + +for os in darwin linux windows; do + for arch in amd64 arm64; do + verify_archive "$os" "$arch" + done +done diff --git a/specs/cli.feature b/specs/cli.feature index 2220821..a94c23e 100644 --- a/specs/cli.feature +++ b/specs/cli.feature @@ -6,6 +6,8 @@ Feature: Realmroot Toolbox command line When the release workflow publishes that version Then macOS, Linux, and Windows archives are available with checksums And macOS users can install the same version from the maintained Homebrew Tap + And Webi can install the stable or an explicit version on amd64 and arm64 + And Webi verifies the published checksum before extracting the archive @journey:cli-version @entrypoint:version Scenario: Inspect the installed Toolbox build From 0766e4c2c96b97e86eb30400ada3094106b144aa Mon Sep 17 00:00:00 2001 From: jarvis Date: Sat, 29 Aug 2026 14:36:39 -0400 Subject: [PATCH 03/10] feat(release): publish versioned Webi origin --- .github/workflows/ci.yml | 1 + packaging/webi/README.md | 15 ++++ packaging/webi/origin/realmroot@0.4.2 | 101 ++++++++++++++++++++++++++ scripts/generate-webi-origin.sh | 41 +++++++++++ scripts/install-realmroot.sh | 9 ++- scripts/verify-webi-origin.sh | 98 +++++++++++++++++++++++++ 6 files changed, 264 insertions(+), 1 deletion(-) create mode 100755 packaging/webi/origin/realmroot@0.4.2 create mode 100755 scripts/generate-webi-origin.sh create mode 100755 scripts/verify-webi-origin.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f98406c..d422ef3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,3 +31,4 @@ jobs: version: v2.17.1 args: release --snapshot --clean - run: ./scripts/verify-release-assets.sh dist + - run: ./scripts/verify-webi-origin.sh 0.4.2 diff --git a/packaging/webi/README.md b/packaging/webi/README.md index 68af027..ebee550 100644 --- a/packaging/webi/README.md +++ b/packaging/webi/README.md @@ -10,3 +10,18 @@ The public `https://webi.sh/realmroot` and `https://webi.ms/realmroot` URLs do not consume these files from the Realmroot repository. They become available only after the package is merged upstream and Webi refreshes its deployed release cache. + +## Pre-merge static origin + +The `origin/` directory is a small, Realmroot-owned bridge for consumers that +need Webi's `package@version` URL shape before the upstream deployment. Each +committed `realmroot@` file is generated by +`scripts/generate-webi-origin.sh`. The generator validates the upstream Webi +package's `releases.conf` and seals the requested version into Realmroot's +checksum-verifying installer source. Downloaded CLI archives are verified +against that release's `checksums.txt` before extraction. + +Consumers must pin the origin to the immutable commit that introduced the +generated artifact. They can retain `realmroot@` as their package +declaration and later replace only the origin with `https://webi.sh`; installed +resource data does not change. diff --git a/packaging/webi/origin/realmroot@0.4.2 b/packaging/webi/origin/realmroot@0.4.2 new file mode 100755 index 0000000..9d3e6b7 --- /dev/null +++ b/packaging/webi/origin/realmroot@0.4.2 @@ -0,0 +1,101 @@ +#!/bin/sh + +set -e +set -u + +pinned_version='0.4.2' +if test -n "$pinned_version"; then + requested_version="$pinned_version" +else + requested_version="${1:-${REALMROOT_VERSION:-stable}}" +fi +case "$requested_version" in + stable) + latest_url="$(curl -fsSLo /dev/null -w '%{url_effective}' https://github.com/realmroot/cli/releases/latest)" + version="${latest_url##*/}" + version="${version#v}" + ;; + v*) version="${requested_version#v}" ;; + *) version="$requested_version" ;; +esac + +case "$version" in + '' | *[!0-9A-Za-z.+-]*) + echo "invalid Realmroot version: $version" >&2 + exit 1 + ;; +esac + +case "$(uname -s)" in + Darwin) os="darwin" ;; + Linux) os="linux" ;; + *) + echo "unsupported operating system: $(uname -s)" >&2 + exit 1 + ;; +esac + +case "$(uname -m)" in + x86_64 | amd64) arch="amd64" ;; + arm64 | aarch64) arch="arm64" ;; + *) + echo "unsupported architecture: $(uname -m)" >&2 + exit 1 + ;; +esac + +filename="realmroot_${version}_${os}_${arch}.tar.gz" +release_url="https://github.com/realmroot/cli/releases/download/v${version}" +tmp_dir="$(mktemp -d -t realmroot-install.XXXXXXXX)" +trap 'rm -rf "$tmp_dir"' EXIT HUP INT TERM + +curl -fsSL "$release_url/$filename" -o "$tmp_dir/$filename" +curl -fsSL "$release_url/checksums.txt" -o "$tmp_dir/checksums.txt" + +if ! expected_checksum="$( + awk -v filename="$filename" ' + $2 == filename { count++; checksum = $1 } + END { + if (count != 1 || checksum !~ /^[0-9a-fA-F]{64}$/) exit 1 + print tolower(checksum) + } + ' "$tmp_dir/checksums.txt" +)"; then + echo "expected one SHA-256 checksum for $filename" >&2 + exit 1 +fi + +if command -v sha256sum > /dev/null 2>&1; then + actual_checksum="$(sha256sum "$tmp_dir/$filename" | awk '{ print $1 }')" +elif command -v shasum > /dev/null 2>&1; then + actual_checksum="$(shasum -a 256 "$tmp_dir/$filename" | awk '{ print $1 }')" +else + echo "SHA-256 verification requires sha256sum or shasum" >&2 + exit 1 +fi + +if test "$actual_checksum" != "$expected_checksum"; then + echo "checksum mismatch for $filename" >&2 + exit 1 +fi + +tar -xzf "$tmp_dir/$filename" -C "$tmp_dir" realmroot + +version_dir="$HOME/.local/opt/realmroot-v$version" +bin_dir="$version_dir/bin" +mkdir -p "$bin_dir" "$HOME/.local/bin" "$HOME/.config/envman" +mv "$tmp_dir/realmroot" "$bin_dir/realmroot" +chmod a+x "$bin_dir/realmroot" +ln -sfn "$bin_dir/realmroot" "$HOME/.local/bin/realmroot" + +# Keep HOME and PATH literal so the environment file works for every shell. +# shellcheck disable=SC2016 +path_line='export PATH="$HOME/.local/bin:$PATH"' +path_file="$HOME/.config/envman/PATH.env" +touch "$path_file" +if ! grep -Fqx "$path_line" "$path_file"; then + echo "$path_line" >> "$path_file" +fi + +echo "Installed Realmroot v$version at $HOME/.local/bin/realmroot" +echo "Open a new shell or run: source ~/.config/envman/PATH.env" diff --git a/scripts/generate-webi-origin.sh b/scripts/generate-webi-origin.sh new file mode 100755 index 0000000..b029919 --- /dev/null +++ b/scripts/generate-webi-origin.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +set -e +set -u + +if test "$#" -ne 2; then + echo "usage: $0 " >&2 + exit 1 +fi + +version="${1#v}" +output_dir="$2" + +case "$version" in + '' | *[!0-9A-Za-z.+-]*) + echo "invalid Realmroot version: $version" >&2 + exit 1 + ;; +esac + +script_dir="$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)" +repo_dir="$(dirname "$script_dir")" +source_installer="$script_dir/install-realmroot.sh" +webi_releases="$repo_dir/packaging/webi/realmroot/releases.conf" +output="$output_dir/realmroot@$version" + +if ! grep -Fqx 'github_releases = realmroot/cli' "$webi_releases"; then + echo "unexpected Webi release source in $webi_releases" >&2 + exit 1 +fi + +if test "$(grep -Fxc "pinned_version=''" "$source_installer")" -ne 1; then + echo "expected one version placeholder in $source_installer" >&2 + exit 1 +fi + +mkdir -p "$output_dir" +sed "s/^pinned_version=''$/pinned_version='$version'/" "$source_installer" > "$output" +chmod a+x "$output" + +echo "Generated $output from packaging/webi/realmroot and scripts/install-realmroot.sh" diff --git a/scripts/install-realmroot.sh b/scripts/install-realmroot.sh index 0e5bec2..cfdf8c0 100755 --- a/scripts/install-realmroot.sh +++ b/scripts/install-realmroot.sh @@ -3,7 +3,12 @@ set -e set -u -requested_version="${1:-${REALMROOT_VERSION:-stable}}" +pinned_version='' +if test -n "$pinned_version"; then + requested_version="$pinned_version" +else + requested_version="${1:-${REALMROOT_VERSION:-stable}}" +fi case "$requested_version" in stable) latest_url="$(curl -fsSLo /dev/null -w '%{url_effective}' https://github.com/realmroot/cli/releases/latest)" @@ -83,6 +88,8 @@ mv "$tmp_dir/realmroot" "$bin_dir/realmroot" chmod a+x "$bin_dir/realmroot" ln -sfn "$bin_dir/realmroot" "$HOME/.local/bin/realmroot" +# Keep HOME and PATH literal so the environment file works for every shell. +# shellcheck disable=SC2016 path_line='export PATH="$HOME/.local/bin:$PATH"' path_file="$HOME/.config/envman/PATH.env" touch "$path_file" diff --git a/scripts/verify-webi-origin.sh b/scripts/verify-webi-origin.sh new file mode 100755 index 0000000..ac790ed --- /dev/null +++ b/scripts/verify-webi-origin.sh @@ -0,0 +1,98 @@ +#!/bin/sh + +set -e +set -u + +if test "$#" -ne 1; then + echo "usage: $0 " >&2 + exit 1 +fi + +version="${1#v}" +script_dir="$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)" +repo_dir="$(dirname "$script_dir")" +committed="$repo_dir/packaging/webi/origin/realmroot@$version" +tmp_dir="$(mktemp -d -t realmroot-webi-origin.XXXXXXXX)" +trap 'rm -rf "$tmp_dir"' EXIT HUP INT TERM + +"$script_dir/generate-webi-origin.sh" "$version" "$tmp_dir/generated" +cmp "$committed" "$tmp_dir/generated/realmroot@$version" + +mkdir -p "$tmp_dir/bin" "$tmp_dir/fixtures" +cat > "$tmp_dir/bin/uname" <<'EOF' +#!/bin/sh +case "$1" in + -s) printf '%s\n' "$TEST_UNAME_OS" ;; + -m) printf '%s\n' "$TEST_UNAME_ARCH" ;; + *) exit 1 ;; +esac +EOF +cat > "$tmp_dir/bin/curl" <<'EOF' +#!/bin/sh +output='' +url='' +while test "$#" -gt 0; do + case "$1" in + -o) output="$2"; shift 2 ;; + -*) shift ;; + *) url="$1"; shift ;; + esac +done +test -n "$output" +test -n "$url" +cp "$TEST_FIXTURES/${url##*/}" "$output" +EOF +chmod a+x "$tmp_dir/bin/uname" "$tmp_dir/bin/curl" + +verify_target() { + os="$1" + arch="$2" + uname_os="$3" + uname_arch="$4" + filename="realmroot_${version}_${os}_${arch}.tar.gz" + target_dir="$tmp_dir/target-$os-$arch" + home_dir="$tmp_dir/home-$os-$arch" + + mkdir -p "$target_dir" "$home_dir" + printf '#!/bin/sh\nprintf "realmroot v%s\\n"\n' "$version" > "$target_dir/realmroot" + chmod a+x "$target_dir/realmroot" + tar -czf "$tmp_dir/fixtures/$filename" -C "$target_dir" realmroot + if command -v sha256sum > /dev/null 2>&1; then + checksum="$(sha256sum "$tmp_dir/fixtures/$filename" | awk '{ print $1 }')" + else + checksum="$(shasum -a 256 "$tmp_dir/fixtures/$filename" | awk '{ print $1 }')" + fi + printf '%s %s\n' "$checksum" "$filename" > "$tmp_dir/fixtures/checksums.txt" + + HOME="$home_dir" \ + PATH="$tmp_dir/bin:/usr/bin:/bin" \ + TEST_FIXTURES="$tmp_dir/fixtures" \ + TEST_UNAME_OS="$uname_os" \ + TEST_UNAME_ARCH="$uname_arch" \ + REALMROOT_VERSION=9.9.9 \ + sh "$committed" 8.8.8 + + test "$("$home_dir/.local/bin/realmroot")" = "realmroot v$version" +} + +verify_target darwin amd64 Darwin x86_64 +verify_target darwin arm64 Darwin arm64 +verify_target linux amd64 Linux x86_64 +verify_target linux arm64 Linux aarch64 + +corrupt_home="$tmp_dir/home-corrupt" +mkdir -p "$corrupt_home" +printf '%064d realmroot_%s_linux_amd64.tar.gz\n' 0 "$version" > "$tmp_dir/fixtures/checksums.txt" +if HOME="$corrupt_home" \ + PATH="$tmp_dir/bin:/usr/bin:/bin" \ + TEST_FIXTURES="$tmp_dir/fixtures" \ + TEST_UNAME_OS=Linux \ + TEST_UNAME_ARCH=x86_64 \ + sh "$committed" > "$tmp_dir/corrupt.log" 2>&1; then + echo "corrupt archive unexpectedly installed" >&2 + exit 1 +fi +grep -Fq 'checksum mismatch' "$tmp_dir/corrupt.log" +test ! -e "$corrupt_home/.local/bin/realmroot" + +echo "Verified generated Webi origin for Realmroot v$version" From cb254f2fa17b4f58bb447c731fe61b002945c0e4 Mon Sep 17 00:00:00 2001 From: jarvis Date: Sat, 29 Aug 2026 14:37:16 -0400 Subject: [PATCH 04/10] docs: document temporary AMA Webi origin --- README.md | 43 ++++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index d42770f..5a7b84d 100644 --- a/README.md +++ b/README.md @@ -38,38 +38,27 @@ arm64. The `webi.sh/realmroot` and `webi.ms/realmroot` URLs become available only after the Realmroot package is merged into [`webinstall/webi-installers`](https://github.com/webinstall/webi-installers) -and deployed by Webi. Until then, automation can use the Realmroot-owned bridge -installer from the immutable commit below. Pin both the installer commit and -the CLI release version; `stable` intentionally follows future releases. +and deployed by Webi. -On macOS or Linux: +Before that deployment, AMA can keep its declarative package pinned as +`realmroot@0.4.2` and use Realmroot's temporary static origin: ```console -curl -fsSLo /tmp/install-realmroot.sh \ - https://raw.githubusercontent.com/realmroot/cli/a6451ece639d24b46b11e16dac4b0ee0d9d1b8bb/scripts/install-realmroot.sh -echo '96c47a9d9295654c6110446a42194af47f22f8c9a6606689749bc0a50acb31c6 /tmp/install-realmroot.sh' \ - | shasum -a 256 -c - -REALMROOT_VERSION=0.4.2 sh /tmp/install-realmroot.sh +export AMA_WEBI_ORIGIN=https://raw.githubusercontent.com/realmroot/cli/0766e4c2c96b97e86eb30400ada3094106b144aa/packaging/webi/origin ``` -On Windows PowerShell: - -```powershell -$installer = "$Env:TEMP\install-realmroot.ps1" -Invoke-WebRequest ` - https://raw.githubusercontent.com/realmroot/cli/a6451ece639d24b46b11e16dac4b0ee0d9d1b8bb/scripts/install-realmroot.ps1 ` - -OutFile $installer -if ((Get-FileHash $installer -Algorithm SHA256).Hash.ToLowerInvariant() -ne ` - '8eebe604e181d27ec0425b76ab949386174b3af9db493ebf8ab17bc0a6dbbaa0') { - throw 'Realmroot installer checksum mismatch' -} -& $installer -Version 0.4.2 -``` - -These bridge installers use the same `~/.local` versioned layout as Webi and -fail before extraction unless the archive matches the selected GitHub -release's `checksums.txt`. They are not aliases for the pending Webi package; -switch automation to the canonical Webi URLs after the upstream deployment. +The complete installer is therefore fetched from +`$AMA_WEBI_ORIGIN/realmroot@0.4.2`. Its SHA-256 digest is +`02599b467d05b00862f0e5edfecaad6fb63901e0ef8c1399897d38eed29723a6`. +The immutable Git commit pins the installer implementation, and the package +suffix pins the CLI release. The generated installer rejects version +overrides and fails before extraction unless the selected archive matches +release `v0.4.2`'s `checksums.txt`. + +This origin is a committed static artifact, not a custom Webinstall service. +After the upstream Webi deployment, AMA changes only `AMA_WEBI_ORIGIN` to +`https://webi.sh`; `realmroot@0.4.2` and the installed resource data remain +unchanged. Homebrew installs a prebuilt macOS or Linux binary and does not require Go: From 0dbd62b6d0deb86c39fbaa93f0a7ed68a42e9fbd Mon Sep 17 00:00:00 2001 From: jarvis Date: Sat, 29 Aug 2026 14:39:00 -0400 Subject: [PATCH 05/10] refactor(release): keep Webi integration upstream-only --- .github/workflows/ci.yml | 1 - README.md | 23 +----- packaging/webi/README.md | 15 ---- packaging/webi/origin/realmroot@0.4.2 | 101 -------------------------- scripts/generate-webi-origin.sh | 41 ----------- scripts/install-realmroot.ps1 | 82 --------------------- scripts/install-realmroot.sh | 101 -------------------------- scripts/verify-webi-origin.sh | 98 ------------------------- 8 files changed, 3 insertions(+), 459 deletions(-) delete mode 100755 packaging/webi/origin/realmroot@0.4.2 delete mode 100755 scripts/generate-webi-origin.sh delete mode 100644 scripts/install-realmroot.ps1 delete mode 100755 scripts/install-realmroot.sh delete mode 100755 scripts/verify-webi-origin.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d422ef3..f98406c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,4 +31,3 @@ jobs: version: v2.17.1 args: release --snapshot --clean - run: ./scripts/verify-release-assets.sh dist - - run: ./scripts/verify-webi-origin.sh 0.4.2 diff --git a/README.md b/README.md index 5a7b84d..fab702a 100644 --- a/README.md +++ b/README.md @@ -39,26 +39,9 @@ The `webi.sh/realmroot` and `webi.ms/realmroot` URLs become available only after the Realmroot package is merged into [`webinstall/webi-installers`](https://github.com/webinstall/webi-installers) and deployed by Webi. - -Before that deployment, AMA can keep its declarative package pinned as -`realmroot@0.4.2` and use Realmroot's temporary static origin: - -```console -export AMA_WEBI_ORIGIN=https://raw.githubusercontent.com/realmroot/cli/0766e4c2c96b97e86eb30400ada3094106b144aa/packaging/webi/origin -``` - -The complete installer is therefore fetched from -`$AMA_WEBI_ORIGIN/realmroot@0.4.2`. Its SHA-256 digest is -`02599b467d05b00862f0e5edfecaad6fb63901e0ef8c1399897d38eed29723a6`. -The immutable Git commit pins the installer implementation, and the package -suffix pins the CLI release. The generated installer rejects version -overrides and fails before extraction unless the selected archive matches -release `v0.4.2`'s `checksums.txt`. - -This origin is a committed static artifact, not a custom Webinstall service. -After the upstream Webi deployment, AMA changes only `AMA_WEBI_ORIGIN` to -`https://webi.sh`; `realmroot@0.4.2` and the installed resource data remain -unchanged. +There is no Realmroot-hosted Webi origin or pre-deployment installer endpoint. +Use the GitHub release archives directly, with `checksums.txt` verification, +until the official Webi deployment is available. Homebrew installs a prebuilt macOS or Linux binary and does not require Go: diff --git a/packaging/webi/README.md b/packaging/webi/README.md index ebee550..68af027 100644 --- a/packaging/webi/README.md +++ b/packaging/webi/README.md @@ -10,18 +10,3 @@ The public `https://webi.sh/realmroot` and `https://webi.ms/realmroot` URLs do not consume these files from the Realmroot repository. They become available only after the package is merged upstream and Webi refreshes its deployed release cache. - -## Pre-merge static origin - -The `origin/` directory is a small, Realmroot-owned bridge for consumers that -need Webi's `package@version` URL shape before the upstream deployment. Each -committed `realmroot@` file is generated by -`scripts/generate-webi-origin.sh`. The generator validates the upstream Webi -package's `releases.conf` and seals the requested version into Realmroot's -checksum-verifying installer source. Downloaded CLI archives are verified -against that release's `checksums.txt` before extraction. - -Consumers must pin the origin to the immutable commit that introduced the -generated artifact. They can retain `realmroot@` as their package -declaration and later replace only the origin with `https://webi.sh`; installed -resource data does not change. diff --git a/packaging/webi/origin/realmroot@0.4.2 b/packaging/webi/origin/realmroot@0.4.2 deleted file mode 100755 index 9d3e6b7..0000000 --- a/packaging/webi/origin/realmroot@0.4.2 +++ /dev/null @@ -1,101 +0,0 @@ -#!/bin/sh - -set -e -set -u - -pinned_version='0.4.2' -if test -n "$pinned_version"; then - requested_version="$pinned_version" -else - requested_version="${1:-${REALMROOT_VERSION:-stable}}" -fi -case "$requested_version" in - stable) - latest_url="$(curl -fsSLo /dev/null -w '%{url_effective}' https://github.com/realmroot/cli/releases/latest)" - version="${latest_url##*/}" - version="${version#v}" - ;; - v*) version="${requested_version#v}" ;; - *) version="$requested_version" ;; -esac - -case "$version" in - '' | *[!0-9A-Za-z.+-]*) - echo "invalid Realmroot version: $version" >&2 - exit 1 - ;; -esac - -case "$(uname -s)" in - Darwin) os="darwin" ;; - Linux) os="linux" ;; - *) - echo "unsupported operating system: $(uname -s)" >&2 - exit 1 - ;; -esac - -case "$(uname -m)" in - x86_64 | amd64) arch="amd64" ;; - arm64 | aarch64) arch="arm64" ;; - *) - echo "unsupported architecture: $(uname -m)" >&2 - exit 1 - ;; -esac - -filename="realmroot_${version}_${os}_${arch}.tar.gz" -release_url="https://github.com/realmroot/cli/releases/download/v${version}" -tmp_dir="$(mktemp -d -t realmroot-install.XXXXXXXX)" -trap 'rm -rf "$tmp_dir"' EXIT HUP INT TERM - -curl -fsSL "$release_url/$filename" -o "$tmp_dir/$filename" -curl -fsSL "$release_url/checksums.txt" -o "$tmp_dir/checksums.txt" - -if ! expected_checksum="$( - awk -v filename="$filename" ' - $2 == filename { count++; checksum = $1 } - END { - if (count != 1 || checksum !~ /^[0-9a-fA-F]{64}$/) exit 1 - print tolower(checksum) - } - ' "$tmp_dir/checksums.txt" -)"; then - echo "expected one SHA-256 checksum for $filename" >&2 - exit 1 -fi - -if command -v sha256sum > /dev/null 2>&1; then - actual_checksum="$(sha256sum "$tmp_dir/$filename" | awk '{ print $1 }')" -elif command -v shasum > /dev/null 2>&1; then - actual_checksum="$(shasum -a 256 "$tmp_dir/$filename" | awk '{ print $1 }')" -else - echo "SHA-256 verification requires sha256sum or shasum" >&2 - exit 1 -fi - -if test "$actual_checksum" != "$expected_checksum"; then - echo "checksum mismatch for $filename" >&2 - exit 1 -fi - -tar -xzf "$tmp_dir/$filename" -C "$tmp_dir" realmroot - -version_dir="$HOME/.local/opt/realmroot-v$version" -bin_dir="$version_dir/bin" -mkdir -p "$bin_dir" "$HOME/.local/bin" "$HOME/.config/envman" -mv "$tmp_dir/realmroot" "$bin_dir/realmroot" -chmod a+x "$bin_dir/realmroot" -ln -sfn "$bin_dir/realmroot" "$HOME/.local/bin/realmroot" - -# Keep HOME and PATH literal so the environment file works for every shell. -# shellcheck disable=SC2016 -path_line='export PATH="$HOME/.local/bin:$PATH"' -path_file="$HOME/.config/envman/PATH.env" -touch "$path_file" -if ! grep -Fqx "$path_line" "$path_file"; then - echo "$path_line" >> "$path_file" -fi - -echo "Installed Realmroot v$version at $HOME/.local/bin/realmroot" -echo "Open a new shell or run: source ~/.config/envman/PATH.env" diff --git a/scripts/generate-webi-origin.sh b/scripts/generate-webi-origin.sh deleted file mode 100755 index b029919..0000000 --- a/scripts/generate-webi-origin.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/sh - -set -e -set -u - -if test "$#" -ne 2; then - echo "usage: $0 " >&2 - exit 1 -fi - -version="${1#v}" -output_dir="$2" - -case "$version" in - '' | *[!0-9A-Za-z.+-]*) - echo "invalid Realmroot version: $version" >&2 - exit 1 - ;; -esac - -script_dir="$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)" -repo_dir="$(dirname "$script_dir")" -source_installer="$script_dir/install-realmroot.sh" -webi_releases="$repo_dir/packaging/webi/realmroot/releases.conf" -output="$output_dir/realmroot@$version" - -if ! grep -Fqx 'github_releases = realmroot/cli' "$webi_releases"; then - echo "unexpected Webi release source in $webi_releases" >&2 - exit 1 -fi - -if test "$(grep -Fxc "pinned_version=''" "$source_installer")" -ne 1; then - echo "expected one version placeholder in $source_installer" >&2 - exit 1 -fi - -mkdir -p "$output_dir" -sed "s/^pinned_version=''$/pinned_version='$version'/" "$source_installer" > "$output" -chmod a+x "$output" - -echo "Generated $output from packaging/webi/realmroot and scripts/install-realmroot.sh" diff --git a/scripts/install-realmroot.ps1 b/scripts/install-realmroot.ps1 deleted file mode 100644 index dd4fb01..0000000 --- a/scripts/install-realmroot.ps1 +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env pwsh - -param( - [string]$Version = $Env:REALMROOT_VERSION -) - -$ErrorActionPreference = 'Stop' -$ProgressPreference = 'SilentlyContinue' - -if ([string]::IsNullOrWhiteSpace($Version) -or $Version -eq 'stable') { - $release = Invoke-RestMethod -Uri 'https://api.github.com/repos/realmroot/cli/releases/latest' - $Version = $release.tag_name.TrimStart('v') -} else { - $Version = $Version.TrimStart('v') -} -if ($Version -notmatch '^[0-9A-Za-z.+-]+$') { - throw "Invalid Realmroot version: $Version" -} - -$architecture = $Env:PROCESSOR_ARCHITEW6432 -if ([string]::IsNullOrWhiteSpace($architecture)) { - $architecture = $Env:PROCESSOR_ARCHITECTURE -} -switch ($architecture) { - 'AMD64' { $arch = 'amd64' } - 'ARM64' { $arch = 'arm64' } - default { throw "Unsupported Windows architecture: $architecture" } -} - -$filename = "realmroot_${Version}_windows_${arch}.zip" -$releaseUrl = "https://github.com/realmroot/cli/releases/download/v${Version}" -$tempDir = Join-Path ([System.IO.Path]::GetTempPath()) ("realmroot-install-" + [guid]::NewGuid()) -$archivePath = Join-Path $tempDir $filename -$checksumsPath = Join-Path $tempDir 'checksums.txt' -New-Item $tempDir -ItemType Directory | Out-Null - -try { - Invoke-WebRequest -Uri "$releaseUrl/$filename" -OutFile $archivePath - Invoke-WebRequest -Uri "$releaseUrl/checksums.txt" -OutFile $checksumsPath - - $escapedFilename = [regex]::Escape($filename) - $checksumPattern = "^(?[0-9a-fA-F]{64})\s+\*?${escapedFilename}$" - $checksumMatches = @( - Get-Content -Path $checksumsPath | ForEach-Object { - if ($_ -match $checksumPattern) { - $Matches['hash'].ToLowerInvariant() - } - } - ) - if ($checksumMatches.Count -ne 1) { - throw "Expected one SHA-256 checksum for $filename" - } - - $actualChecksum = (Get-FileHash -Path $archivePath -Algorithm SHA256).Hash.ToLowerInvariant() - if ($actualChecksum -ne $checksumMatches[0]) { - throw "Checksum mismatch for $filename" - } - - Expand-Archive -Path $archivePath -DestinationPath $tempDir -Force - - $versionDir = Join-Path $Env:USERPROFILE ".local\opt\realmroot-v$Version" - $sourceBin = Join-Path $versionDir 'bin' - $destinationBin = Join-Path $Env:USERPROFILE '.local\bin' - $sourceCommand = Join-Path $sourceBin 'realmroot.exe' - $destinationCommand = Join-Path $destinationBin 'realmroot.exe' - - New-Item $sourceBin -ItemType Directory -Force | Out-Null - New-Item $destinationBin -ItemType Directory -Force | Out-Null - Move-Item -Path (Join-Path $tempDir 'realmroot.exe') -Destination $sourceCommand -Force - Copy-Item -Path $sourceCommand -Destination $destinationCommand -Force - - $userPath = [Environment]::GetEnvironmentVariable('Path', 'User') - $pathEntries = @($userPath -split ';' | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }) - if ($pathEntries -notcontains $destinationBin) { - [Environment]::SetEnvironmentVariable('Path', (($destinationBin) + ';' + $userPath).TrimEnd(';'), 'User') - } - - Write-Output "Installed Realmroot v$Version at $destinationCommand" - Write-Output 'Open a new PowerShell session before running realmroot.' -} finally { - Remove-Item -Path $tempDir -Recurse -Force -ErrorAction Ignore -} diff --git a/scripts/install-realmroot.sh b/scripts/install-realmroot.sh deleted file mode 100755 index cfdf8c0..0000000 --- a/scripts/install-realmroot.sh +++ /dev/null @@ -1,101 +0,0 @@ -#!/bin/sh - -set -e -set -u - -pinned_version='' -if test -n "$pinned_version"; then - requested_version="$pinned_version" -else - requested_version="${1:-${REALMROOT_VERSION:-stable}}" -fi -case "$requested_version" in - stable) - latest_url="$(curl -fsSLo /dev/null -w '%{url_effective}' https://github.com/realmroot/cli/releases/latest)" - version="${latest_url##*/}" - version="${version#v}" - ;; - v*) version="${requested_version#v}" ;; - *) version="$requested_version" ;; -esac - -case "$version" in - '' | *[!0-9A-Za-z.+-]*) - echo "invalid Realmroot version: $version" >&2 - exit 1 - ;; -esac - -case "$(uname -s)" in - Darwin) os="darwin" ;; - Linux) os="linux" ;; - *) - echo "unsupported operating system: $(uname -s)" >&2 - exit 1 - ;; -esac - -case "$(uname -m)" in - x86_64 | amd64) arch="amd64" ;; - arm64 | aarch64) arch="arm64" ;; - *) - echo "unsupported architecture: $(uname -m)" >&2 - exit 1 - ;; -esac - -filename="realmroot_${version}_${os}_${arch}.tar.gz" -release_url="https://github.com/realmroot/cli/releases/download/v${version}" -tmp_dir="$(mktemp -d -t realmroot-install.XXXXXXXX)" -trap 'rm -rf "$tmp_dir"' EXIT HUP INT TERM - -curl -fsSL "$release_url/$filename" -o "$tmp_dir/$filename" -curl -fsSL "$release_url/checksums.txt" -o "$tmp_dir/checksums.txt" - -if ! expected_checksum="$( - awk -v filename="$filename" ' - $2 == filename { count++; checksum = $1 } - END { - if (count != 1 || checksum !~ /^[0-9a-fA-F]{64}$/) exit 1 - print tolower(checksum) - } - ' "$tmp_dir/checksums.txt" -)"; then - echo "expected one SHA-256 checksum for $filename" >&2 - exit 1 -fi - -if command -v sha256sum > /dev/null 2>&1; then - actual_checksum="$(sha256sum "$tmp_dir/$filename" | awk '{ print $1 }')" -elif command -v shasum > /dev/null 2>&1; then - actual_checksum="$(shasum -a 256 "$tmp_dir/$filename" | awk '{ print $1 }')" -else - echo "SHA-256 verification requires sha256sum or shasum" >&2 - exit 1 -fi - -if test "$actual_checksum" != "$expected_checksum"; then - echo "checksum mismatch for $filename" >&2 - exit 1 -fi - -tar -xzf "$tmp_dir/$filename" -C "$tmp_dir" realmroot - -version_dir="$HOME/.local/opt/realmroot-v$version" -bin_dir="$version_dir/bin" -mkdir -p "$bin_dir" "$HOME/.local/bin" "$HOME/.config/envman" -mv "$tmp_dir/realmroot" "$bin_dir/realmroot" -chmod a+x "$bin_dir/realmroot" -ln -sfn "$bin_dir/realmroot" "$HOME/.local/bin/realmroot" - -# Keep HOME and PATH literal so the environment file works for every shell. -# shellcheck disable=SC2016 -path_line='export PATH="$HOME/.local/bin:$PATH"' -path_file="$HOME/.config/envman/PATH.env" -touch "$path_file" -if ! grep -Fqx "$path_line" "$path_file"; then - echo "$path_line" >> "$path_file" -fi - -echo "Installed Realmroot v$version at $HOME/.local/bin/realmroot" -echo "Open a new shell or run: source ~/.config/envman/PATH.env" diff --git a/scripts/verify-webi-origin.sh b/scripts/verify-webi-origin.sh deleted file mode 100755 index ac790ed..0000000 --- a/scripts/verify-webi-origin.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/sh - -set -e -set -u - -if test "$#" -ne 1; then - echo "usage: $0 " >&2 - exit 1 -fi - -version="${1#v}" -script_dir="$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)" -repo_dir="$(dirname "$script_dir")" -committed="$repo_dir/packaging/webi/origin/realmroot@$version" -tmp_dir="$(mktemp -d -t realmroot-webi-origin.XXXXXXXX)" -trap 'rm -rf "$tmp_dir"' EXIT HUP INT TERM - -"$script_dir/generate-webi-origin.sh" "$version" "$tmp_dir/generated" -cmp "$committed" "$tmp_dir/generated/realmroot@$version" - -mkdir -p "$tmp_dir/bin" "$tmp_dir/fixtures" -cat > "$tmp_dir/bin/uname" <<'EOF' -#!/bin/sh -case "$1" in - -s) printf '%s\n' "$TEST_UNAME_OS" ;; - -m) printf '%s\n' "$TEST_UNAME_ARCH" ;; - *) exit 1 ;; -esac -EOF -cat > "$tmp_dir/bin/curl" <<'EOF' -#!/bin/sh -output='' -url='' -while test "$#" -gt 0; do - case "$1" in - -o) output="$2"; shift 2 ;; - -*) shift ;; - *) url="$1"; shift ;; - esac -done -test -n "$output" -test -n "$url" -cp "$TEST_FIXTURES/${url##*/}" "$output" -EOF -chmod a+x "$tmp_dir/bin/uname" "$tmp_dir/bin/curl" - -verify_target() { - os="$1" - arch="$2" - uname_os="$3" - uname_arch="$4" - filename="realmroot_${version}_${os}_${arch}.tar.gz" - target_dir="$tmp_dir/target-$os-$arch" - home_dir="$tmp_dir/home-$os-$arch" - - mkdir -p "$target_dir" "$home_dir" - printf '#!/bin/sh\nprintf "realmroot v%s\\n"\n' "$version" > "$target_dir/realmroot" - chmod a+x "$target_dir/realmroot" - tar -czf "$tmp_dir/fixtures/$filename" -C "$target_dir" realmroot - if command -v sha256sum > /dev/null 2>&1; then - checksum="$(sha256sum "$tmp_dir/fixtures/$filename" | awk '{ print $1 }')" - else - checksum="$(shasum -a 256 "$tmp_dir/fixtures/$filename" | awk '{ print $1 }')" - fi - printf '%s %s\n' "$checksum" "$filename" > "$tmp_dir/fixtures/checksums.txt" - - HOME="$home_dir" \ - PATH="$tmp_dir/bin:/usr/bin:/bin" \ - TEST_FIXTURES="$tmp_dir/fixtures" \ - TEST_UNAME_OS="$uname_os" \ - TEST_UNAME_ARCH="$uname_arch" \ - REALMROOT_VERSION=9.9.9 \ - sh "$committed" 8.8.8 - - test "$("$home_dir/.local/bin/realmroot")" = "realmroot v$version" -} - -verify_target darwin amd64 Darwin x86_64 -verify_target darwin arm64 Darwin arm64 -verify_target linux amd64 Linux x86_64 -verify_target linux arm64 Linux aarch64 - -corrupt_home="$tmp_dir/home-corrupt" -mkdir -p "$corrupt_home" -printf '%064d realmroot_%s_linux_amd64.tar.gz\n' 0 "$version" > "$tmp_dir/fixtures/checksums.txt" -if HOME="$corrupt_home" \ - PATH="$tmp_dir/bin:/usr/bin:/bin" \ - TEST_FIXTURES="$tmp_dir/fixtures" \ - TEST_UNAME_OS=Linux \ - TEST_UNAME_ARCH=x86_64 \ - sh "$committed" > "$tmp_dir/corrupt.log" 2>&1; then - echo "corrupt archive unexpectedly installed" >&2 - exit 1 -fi -grep -Fq 'checksum mismatch' "$tmp_dir/corrupt.log" -test ! -e "$corrupt_home/.local/bin/realmroot" - -echo "Verified generated Webi origin for Realmroot v$version" From 07363e5bf4f99b641c172714908f08e18fc5814d Mon Sep 17 00:00:00 2001 From: jarvis Date: Sat, 29 Aug 2026 14:41:53 -0400 Subject: [PATCH 06/10] docs(webi): request upstream beta validation --- packaging/webi/README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/packaging/webi/README.md b/packaging/webi/README.md index 68af027..466faf7 100644 --- a/packaging/webi/README.md +++ b/packaging/webi/README.md @@ -10,3 +10,24 @@ The public `https://webi.sh/realmroot` and `https://webi.ms/realmroot` URLs do not consume these files from the Realmroot repository. They become available only after the package is merged upstream and Webi refreshes its deployed release cache. + +## Upstream Beta validation request + +When submitting these files upstream, ask a Webi maintainer to deploy the PR +candidate to Webi Beta before merge. The deployment is maintainer-controlled; +Realmroot does not publish or operate an alternate Webi origin. + +After the candidate is deployed, smoke-test both release selectors on a clean +macOS or Linux account: + +```console +curl -sS https://beta.webi.sh/realmroot@stable | sh +realmroot version +curl -sS https://beta.webi.sh/realmroot@0.4.2 | sh +realmroot version +``` + +Both installers must select the target-appropriate archive and verify it +against the selected GitHub release's `checksums.txt`. A successful Beta test +does not make the production URLs available; production use still begins only +after upstream merge and deployment. From aab3090ee1b142fe3e6e1c9fdcd7106e89c25289 Mon Sep 17 00:00:00 2001 From: jarvis Date: Sat, 29 Aug 2026 14:47:50 -0400 Subject: [PATCH 07/10] ci(release): bound snapshot build parallelism --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f98406c..b108925 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,5 +29,5 @@ jobs: with: distribution: goreleaser version: v2.17.1 - args: release --snapshot --clean + args: --parallelism 2 release --snapshot --clean - run: ./scripts/verify-release-assets.sh dist From dcc6a609870fe0071f4b51708ddf817119ccdeb6 Mon Sep 17 00:00:00 2001 From: jarvis Date: Sat, 29 Aug 2026 14:50:52 -0400 Subject: [PATCH 08/10] ci(release): parallelize target build verification --- .github/workflows/ci.yml | 48 +++++++++++++++++++++++++++++++--- scripts/verify-build-matrix.sh | 39 +++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 3 deletions(-) create mode 100755 scripts/verify-build-matrix.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b108925..c229602 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,15 +19,57 @@ jobs: cache: true - run: go test ./... - run: go vet ./... - - run: go build ./... - uses: goreleaser/goreleaser-action@v7 with: distribution: goreleaser version: v2.17.1 args: check + + build-matrix: + name: build (${{ matrix.goos }}/${{ matrix.goarch }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + goos: [darwin, linux, windows] + goarch: [amd64, arm64] + steps: + - uses: actions/checkout@v7 + with: + fetch-depth: 0 + - uses: actions/setup-go@v7 + with: + go-version-file: go.mod + cache: true + - run: mkdir build - uses: goreleaser/goreleaser-action@v7 with: distribution: goreleaser version: v2.17.1 - args: --parallelism 2 release --snapshot --clean - - run: ./scripts/verify-release-assets.sh dist + args: >- + build --single-target --snapshot --clean + --output build/realmroot_${{ matrix.goos }}_${{ matrix.goarch }}${{ matrix.goos == 'windows' && '.exe' || '' }} + env: + GOOS: ${{ matrix.goos }} + GOARCH: ${{ matrix.goarch }} + - uses: actions/upload-artifact@v7 + with: + name: realmroot-${{ matrix.goos }}-${{ matrix.goarch }} + path: build/realmroot_* + if-no-files-found: error + + verify-build-matrix: + runs-on: ubuntu-latest + needs: build-matrix + steps: + - uses: actions/checkout@v7 + - uses: actions/setup-go@v7 + with: + go-version-file: go.mod + cache: false + - uses: actions/download-artifact@v8 + with: + pattern: realmroot-* + path: build + merge-multiple: true + - run: ./scripts/verify-build-matrix.sh build diff --git a/scripts/verify-build-matrix.sh b/scripts/verify-build-matrix.sh new file mode 100755 index 0000000..1db302e --- /dev/null +++ b/scripts/verify-build-matrix.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +set -euo pipefail + +build_dir="${1:-build}" +targets=( + darwin_amd64 + darwin_arm64 + linux_amd64 + linux_arm64 + windows_amd64 + windows_arm64 +) + +actual_count="$(find "$build_dir" -maxdepth 1 -type f -name 'realmroot_*' | wc -l | tr -d ' ')" +if [[ "$actual_count" != "${#targets[@]}" ]]; then + echo "expected ${#targets[@]} matrix binaries, found $actual_count" >&2 + exit 1 +fi + +for target in "${targets[@]}"; do + os="${target%_*}" + arch="${target#*_}" + suffix='' + if [[ "$os" == windows ]]; then + suffix='.exe' + fi + + binary="$build_dir/realmroot_${target}${suffix}" + if [[ ! -f "$binary" ]]; then + echo "missing matrix binary: $binary" >&2 + exit 1 + fi + + metadata="$(go version -m "$binary")" + grep -Fq $'\tbuild\tGOOS='"$os" <<<"$metadata" + grep -Fq $'\tbuild\tGOARCH='"$arch" <<<"$metadata" + echo "verified realmroot_${target}${suffix}" +done From 6da15f76f9a1da0e6360a377c3c841a692a54624 Mon Sep 17 00:00:00 2001 From: jarvis Date: Sat, 29 Aug 2026 14:54:56 -0400 Subject: [PATCH 09/10] revert(ci): defer target matrix optimization --- .github/workflows/ci.yml | 50 +--------------------------------- scripts/verify-build-matrix.sh | 39 -------------------------- 2 files changed, 1 insertion(+), 88 deletions(-) delete mode 100755 scripts/verify-build-matrix.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c229602..1d9bf60 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,57 +19,9 @@ jobs: cache: true - run: go test ./... - run: go vet ./... + - run: go build ./... - uses: goreleaser/goreleaser-action@v7 with: distribution: goreleaser version: v2.17.1 args: check - - build-matrix: - name: build (${{ matrix.goos }}/${{ matrix.goarch }}) - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - goos: [darwin, linux, windows] - goarch: [amd64, arm64] - steps: - - uses: actions/checkout@v7 - with: - fetch-depth: 0 - - uses: actions/setup-go@v7 - with: - go-version-file: go.mod - cache: true - - run: mkdir build - - uses: goreleaser/goreleaser-action@v7 - with: - distribution: goreleaser - version: v2.17.1 - args: >- - build --single-target --snapshot --clean - --output build/realmroot_${{ matrix.goos }}_${{ matrix.goarch }}${{ matrix.goos == 'windows' && '.exe' || '' }} - env: - GOOS: ${{ matrix.goos }} - GOARCH: ${{ matrix.goarch }} - - uses: actions/upload-artifact@v7 - with: - name: realmroot-${{ matrix.goos }}-${{ matrix.goarch }} - path: build/realmroot_* - if-no-files-found: error - - verify-build-matrix: - runs-on: ubuntu-latest - needs: build-matrix - steps: - - uses: actions/checkout@v7 - - uses: actions/setup-go@v7 - with: - go-version-file: go.mod - cache: false - - uses: actions/download-artifact@v8 - with: - pattern: realmroot-* - path: build - merge-multiple: true - - run: ./scripts/verify-build-matrix.sh build diff --git a/scripts/verify-build-matrix.sh b/scripts/verify-build-matrix.sh deleted file mode 100755 index 1db302e..0000000 --- a/scripts/verify-build-matrix.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -build_dir="${1:-build}" -targets=( - darwin_amd64 - darwin_arm64 - linux_amd64 - linux_arm64 - windows_amd64 - windows_arm64 -) - -actual_count="$(find "$build_dir" -maxdepth 1 -type f -name 'realmroot_*' | wc -l | tr -d ' ')" -if [[ "$actual_count" != "${#targets[@]}" ]]; then - echo "expected ${#targets[@]} matrix binaries, found $actual_count" >&2 - exit 1 -fi - -for target in "${targets[@]}"; do - os="${target%_*}" - arch="${target#*_}" - suffix='' - if [[ "$os" == windows ]]; then - suffix='.exe' - fi - - binary="$build_dir/realmroot_${target}${suffix}" - if [[ ! -f "$binary" ]]; then - echo "missing matrix binary: $binary" >&2 - exit 1 - fi - - metadata="$(go version -m "$binary")" - grep -Fq $'\tbuild\tGOOS='"$os" <<<"$metadata" - grep -Fq $'\tbuild\tGOARCH='"$arch" <<<"$metadata" - echo "verified realmroot_${target}${suffix}" -done From ae2acd599ba5ba308aa837280568dc0b73484ade Mon Sep 17 00:00:00 2001 From: jarvis Date: Sat, 29 Aug 2026 15:37:12 -0400 Subject: [PATCH 10/10] chore(webi): move installer contribution upstream --- packaging/webi/README.md | 33 ---------- packaging/webi/realmroot/README.md | 58 ----------------- packaging/webi/realmroot/install.ps1 | 86 -------------------------- packaging/webi/realmroot/install.sh | 74 ---------------------- packaging/webi/realmroot/releases.conf | 1 - 5 files changed, 252 deletions(-) delete mode 100644 packaging/webi/README.md delete mode 100644 packaging/webi/realmroot/README.md delete mode 100644 packaging/webi/realmroot/install.ps1 delete mode 100755 packaging/webi/realmroot/install.sh delete mode 100644 packaging/webi/realmroot/releases.conf diff --git a/packaging/webi/README.md b/packaging/webi/README.md deleted file mode 100644 index 466faf7..0000000 --- a/packaging/webi/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# Webi upstream package - -The `realmroot/` directory is the package contribution for -[`webinstall/webi-installers`](https://github.com/webinstall/webi-installers). -Copy it to the upstream repository root and add `realmroot` alphabetically to -the three package lists in `test/install.sh`, as required by upstream's -contribution guide. - -The public `https://webi.sh/realmroot` and `https://webi.ms/realmroot` URLs do -not consume these files from the Realmroot repository. They become available -only after the package is merged upstream and Webi refreshes its deployed -release cache. - -## Upstream Beta validation request - -When submitting these files upstream, ask a Webi maintainer to deploy the PR -candidate to Webi Beta before merge. The deployment is maintainer-controlled; -Realmroot does not publish or operate an alternate Webi origin. - -After the candidate is deployed, smoke-test both release selectors on a clean -macOS or Linux account: - -```console -curl -sS https://beta.webi.sh/realmroot@stable | sh -realmroot version -curl -sS https://beta.webi.sh/realmroot@0.4.2 | sh -realmroot version -``` - -Both installers must select the target-appropriate archive and verify it -against the selected GitHub release's `checksums.txt`. A successful Beta test -does not make the production URLs available; production use still begins only -after upstream merge and deployment. diff --git a/packaging/webi/realmroot/README.md b/packaging/webi/realmroot/README.md deleted file mode 100644 index d04854e..0000000 --- a/packaging/webi/realmroot/README.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: Realmroot Toolbox -homepage: https://realmroot.dev -tagline: | - Realmroot is an Agent-native toolbox for approved access to private resources. ---- - -To update to the latest stable release, run `webi realmroot@stable`. To install -an explicit release, run `webi realmroot@0.4.2` with the required version. - -### Files - -These files are created or modified by this installer: - -```text -~/.config/envman/PATH.env -~/.local/bin/realmroot -~/.local/opt/realmroot-vVERSION/bin/realmroot -``` - -## Cheat Sheet - -> Realmroot gives Agents one stable identity and lets them discover and invoke -> private capabilities with controller-approved authority. - -### Inspect the Agent identity - -```sh -realmroot agent whoami -``` - -### Discover available Resource Servers - -```sh -realmroot toolbox -realmroot toolbox github -``` - -### Request task-scoped authority - -```sh -realmroot agent request \ - --resource-server github \ - --context realmroot \ - --scope contents:read -``` - -### Run an authenticated native command - -```sh -realmroot exec github -- gh repo view realmroot/cli -``` - -### Inspect the installed version - -```sh -realmroot version -``` diff --git a/packaging/webi/realmroot/install.ps1 b/packaging/webi/realmroot/install.ps1 deleted file mode 100644 index e6238f7..0000000 --- a/packaging/webi/realmroot/install.ps1 +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env pwsh - -$pkg_cmd_name = "realmroot" - -$pkg_dst_cmd = "$Env:USERPROFILE\.local\bin\realmroot.exe" -$pkg_dst_bin = "$Env:USERPROFILE\.local\bin" -$pkg_dst = "$pkg_dst_cmd" - -$pkg_src_cmd = "$Env:USERPROFILE\.local\opt\realmroot-v$Env:WEBI_VERSION\bin\realmroot.exe" -$pkg_src_bin = "$Env:USERPROFILE\.local\opt\realmroot-v$Env:WEBI_VERSION\bin" -$pkg_src_dir = "$Env:USERPROFILE\.local\opt\realmroot-v$Env:WEBI_VERSION" -$pkg_src = "$pkg_src_cmd" - -function Get-RealmrootFile { - param( - [string]$Url, - [string]$Path - ) - - if (Test-Path -Path $Path) { - Write-Output "Found $Path" - return - } - - $partialPath = "${Path}.part" - Remove-Item -Path $partialPath -Force -ErrorAction Ignore - & curl.exe -A "$Env:WEBI_UA" -fsSL $Url -o $partialPath - if ($LASTEXITCODE -ne 0) { - Remove-Item -Path $partialPath -Force -ErrorAction Ignore - throw "Failed to download $Url" - } - Move-Item -Path $partialPath -Destination $Path -} - -$pkg_download_dir = "$Env:USERPROFILE\Downloads\webi\realmroot\$Env:WEBI_VERSION" -New-Item $pkg_download_dir -ItemType Directory -Force | Out-Null -$pkg_download = "$pkg_download_dir\$Env:WEBI_PKG_FILE" -$checksums_file = "$pkg_download_dir\checksums.txt" -$checksums_url = "https://github.com/realmroot/cli/releases/download/v$Env:WEBI_VERSION/checksums.txt" - -Get-RealmrootFile -Url $Env:WEBI_PKG_URL -Path $pkg_download -Get-RealmrootFile -Url $checksums_url -Path $checksums_file - -$escaped_filename = [regex]::Escape($Env:WEBI_PKG_FILE) -$checksum_pattern = "^(?[0-9a-fA-F]{64})\s+\*?${escaped_filename}$" -$checksum_matches = @( - Get-Content -Path $checksums_file | ForEach-Object { - if ($_ -match $checksum_pattern) { - $Matches['hash'].ToLowerInvariant() - } - } -) -if ($checksum_matches.Count -ne 1) { - throw "Expected one SHA-256 checksum for $Env:WEBI_PKG_FILE" -} - -$actual_checksum = (Get-FileHash -Path $pkg_download -Algorithm SHA256).Hash.ToLowerInvariant() -if ($actual_checksum -ne $checksum_matches[0]) { - Remove-Item -Path $pkg_download -Force - throw "Checksum mismatch for $Env:WEBI_PKG_FILE" -} -Write-Output "Verified SHA-256 checksum for $Env:WEBI_PKG_FILE" - -if (!(Test-Path -Path $pkg_src_cmd)) { - Write-Output "Installing realmroot" - Push-Location .local\tmp - - Remove-Item -Path ".\realmroot.exe" -Force -ErrorAction Ignore - - Write-Output "Unpacking $pkg_download" - & tar xf $pkg_download - if ($LASTEXITCODE -ne 0) { - throw "Failed to unpack $pkg_download" - } - - Write-Output "Install Location: $pkg_src_cmd" - New-Item $pkg_src_bin -ItemType Directory -Force | Out-Null - Move-Item -Path ".\realmroot.exe" -Destination $pkg_src_cmd - - Pop-Location -} - -Write-Output "Copying into '$pkg_dst_cmd' from '$pkg_src_cmd'" -Remove-Item -Path $pkg_dst_cmd -Force -ErrorAction Ignore -New-Item $pkg_dst_bin -ItemType Directory -Force | Out-Null -Copy-Item -Path $pkg_src -Destination $pkg_dst diff --git a/packaging/webi/realmroot/install.sh b/packaging/webi/realmroot/install.sh deleted file mode 100755 index 8c5f87d..0000000 --- a/packaging/webi/realmroot/install.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/sh - -# shellcheck disable=SC2034 - -__init_realmroot() { - set -e - set -u - - pkg_cmd_name="realmroot" - - pkg_dst_cmd="$HOME/.local/bin/realmroot" - pkg_dst="$pkg_dst_cmd" - - pkg_src_cmd="$HOME/.local/opt/realmroot-v$WEBI_VERSION/bin/realmroot" - pkg_src_dir="$HOME/.local/opt/realmroot-v$WEBI_VERSION" - pkg_src="$pkg_src_cmd" - - pkg_pre_install() { - webi_check_installed - webi_check_available - webi_download \ - "$WEBI_PKG_URL" \ - "$WEBI_PKG_PATH/$WEBI_PKG_FILE" - - my_checksums_url="https://github.com/realmroot/cli/releases/download/v$WEBI_VERSION/checksums.txt" - my_checksums_file="$WEBI_PKG_PATH/checksums.txt" - webi_download "$my_checksums_url" "$my_checksums_file" "realmroot checksums" - - if ! my_expected_checksum="$( - awk -v filename="$WEBI_PKG_FILE" ' - $2 == filename { count++; checksum = $1 } - END { - if (count != 1 || checksum !~ /^[0-9a-fA-F]{64}$/) exit 1 - print tolower(checksum) - } - ' "$my_checksums_file" - )"; then - echo >&2 " Error: expected one SHA-256 checksum for $WEBI_PKG_FILE" - return 1 - fi - - if command -v sha256sum > /dev/null 2>&1; then - my_actual_checksum="$(sha256sum "$WEBI_PKG_PATH/$WEBI_PKG_FILE" | awk '{ print $1 }')" - elif command -v shasum > /dev/null 2>&1; then - my_actual_checksum="$(shasum -a 256 "$WEBI_PKG_PATH/$WEBI_PKG_FILE" | awk '{ print $1 }')" - else - echo >&2 " Error: SHA-256 verification requires sha256sum or shasum" - return 1 - fi - - if test "$my_actual_checksum" != "$my_expected_checksum"; then - rm -f "$WEBI_PKG_PATH/$WEBI_PKG_FILE" - echo >&2 " Error: checksum mismatch for $WEBI_PKG_FILE" - return 1 - fi - - echo " Verified SHA-256 checksum for $WEBI_PKG_FILE" - webi_extract - } - - pkg_install() { - mkdir -p "$(dirname "$pkg_src_cmd")" - mv ./realmroot "$pkg_src_cmd" - } - - pkg_get_current_version() { - realmroot version 2> /dev/null | - head -n 1 | - cut -d ' ' -f 2 | - sed 's:^v::' - } -} - -__init_realmroot diff --git a/packaging/webi/realmroot/releases.conf b/packaging/webi/realmroot/releases.conf deleted file mode 100644 index 6e94b10..0000000 --- a/packaging/webi/realmroot/releases.conf +++ /dev/null @@ -1 +0,0 @@ -github_releases = realmroot/cli