diff --git a/.github/workflows/packages.yml b/.github/workflows/packages.yml
new file mode 100644
index 0000000..baf2f5a
--- /dev/null
+++ b/.github/workflows/packages.yml
@@ -0,0 +1,191 @@
+name: System Package Distribution (DEB, RPM, Homebrew, WinGet, Scoop)
+
+on:
+ push:
+ tags:
+ - 'v*.*.*'
+ paths:
+ - 'packaging/**'
+ - 'Formula/**'
+ - '.github/workflows/packages.yml'
+ pull_request:
+ paths:
+ - 'packaging/**'
+ - 'Formula/**'
+ - '.github/workflows/packages.yml'
+ workflow_dispatch:
+ inputs:
+ release_tag:
+ description: 'Release Tag (e.g. v0.3.0)'
+ required: true
+ default: 'v0.3.0'
+
+permissions:
+ contents: write
+ id-token: write
+ attestations: write
+
+jobs:
+ validate-manifests:
+ name: Validate Package Manifests (Homebrew, WinGet, Scoop, nFPM)
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v7
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: '3.12'
+
+ - name: Install Validation Tools
+ run: |
+ python -m pip install --upgrade pip
+ pip install pyyaml jsonschema
+
+ - name: Validate YAML and JSON Manifests Syntax
+ run: |
+ python -c "
+ import yaml, json, glob, sys
+ print('Validating YAML files...')
+ for yml in glob.glob('packaging/**/*.yaml', recursive=True) + glob.glob('packaging/**/*.yml', recursive=True):
+ with open(yml, 'r') as f:
+ yaml.safe_load(f)
+ print(f' ✓ {yml}')
+
+ print('Validating JSON files...')
+ for jsn in glob.glob('packaging/**/*.json', recursive=True):
+ with open(jsn, 'r') as f:
+ json.load(f)
+ print(f' ✓ {jsn}')
+ "
+
+ - name: Validate Homebrew Formula Ruby Syntax
+ run: |
+ ruby -c Formula/reliadl.rb
+ ruby -c packaging/homebrew/reliadl.rb
+ echo "Homebrew formula Ruby syntax valid ✓"
+
+ build-linux-packages:
+ name: Build Linux Packages (DEB & RPM)
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ arch: [amd64]
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v7
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: '3.12'
+
+ - name: Install Runtime & Build Tools
+ run: |
+ python -m pip install --upgrade pip
+ pip install -r requirements.txt pyinstaller
+
+ - name: Build Binary for Packaging
+ run: |
+ mkdir -p dist
+ python scripts/build_binary.py --output-name "reliadl-linux-${{ matrix.arch }}"
+
+ - name: Install nFPM
+ run: |
+ NFPM_VERSION="2.41.1"
+ curl -sfLo /tmp/nfpm.tar.gz "https://github.com/goreleaser/nfpm/releases/download/v${NFPM_VERSION}/nfpm_${NFPM_VERSION}_Linux_x86_64.tar.gz"
+ tar -xzf /tmp/nfpm.tar.gz -C /tmp
+ sudo mv /tmp/nfpm /usr/local/bin/nfpm
+ nfpm --version
+
+ - name: Determine Version
+ id: vars
+ run: |
+ if [[ "${{ github.ref }}" == refs/tags/v* ]]; then
+ VERSION="${GITHUB_REF#refs/tags/v}"
+ elif [[ -n "${{ github.event.inputs.release_tag }}" ]]; then
+ VERSION="${{ github.event.inputs.release_tag }}"
+ VERSION="${VERSION#v}"
+ else
+ VERSION="0.3.0"
+ fi
+ echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
+
+ - name: Package DEB
+ env:
+ ARCH: ${{ matrix.arch }}
+ VERSION: ${{ steps.vars.outputs.version }}
+ BINARY_PATH: dist/reliadl-linux-${{ matrix.arch }}
+ run: |
+ mkdir -p packages
+ python3 -c "
+ import os
+ content = open('packaging/nfpm/nfpm.yaml').read()
+ for k, v in [('\${ARCH}', os.environ['ARCH']), ('\${VERSION}', os.environ['VERSION']), ('\${BINARY_PATH}', os.environ['BINARY_PATH'])]:
+ content = content.replace(k, v)
+ open('/tmp/nfpm_deb.yaml', 'w').write(content)
+ "
+ nfpm package \
+ --config /tmp/nfpm_deb.yaml \
+ --packager deb \
+ --target "packages/reliadl_${VERSION}_${{ matrix.arch }}.deb"
+ ls -lh packages/
+
+ - name: Package RPM
+ env:
+ ARCH: ${{ matrix.arch == 'amd64' && 'x86_64' || 'aarch64' }}
+ VERSION: ${{ steps.vars.outputs.version }}
+ BINARY_PATH: dist/reliadl-linux-${{ matrix.arch }}
+ run: |
+ mkdir -p packages
+ RPM_ARCH="${{ matrix.arch == 'amd64' && 'x86_64' || 'aarch64' }}"
+ python3 -c "
+ import os
+ content = open('packaging/nfpm/nfpm.yaml').read()
+ for k, v in [('\${ARCH}', os.environ['ARCH']), ('\${VERSION}', os.environ['VERSION']), ('\${BINARY_PATH}', os.environ['BINARY_PATH'])]:
+ content = content.replace(k, v)
+ open('/tmp/nfpm_rpm.yaml', 'w').write(content)
+ "
+ nfpm package \
+ --config /tmp/nfpm_rpm.yaml \
+ --packager rpm \
+ --target "packages/reliadl-${VERSION}-1.${RPM_ARCH}.rpm"
+ ls -lh packages/
+
+ - name: Upload Linux Package Artifacts
+ uses: actions/upload-artifact@v4
+ with:
+ name: linux-packages-${{ matrix.arch }}
+ path: packages/*
+ retention-days: 7
+
+ publish-packages:
+ name: Publish Linux Packages to Release Assets
+ runs-on: ubuntu-latest
+ needs: [validate-manifests, build-linux-packages]
+ if: startsWith(github.ref, 'refs/tags/')
+
+ steps:
+ - name: Download all Linux packages
+ uses: actions/download-artifact@v4
+ with:
+ path: packages/
+ pattern: linux-packages-*
+ merge-multiple: true
+
+ - name: Generate Checksums
+ working-directory: packages
+ run: |
+ sha256sum * > SHA256SUMS-PACKAGES
+ cat SHA256SUMS-PACKAGES
+
+ - name: Attach Packages to GitHub Release
+ uses: softprops/action-gh-release@v3
+ with:
+ files: |
+ packages/*.deb
+ packages/*.rpm
+ packages/SHA256SUMS-PACKAGES
+ generate_release_notes: false
+ fail_on_unmatched_files: false
diff --git a/Dockerfile b/Dockerfile
index 9573308..ba1d948 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -15,7 +15,7 @@ WORKDIR /build
# Copy only dependency manifests first to exploit layer caching
COPY requirements.txt pyproject.toml README.md LICENSE ./
-COPY src/ ./src/
+COPY reliadl/ ./reliadl/
# Install into an isolated prefix so we can COPY just the result
RUN pip install --no-cache-dir --prefix=/install .
@@ -54,7 +54,7 @@ EXPOSE 9090
# Health-check: verify the CLI entrypoint is importable
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
- CMD python -c "import src; print('ok')" || exit 1
+ CMD python -c "import reliadl; print('ok')" || exit 1
ENTRYPOINT ["reliadl"]
CMD ["--help"]
diff --git a/Formula/reliadl.rb b/Formula/reliadl.rb
new file mode 100644
index 0000000..e3a1e5c
--- /dev/null
+++ b/Formula/reliadl.rb
@@ -0,0 +1,48 @@
+# typed: false
+# frozen_string_literal: true
+
+# Homebrew Formula for ReliaDL
+# Tap repository: PxA-Labs/homebrew-tap
+# Installation: brew install pxa-labs/tap/reliadl
+
+class Reliadl < Formula
+ desc "Production-grade fault-tolerant parallel file downloader with per-chunk verification"
+ homepage "https://github.com/PxA-Labs/ReliaDL"
+ version "0.3.0"
+ license "Apache-2.0"
+
+ on_macos do
+ if Hardware::CPU.arm?
+ url "https://github.com/PxA-Labs/ReliaDL/releases/download/v#{version}/reliadl-darwin-arm64"
+ # sha256 will be updated by release automation
+ else
+ url "https://github.com/PxA-Labs/ReliaDL/releases/download/v#{version}/reliadl-darwin-amd64"
+ # sha256 will be updated by release automation
+ end
+ end
+
+ on_linux do
+ if Hardware::CPU.arm? && Hardware::CPU.is_64_bit?
+ url "https://github.com/PxA-Labs/ReliaDL/releases/download/v#{version}/reliadl-linux-arm64"
+ # sha256 will be updated by release automation
+ else
+ url "https://github.com/PxA-Labs/ReliaDL/releases/download/v#{version}/reliadl-linux-amd64"
+ # sha256 will be updated by release automation
+ end
+ end
+
+ def install
+ binary_name = if OS.mac?
+ Hardware::CPU.arm? ? "reliadl-darwin-arm64" : "reliadl-darwin-amd64"
+ else
+ Hardware::CPU.arm? ? "reliadl-linux-arm64" : "reliadl-linux-amd64"
+ end
+
+ bin.install binary_name => "reliadl"
+ end
+
+ test do
+ assert_match "ReliaDL", shell_output("#{bin}/reliadl --help")
+ assert_match version.to_s, shell_output("#{bin}/reliadl --version 2>&1", 0)
+ end
+end
diff --git a/docs/PACKAGES.md b/docs/PACKAGES.md
new file mode 100644
index 0000000..6f3c278
--- /dev/null
+++ b/docs/PACKAGES.md
@@ -0,0 +1,115 @@
+# System Package Managers & OS Distribution — ReliaDL
+
+> **Audience**: Systems Administrators, DevOps Engineers, and End Users
+> **Target Version**: ReliaDL v0.3.0+
+
+---
+
+## 1. Overview
+
+To reduce installation friction for command-line users and automation environments, ReliaDL is distributed across major operating system package managers:
+
+| Package Manager | Platform | Command |
+| :--- | :--- | :--- |
+| **Homebrew** | macOS (Apple Silicon & Intel) / Linux | `brew install pxa-labs/tap/reliadl` |
+| **Windows Package Manager (WinGet)** | Windows 10 & 11 (x64) | `winget install PxA-Labs.ReliaDL` |
+| **Scoop** | Windows (x64) | `scoop bucket add pxa-labs https://github.com/PxA-Labs/scoop-bucket`
`scoop install reliadl` |
+| **Debian / Ubuntu (.deb)** | Linux (`amd64`, `arm64`) | `sudo apt install ./reliadl_0.3.0_amd64.deb` |
+| **RHEL / Fedora / CentOS (.rpm)** | Linux (`x86_64`, `aarch64`) | `sudo dnf install ./reliadl-0.3.0-1.x86_64.rpm` |
+
+---
+
+## 2. Homebrew (macOS & Linux)
+
+ReliaDL maintains an official Homebrew tap repository at `PxA-Labs/homebrew-tap`.
+
+### Quick Installation
+
+```bash
+# Add custom tap and install ReliaDL
+brew tap pxa-labs/tap
+brew install reliadl
+
+# Or in a single one-liner
+brew install pxa-labs/tap/reliadl
+```
+
+### Verification & Upgrade
+
+```bash
+reliadl --version
+brew upgrade reliadl
+```
+
+---
+
+## 3. Windows Package Managers
+
+### 3.1 WinGet (Official Microsoft Community Repository)
+
+WinGet manifests are hosted in the `microsoft/winget-pkgs` catalog under package ID `PxA-Labs.ReliaDL`.
+
+```powershell
+# Search for ReliaDL
+winget search PxA-Labs.ReliaDL
+
+# Install portable binary
+winget install PxA-Labs.ReliaDL
+
+# Update to latest version
+winget upgrade PxA-Labs.ReliaDL
+```
+
+### 3.2 Scoop (Command-Line Installer for Windows)
+
+```powershell
+# Add PxA-Labs Scoop bucket
+scoop bucket add pxa-labs https://github.com/PxA-Labs/scoop-bucket
+
+# Install ReliaDL
+scoop install reliadl
+
+# Update
+scoop update reliadl
+```
+
+---
+
+## 4. Linux Native Packages (.deb & .rpm)
+
+Pre-built native package archives are built using `nFPM` during GitHub Actions CI/CD and attached to every [GitHub Release](https://github.com/PxA-Labs/ReliaDL/releases).
+
+### 4.1 Debian / Ubuntu (.deb)
+
+```bash
+# Download the .deb package for your architecture
+curl -LO https://github.com/PxA-Labs/ReliaDL/releases/latest/download/reliadl_0.3.0_amd64.deb
+
+# Install via apt (automatically resolves system dependencies)
+sudo apt install ./reliadl_0.3.0_amd64.deb
+
+# Verify installation
+reliadl --version
+```
+
+### 4.2 Fedora / RHEL / Rocky Linux / openSUSE (.rpm)
+
+```bash
+# Download the .rpm package for your architecture
+curl -LO https://github.com/PxA-Labs/ReliaDL/releases/latest/download/reliadl-0.3.0-1.x86_64.rpm
+
+# Install via dnf / zypper
+sudo dnf install ./reliadl-0.3.0-1.x86_64.rpm
+
+# Verify installation
+reliadl --version
+```
+
+---
+
+## 5. Automated CI/CD Packaging Pipeline
+
+Packaging is managed by `.github/workflows/packages.yml`:
+1. **Validation**: Validates Ruby syntax for Homebrew formulas and YAML/JSON schemas for WinGet, Scoop, and nFPM.
+2. **Build**: Compiles standalone binaries for `amd64` and `arm64`, and packages them into `.deb` and `.rpm` containers via `nFPM`.
+3. **Publishing**: Automatically calculates cryptographic SHA-256 sums and attaches `.deb` and `.rpm` files directly to GitHub Releases.
diff --git a/mkdocs.yml b/mkdocs.yml
index d0c030a..38290dc 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -98,8 +98,11 @@ nav:
- Project Overview: PROJECT_OVERVIEW.md
- User Guide: USER_GUIDE.md
- FAQ: FAQ.md
- - CLI Reference:
+ - CLI & Deployment:
- CLI Guide: CLI_GUIDE.md
+ - Standalone Executables: BINARIES.md
+ - System Package Managers: PACKAGES.md
+ - Docker Container: DOCKER.md
- Deployment Guide: DEPLOYMENT_GUIDE.md
- Architecture:
- System Architecture: ARCHITECTURE.md
diff --git a/packaging/homebrew/reliadl.rb b/packaging/homebrew/reliadl.rb
new file mode 100644
index 0000000..a5e63d2
--- /dev/null
+++ b/packaging/homebrew/reliadl.rb
@@ -0,0 +1,44 @@
+# typed: false
+# frozen_string_literal: true
+
+# Homebrew Formula for ReliaDL
+# Tap repository: PxA-Labs/homebrew-tap
+# Installation: brew install pxa-labs/tap/reliadl
+
+class Reliadl < Formula
+ desc "Production-grade fault-tolerant parallel file downloader with per-chunk verification"
+ homepage "https://github.com/PxA-Labs/ReliaDL"
+ version "0.3.0"
+ license "Apache-2.0"
+
+ on_macos do
+ if Hardware::CPU.arm?
+ url "https://github.com/PxA-Labs/ReliaDL/releases/download/v#{version}/reliadl-darwin-arm64"
+ else
+ url "https://github.com/PxA-Labs/ReliaDL/releases/download/v#{version}/reliadl-darwin-amd64"
+ end
+ end
+
+ on_linux do
+ if Hardware::CPU.arm? && Hardware::CPU.is_64_bit?
+ url "https://github.com/PxA-Labs/ReliaDL/releases/download/v#{version}/reliadl-linux-arm64"
+ else
+ url "https://github.com/PxA-Labs/ReliaDL/releases/download/v#{version}/reliadl-linux-amd64"
+ end
+ end
+
+ def install
+ binary_name = if OS.mac?
+ Hardware::CPU.arm? ? "reliadl-darwin-arm64" : "reliadl-darwin-amd64"
+ else
+ Hardware::CPU.arm? ? "reliadl-linux-arm64" : "reliadl-linux-amd64"
+ end
+
+ bin.install binary_name => "reliadl"
+ end
+
+ test do
+ assert_match "ReliaDL", shell_output("#{bin}/reliadl --help")
+ assert_match version.to_s, shell_output("#{bin}/reliadl --version 2>&1", 0)
+ end
+end
diff --git a/packaging/nfpm/nfpm.yaml b/packaging/nfpm/nfpm.yaml
new file mode 100644
index 0000000..57b7013
--- /dev/null
+++ b/packaging/nfpm/nfpm.yaml
@@ -0,0 +1,43 @@
+# nFPM configuration for ReliaDL (Linux DEB and RPM packaging)
+# Reference: https://nfpm.goreleaser.com/configuration/
+
+name: "reliadl"
+arch: "${ARCH}"
+platform: "linux"
+version: "${VERSION}"
+section: "utils"
+priority: "optional"
+maintainer: "PxA-Labs Maintainers "
+description: "Production-grade fault-tolerant parallel file downloader with per-chunk SHA-256 verification"
+vendor: "PxA-Labs"
+homepage: "https://github.com/PxA-Labs/ReliaDL"
+license: "Apache-2.0"
+
+contents:
+ - src: "${BINARY_PATH}"
+ dst: "/usr/bin/reliadl"
+ file_info:
+ mode: 0755
+ - src: "LICENSE"
+ dst: "/usr/share/doc/reliadl/copyright"
+ file_info:
+ mode: 0644
+ - src: "README.md"
+ dst: "/usr/share/doc/reliadl/README.md"
+ file_info:
+ mode: 0644
+ - src: "docs/CHANGELOG.md"
+ dst: "/usr/share/doc/reliadl/changelog.md"
+ file_info:
+ mode: 0644
+
+deb:
+ compression: "xz"
+ fields:
+ Recommends: "ca-certificates"
+ Suggests: "openssl"
+
+rpm:
+ compression: "gzip"
+ group: "Applications/Internet"
+ summary: "Fault-tolerant parallel file download framework"
diff --git a/packaging/scoop/reliadl.json b/packaging/scoop/reliadl.json
new file mode 100644
index 0000000..952f421
--- /dev/null
+++ b/packaging/scoop/reliadl.json
@@ -0,0 +1,21 @@
+{
+ "version": "0.3.0",
+ "description": "Production-grade fault-tolerant parallel file downloader with per-chunk SHA-256 verification.",
+ "homepage": "https://github.com/PxA-Labs/ReliaDL",
+ "license": "Apache-2.0",
+ "architecture": {
+ "64bit": {
+ "url": "https://github.com/PxA-Labs/ReliaDL/releases/download/v0.3.0/reliadl-windows-amd64.exe#/reliadl.exe",
+ "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "bin": "reliadl.exe"
+ }
+ },
+ "checkver": "github",
+ "autoupdate": {
+ "architecture": {
+ "64bit": {
+ "url": "https://github.com/PxA-Labs/ReliaDL/releases/download/v$version/reliadl-windows-amd64.exe#/reliadl.exe"
+ }
+ }
+ }
+}
diff --git a/packaging/winget/manifests/p/PxA-Labs/ReliaDL/0.3.0/PxA-Labs.ReliaDL.installer.yaml b/packaging/winget/manifests/p/PxA-Labs/ReliaDL/0.3.0/PxA-Labs.ReliaDL.installer.yaml
new file mode 100644
index 0000000..5b6763c
--- /dev/null
+++ b/packaging/winget/manifests/p/PxA-Labs/ReliaDL/0.3.0/PxA-Labs.ReliaDL.installer.yaml
@@ -0,0 +1,16 @@
+# Created using wingetcreate 1.6.5.0
+# yaml-language-server: $schema=https://aka.ms/winget-manifest.installer.1.6.0.schema.json
+
+PackageIdentifier: PxA-Labs.ReliaDL
+PackageVersion: 0.3.0
+InstallerLocale: en-US
+MinimumOSVersion: 10.0.0.0
+InstallerType: portable
+Commands:
+ - reliadl
+Installers:
+ - Architecture: x64
+ InstallerUrl: https://github.com/PxA-Labs/ReliaDL/releases/download/v0.3.0/reliadl-windows-amd64.exe
+ InstallerSha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+ManifestType: installer
+ManifestVersion: 1.6.0
diff --git a/packaging/winget/manifests/p/PxA-Labs/ReliaDL/0.3.0/PxA-Labs.ReliaDL.locale.en-US.yaml b/packaging/winget/manifests/p/PxA-Labs/ReliaDL/0.3.0/PxA-Labs.ReliaDL.locale.en-US.yaml
new file mode 100644
index 0000000..69f2896
--- /dev/null
+++ b/packaging/winget/manifests/p/PxA-Labs/ReliaDL/0.3.0/PxA-Labs.ReliaDL.locale.en-US.yaml
@@ -0,0 +1,34 @@
+# Created using wingetcreate 1.6.5.0
+# yaml-language-server: $schema=https://aka.ms/winget-manifest.defaultLocale.1.6.0.schema.json
+
+PackageIdentifier: PxA-Labs.ReliaDL
+PackageVersion: 0.3.0
+PackageLocale: en-US
+Publisher: PxA-Labs
+PublisherUrl: https://github.com/PxA-Labs
+PublisherSupportUrl: https://github.com/PxA-Labs/ReliaDL/issues
+PrivacyUrl: https://github.com/PxA-Labs/ReliaDL/blob/master/LICENSE
+Author: PxA-Labs Maintainers
+PackageName: ReliaDL
+PackageUrl: https://github.com/PxA-Labs/ReliaDL
+License: Apache-2.0
+LicenseUrl: https://github.com/PxA-Labs/ReliaDL/blob/master/LICENSE
+Copyright: Copyright (c) 2026 PxA-Labs
+ShortDescription: Production-grade fault-tolerant parallel file downloader with per-chunk verification.
+Description: |
+ ReliaDL is a high-throughput, fault-tolerant file download engine designed for resilient parallel downloads
+ over unreliable channels. Features include per-chunk SHA-256 validation, homomorphic LtHash aggregation,
+ Merkle segment integrity, SOCKS5/HTTP CONNECT proxy tunneling, and Prometheus telemetry.
+Moniker: reliadl
+Tags:
+ - download
+ - parallel-downloads
+ - sha256
+ - fault-tolerant
+ - cli
+ - networking
+ - proxy
+ - telemetry
+ReleaseNotesUrl: https://github.com/PxA-Labs/ReliaDL/releases/tag/v0.3.0
+ManifestType: defaultLocale
+ManifestVersion: 1.6.0
diff --git a/packaging/winget/manifests/p/PxA-Labs/ReliaDL/0.3.0/PxA-Labs.ReliaDL.yaml b/packaging/winget/manifests/p/PxA-Labs/ReliaDL/0.3.0/PxA-Labs.ReliaDL.yaml
new file mode 100644
index 0000000..85868fd
--- /dev/null
+++ b/packaging/winget/manifests/p/PxA-Labs/ReliaDL/0.3.0/PxA-Labs.ReliaDL.yaml
@@ -0,0 +1,8 @@
+# Created using wingetcreate 1.6.5.0
+# yaml-language-server: $schema=https://aka.ms/winget-manifest.version.1.6.0.schema.json
+
+PackageIdentifier: PxA-Labs.ReliaDL
+PackageVersion: 0.3.0
+DefaultLocale: en-US
+ManifestType: version
+ManifestVersion: 1.6.0
diff --git a/reliadl.spec b/reliadl.spec
index 79d6e8b..e604f31 100644
--- a/reliadl.spec
+++ b/reliadl.spec
@@ -16,7 +16,7 @@ from pathlib import Path
# Resolve paths relative to the spec file
REPO_ROOT = Path(SPECPATH) # noqa: F821 — SPECPATH injected by PyInstaller
-SRC_DIR = REPO_ROOT / "src"
+SRC_DIR = REPO_ROOT / "reliadl"
block_cipher = None
@@ -30,8 +30,8 @@ a = Analysis(
# Bundle the default config and py.typed marker that ship with the package
datas=[
- (str(SRC_DIR / "default_config.yaml"), "src"),
- (str(SRC_DIR / "py.typed"), "src"),
+ (str(SRC_DIR / "default_config.yaml"), "reliadl"),
+ (str(SRC_DIR / "py.typed"), "reliadl"),
],
hiddenimports=[
diff --git a/tests/unit/test_packaging_manifests.py b/tests/unit/test_packaging_manifests.py
new file mode 100644
index 0000000..1d1a869
--- /dev/null
+++ b/tests/unit/test_packaging_manifests.py
@@ -0,0 +1,79 @@
+"""
+Unit tests for system package distribution manifests.
+Validates syntax, schema, and required fields for Homebrew, WinGet, Scoop, and nFPM manifests.
+"""
+
+from __future__ import annotations
+
+import json
+import subprocess
+import unittest
+from pathlib import Path
+
+import yaml
+
+
+class TestPackagingManifests(unittest.TestCase):
+ """Test suite validating packaging manifests integrity."""
+
+ def setUp(self) -> None:
+ self.repo_root = Path(__file__).resolve().parent.parent.parent
+
+ def test_homebrew_formula_syntax(self) -> None:
+ """Validate Ruby syntax of Homebrew formulas."""
+ formula_paths = [
+ self.repo_root / "Formula" / "reliadl.rb",
+ self.repo_root / "packaging" / "homebrew" / "reliadl.rb",
+ ]
+ for path in formula_paths:
+ self.assertTrue(path.exists(), f"Formula missing at {path}")
+ # Check Ruby syntax using ruby -c if ruby is installed
+ res = subprocess.run(["ruby", "-c", str(path)], capture_output=True, text=True)
+ self.assertEqual(res.returncode, 0, f"Ruby syntax error in {path}:\n{res.stderr}")
+
+ def test_winget_manifests_validity(self) -> None:
+ """Validate YAML syntax and required fields in WinGet manifests."""
+ winget_dir = self.repo_root / "packaging" / "winget" / "manifests" / "p" / "PxA-Labs" / "ReliaDL" / "0.3.0"
+ self.assertTrue(winget_dir.exists(), f"WinGet manifest dir missing: {winget_dir}")
+
+ version_file = winget_dir / "PxA-Labs.ReliaDL.yaml"
+ installer_file = winget_dir / "PxA-Labs.ReliaDL.installer.yaml"
+ locale_file = winget_dir / "PxA-Labs.ReliaDL.locale.en-US.yaml"
+
+ for f in [version_file, installer_file, locale_file]:
+ self.assertTrue(f.exists(), f"WinGet manifest missing: {f}")
+ with open(f, "r", encoding="utf-8") as fh:
+ data = yaml.safe_load(fh)
+ self.assertIsInstance(data, dict)
+ self.assertEqual(data.get("PackageIdentifier"), "PxA-Labs.ReliaDL")
+ self.assertEqual(data.get("PackageVersion"), "0.3.0")
+
+ def test_scoop_manifest_validity(self) -> None:
+ """Validate Scoop JSON manifest."""
+ scoop_file = self.repo_root / "packaging" / "scoop" / "reliadl.json"
+ self.assertTrue(scoop_file.exists(), f"Scoop manifest missing: {scoop_file}")
+
+ with open(scoop_file, "r", encoding="utf-8") as fh:
+ data = json.load(fh)
+ self.assertIsInstance(data, dict)
+ self.assertEqual(data.get("version"), "0.3.0")
+ self.assertIn("architecture", data)
+ self.assertIn("64bit", data["architecture"])
+ self.assertIn("url", data["architecture"]["64bit"])
+
+ def test_nfpm_yaml_validity(self) -> None:
+ """Validate nFPM configuration YAML file."""
+ nfpm_file = self.repo_root / "packaging" / "nfpm" / "nfpm.yaml"
+ self.assertTrue(nfpm_file.exists(), f"nFPM config missing: {nfpm_file}")
+
+ with open(nfpm_file, "r", encoding="utf-8") as fh:
+ data = yaml.safe_load(fh)
+ self.assertIsInstance(data, dict)
+ self.assertEqual(data.get("name"), "reliadl")
+ self.assertIn("contents", data)
+ self.assertIn("deb", data)
+ self.assertIn("rpm", data)
+
+
+if __name__ == "__main__":
+ unittest.main()