feat: add Chocolatey package and Linux/macOS install script with automated publishing

This commit is contained in:
HueByte
2026-02-24 19:44:46 +01:00
parent 38df05df41
commit 045515369c
9 changed files with 339 additions and 10 deletions
+19
View File
@@ -157,3 +157,22 @@ jobs:
EchoHub-Client-linux-arm64.zip
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Publish Chocolatey package
if: steps.changes.outputs.src_changed == 'true' && steps.check_release.outputs.exists == 'false'
run: |
VERSION="${{ steps.version.outputs.version }}"
CHECKSUM=$(sha256sum EchoHub-Client-win-x64.zip | awk '{print $1}')
# Stamp version and checksum into package templates
sed -i "s/__VERSION__/$VERSION/g" packaging/choco/echohub.nuspec
sed -i "s/__VERSION__/$VERSION/g" packaging/choco/tools/chocolateyInstall.ps1
sed -i "s/__CHECKSUM64__/$CHECKSUM/g" packaging/choco/tools/chocolateyInstall.ps1
# Build and push the package
mkdir -p /tmp/choco-out
cd packaging/choco
choco pack echohub.nuspec --output-directory /tmp/choco-out
choco push /tmp/choco-out/echohub.*.nupkg --source https://push.chocolatey.org/ --api-key "$CHOCO_API_KEY"
env:
CHOCO_API_KEY: ${{ secrets.CHOCOLATEY_API_KEY }}
+30 -10
View File
@@ -1,12 +1,33 @@
# Getting Started
## Prerequisites
## Install the Client
- [.NET 10 SDK](https://dotnet.microsoft.com/download)
### Windows (Chocolatey)
Or grab a self-contained binary from [Releases](https://github.com/HueByte/EchoHub/releases) -- no runtime needed.
```bash
choco install echohub
```
## Docker
### Linux / macOS
```bash
curl -sSfL https://raw.githubusercontent.com/HueByte/EchoHub/master/scripts/install.sh | sh
```
To install a specific version or to a custom directory:
```bash
curl -sSfL .../install.sh | sh -s -- --version 0.2.8
curl -sSfL .../install.sh | sh -s -- --install-dir /opt/echohub
```
### Manual Download
Grab a self-contained binary from [Releases](https://github.com/HueByte/EchoHub/releases) -- no runtime needed.
## Host a Server
### Docker
The quickest way to host a server:
@@ -17,24 +38,23 @@ docker compose up -d
See the [Docker guide](docker.md) for configuration, pre-built images, and more.
## Run the Server
### From Source
```bash
dotnet run --project src/EchoHub.Server
```
Requires [.NET 10 SDK](https://dotnet.microsoft.com/download).
On first run, the server automatically:
1. Creates `appsettings.json` from the example config
2. Generates a secure JWT secret
3. Creates the SQLite database with a `#general` channel
## Run the Client
```bash
dotnet run --project src/EchoHub.Client
```
## Usage
After installing the client, run `echohub` (or `dotnet run --project src/EchoHub.Client` from source).
Connect to a server, register an account, and start chatting.
## Connect via IRC
+6
View File
@@ -21,7 +21,13 @@
- Extract `IUserService`/`UserService` — consolidate user registration, authentication, and profile management into a dedicated service, eliminating duplicated logic between `AuthController` and `ChatService`
- IRC gateway now checks ban status during authentication (previously skipped)
## Distribution
- Add Chocolatey package — `choco install echohub` for Windows users, auto-published from CI on each release
- Add Linux/macOS install script — `curl -sSfL .../install.sh | sh` with automatic OS/arch detection
## CI
- Add Docker workflow — builds and pushes multi-arch (`amd64`/`arm64`) server image to GHCR on release
- Add `linux-arm64` builds to release pipeline — server and client binaries for ARM Linux (Raspberry Pi, cloud ARM instances)
- Automate Chocolatey package publishing in release workflow (checksum calculation, pack, push)
+26
View File
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
<metadata>
<id>echohub</id>
<version>__VERSION__</version>
<title>EchoHub</title>
<authors>Hue</authors>
<owners>Hue</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<licenseUrl>https://github.com/HueByte/EchoHub/blob/master/LICENSE</licenseUrl>
<projectUrl>https://github.com/HueByte/EchoHub</projectUrl>
<projectSourceUrl>https://github.com/HueByte/EchoHub</projectSourceUrl>
<docsUrl>https://huebyte.github.io/EchoHub</docsUrl>
<bugTrackerUrl>https://github.com/HueByte/EchoHub/issues</bugTrackerUrl>
<packageSourceUrl>https://github.com/HueByte/EchoHub/tree/master/packaging/choco</packageSourceUrl>
<iconUrl>https://raw.githubusercontent.com/HueByte/EchoHub/master/assets/hue_icon.png</iconUrl>
<description>EchoHub is a decentralized IRC-style chat application with a terminal user interface (TUI). Connect to any EchoHub server, join channels, and chat — all from your terminal. Features include SignalR real-time messaging, file sharing, custom themes, and IRC gateway compatibility.</description>
<summary>Decentralized terminal chat client with IRC gateway support</summary>
<tags>chat irc decentralized tui terminal signalr echohub</tags>
<releaseNotes>https://huebyte.github.io/EchoHub/changelog/v__VERSION__.html</releaseNotes>
<copyright>Copyright (c) 2026 Hue</copyright>
</metadata>
<files>
<file src="tools\**" target="tools" />
</files>
</package>
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Hue
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+17
View File
@@ -0,0 +1,17 @@
VERIFICATION
To verify the package contents:
1. Download the official release from:
https://github.com/HueByte/EchoHub/releases
2. Download: EchoHub-Client-win-x64.zip
3. Calculate the SHA256 checksum:
- PowerShell: Get-FileHash EchoHub-Client-win-x64.zip -Algorithm SHA256
- Linux/macOS: sha256sum EchoHub-Client-win-x64.zip
4. Compare with the checksum in chocolateyInstall.ps1 (checksum64 value).
LICENSE: MIT License - see LICENSE.txt in this directory or
https://github.com/HueByte/EchoHub/blob/master/LICENSE
@@ -0,0 +1,18 @@
$ErrorActionPreference = 'Stop'
$toolsDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
$version = $env:chocolateyPackageVersion
$packageArgs = @{
packageName = $env:chocolateyPackageName
unzipLocation = $toolsDir
url64bit = "https://github.com/HueByte/EchoHub/releases/download/v$version/EchoHub-Client-win-x64.zip"
checksum64 = '__CHECKSUM64__'
checksumType64 = 'sha256'
}
Install-ChocolateyZipPackage @packageArgs
# Create a shim so 'echohub' is available on PATH
$exePath = Join-Path $toolsDir 'client-win-x64' 'EchoHub.Client.exe'
Install-BinFile -Name 'echohub' -Path $exePath
@@ -0,0 +1,3 @@
$ErrorActionPreference = 'Stop'
Uninstall-BinFile -Name 'echohub'
+199
View File
@@ -0,0 +1,199 @@
#!/bin/sh
# EchoHub Client Installer
# Usage: curl -sSfL https://raw.githubusercontent.com/HueByte/EchoHub/master/scripts/install.sh | sh
#
# Options (pass as arguments or environment variables):
# --version X.Y.Z Install a specific version (default: latest)
# --install-dir DIR Install to a custom directory
# --help Show this help message
set -eu
REPO="HueByte/EchoHub"
BINARY_NAME="echohub"
INSTALL_DIR=""
VERSION=""
# ── Argument parsing ──────────────────────────────────────────────────────
while [ $# -gt 0 ]; do
case "$1" in
--version)
VERSION="$2"
shift 2
;;
--install-dir)
INSTALL_DIR="$2"
shift 2
;;
--help)
sed -n '2,8p' "$0" 2>/dev/null || true
echo ""
echo " curl -sSfL https://raw.githubusercontent.com/$REPO/master/scripts/install.sh | sh"
echo " curl ... | sh -s -- --version 0.2.8"
echo " curl ... | sh -s -- --install-dir /opt/echohub"
exit 0
;;
*)
echo "Unknown option: $1" >&2
exit 1
;;
esac
done
# ── Platform detection ────────────────────────────────────────────────────
detect_os() {
case "$(uname -s)" in
Linux*) echo "linux" ;;
Darwin*) echo "osx" ;;
*)
echo "Error: Unsupported operating system: $(uname -s)" >&2
echo "EchoHub supports Linux and macOS. For Windows, use: choco install echohub" >&2
exit 1
;;
esac
}
detect_arch() {
case "$(uname -m)" in
x86_64|amd64) echo "x64" ;;
aarch64|arm64) echo "arm64" ;;
*)
echo "Error: Unsupported architecture: $(uname -m)" >&2
echo "EchoHub supports x64 and arm64." >&2
exit 1
;;
esac
}
# ── Version resolution ────────────────────────────────────────────────────
resolve_version() {
if [ -n "$VERSION" ]; then
echo "$VERSION"
return
fi
# Fetch latest release tag from GitHub API
if command -v curl >/dev/null 2>&1; then
tag=$(curl -sSf "https://api.github.com/repos/$REPO/releases/latest" \
| grep '"tag_name"' | head -1 | sed 's/.*"tag_name"[[:space:]]*:[[:space:]]*"v\?\([^"]*\)".*/\1/')
elif command -v wget >/dev/null 2>&1; then
tag=$(wget -qO- "https://api.github.com/repos/$REPO/releases/latest" \
| grep '"tag_name"' | head -1 | sed 's/.*"tag_name"[[:space:]]*:[[:space:]]*"v\?\([^"]*\)".*/\1/')
else
echo "Error: curl or wget is required to detect the latest version." >&2
echo "Install curl/wget or specify a version with --version X.Y.Z" >&2
exit 1
fi
if [ -z "$tag" ]; then
echo "Error: Could not determine latest version from GitHub." >&2
exit 1
fi
echo "$tag"
}
# ── Install directory resolution ──────────────────────────────────────────
resolve_install_dir() {
if [ -n "$INSTALL_DIR" ]; then
echo "$INSTALL_DIR"
return
fi
# Prefer /usr/local/bin if writable, otherwise ~/.local/bin
if [ -w "/usr/local/bin" ]; then
echo "/usr/local/bin"
else
local_bin="$HOME/.local/bin"
mkdir -p "$local_bin"
echo "$local_bin"
fi
}
# ── Download helper ───────────────────────────────────────────────────────
download() {
url="$1"
output="$2"
if command -v curl >/dev/null 2>&1; then
curl -sSfL "$url" -o "$output"
elif command -v wget >/dev/null 2>&1; then
wget -qO "$output" "$url"
else
echo "Error: curl or wget is required." >&2
exit 1
fi
}
# ── Main ──────────────────────────────────────────────────────────────────
main() {
os=$(detect_os)
arch=$(detect_arch)
version=$(resolve_version)
install_dir=$(resolve_install_dir)
artifact="EchoHub-Client-${os}-${arch}.zip"
url="https://github.com/$REPO/releases/download/v${version}/${artifact}"
echo "EchoHub Installer"
echo " Version: v${version}"
echo " Platform: ${os}-${arch}"
echo " Install to: ${install_dir}"
echo ""
# Create temp directory with cleanup trap
tmpdir=$(mktemp -d)
trap 'rm -rf "$tmpdir"' EXIT
echo "Downloading ${artifact}..."
download "$url" "$tmpdir/echohub.zip"
echo "Extracting..."
if command -v unzip >/dev/null 2>&1; then
unzip -qo "$tmpdir/echohub.zip" -d "$tmpdir/extract"
else
echo "Error: unzip is required to extract the archive." >&2
echo "Install it with: apt install unzip / brew install unzip" >&2
exit 1
fi
# The ZIP contains a client-{os}-{arch}/ subdirectory
src_dir="$tmpdir/extract/client-${os}-${arch}"
if [ ! -d "$src_dir" ]; then
# Fallback: look for any directory containing the binary
src_dir=$(find "$tmpdir/extract" -name "EchoHub.Client" -type f -printf '%h' -quit 2>/dev/null || true)
if [ -z "$src_dir" ]; then
echo "Error: Could not find EchoHub.Client binary in the archive." >&2
exit 1
fi
fi
# Install the binary
mkdir -p "$install_dir"
cp "$src_dir/EchoHub.Client" "$install_dir/$BINARY_NAME"
chmod +x "$install_dir/$BINARY_NAME"
echo ""
# Verify
if command -v "$BINARY_NAME" >/dev/null 2>&1; then
echo "Installed successfully! Run 'echohub' to start."
else
echo "Installed to: ${install_dir}/${BINARY_NAME}"
echo ""
echo "WARNING: ${install_dir} is not in your PATH."
echo "Add it to your shell profile:"
echo ""
echo " echo 'export PATH=\"${install_dir}:\$PATH\"' >> ~/.bashrc"
echo " # or for zsh:"
echo " echo 'export PATH=\"${install_dir}:\$PATH\"' >> ~/.zshrc"
fi
}
main