Skip to content

Build and Release

Build and Release #29

Workflow file for this run

name: Build and Release
on:
release:
types: [published]
workflow_dispatch:
inputs:
platform:
description: "Platform to build (all, ubuntu-20.04, ubuntu-latest, windows, macos)"
required: true
default: "all"
type: choice
options:
- all
- ubuntu-20.04
- ubuntu-latest
- windows
- macos
permissions:
contents: write
jobs:
build:
name: Build on ${{ matrix.name }}
runs-on: ${{ matrix.os }}
container: ${{ matrix.container }}
strategy:
fail-fast: false
matrix:
include:
# Build in Ubuntu 20.04 container for GLIBC 2.31 compatibility with older Linux distributions
- name: Ubuntu 20.04 (GLIBC 2.31)
os: ubuntu-latest
container: ubuntu:20.04
platform: ubuntu-20.04
artifact_name: rx-linux-x86_64-ubuntu20.04
binary_path: dist/rx
# Native Ubuntu latest (24.04+) build with GLIBC 2.38+ for the newest systems
- name: Ubuntu Latest (GLIBC 2.38+)
os: ubuntu-latest
container: null
platform: ubuntu-latest
artifact_name: rx-linux-x86_64-ubuntu-latest
binary_path: dist/rx
- name: Windows
os: windows-latest
container: null
platform: windows
artifact_name: rx-windows-x86_64.exe
binary_path: dist/rx.exe
- name: macOS
os: macos-latest
container: null
platform: macos
artifact_name: rx-macos-x86_64
binary_path: dist/rx
steps:
- name: Check if build should run
id: should_build
run: |
if [ "${{ github.event_name }}" = "release" ]; then
echo "should_run=true" >> $GITHUB_OUTPUT
elif [ "${{ github.event.inputs.platform }}" = "all" ]; then
echo "should_run=true" >> $GITHUB_OUTPUT
elif [ "${{ github.event.inputs.platform }}" = "${{ matrix.platform }}" ]; then
echo "should_run=true" >> $GITHUB_OUTPUT
else
echo "should_run=false" >> $GITHUB_OUTPUT
fi
shell: bash
# Install basic tools in Ubuntu 20.04 container
- name: Install container dependencies
if: steps.should_build.outputs.should_run == 'true' && matrix.container == 'ubuntu:20.04'
run: |
export DEBIAN_FRONTEND=noninteractive
export TZ=Etc/UTC
apt-get update
apt-get install -y curl git build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget llvm \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev \
libffi-dev liblzma-dev ca-certificates zstd unzip
env:
DEBIAN_FRONTEND: noninteractive
TZ: Etc/UTC
- name: Checkout code
if: steps.should_build.outputs.should_run == 'true'
uses: actions/checkout@v4
- name: Set up Python
if: steps.should_build.outputs.should_run == 'true' && matrix.container == null
uses: actions/setup-python@v5
with:
python-version: "3.13"
# Install uv manually in container
- name: Install uv in container
if: steps.should_build.outputs.should_run == 'true' && matrix.container == 'ubuntu:20.04'
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
env:
CARGO_HOME: /root/.cargo
- name: Install uv
if: steps.should_build.outputs.should_run == 'true' && matrix.container == null
uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- name: Install Bun in container
if: steps.should_build.outputs.should_run == 'true' && matrix.container == 'ubuntu:20.04'
run: |
curl -fsSL https://bun.sh/install | bash
env:
BUN_INSTALL: /root/.bun
- name: Install Bun
if: steps.should_build.outputs.should_run == 'true' && matrix.container == null
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Build frontend in container
if: steps.should_build.outputs.should_run == 'true' && matrix.container == 'ubuntu:20.04'
run: |
cd src/rx/frontend
/root/.bun/bin/bun install
/root/.bun/bin/bun run build
- name: Build frontend
if: steps.should_build.outputs.should_run == 'true' && matrix.container == null
run: |
cd src/rx/frontend
bun install
bun run build
- name: Install dependencies in container
if: steps.should_build.outputs.should_run == 'true' && matrix.container == 'ubuntu:20.04'
run: |
export PATH="$HOME/.cargo/bin:$PATH"
uv python install 3.13
uv sync --group dev --group build
- name: Install dependencies
if: steps.should_build.outputs.should_run == 'true' && matrix.container == null
run: |
uv sync --group dev --group build
# Install ripgrep in container
- name: Install ripgrep in container
if: steps.should_build.outputs.should_run == 'true' && matrix.container == 'ubuntu:20.04'
run: |
apt-get install -y ripgrep
env:
DEBIAN_FRONTEND: noninteractive
- name: Install ripgrep (Ubuntu)
if: steps.should_build.outputs.should_run == 'true' && matrix.container == null && matrix.os == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y ripgrep
- name: Install ripgrep (macOS)
if: steps.should_build.outputs.should_run == 'true' && matrix.os == 'macos-latest'
run: |
brew install ripgrep
- name: Install ripgrep (Windows)
if: steps.should_build.outputs.should_run == 'true' && matrix.os == 'windows-latest'
run: |
choco install ripgrep -y
- name: Run tests in container
if: steps.should_build.outputs.should_run == 'true' && matrix.container == 'ubuntu:20.04'
run: |
export PATH="$HOME/.cargo/bin:$PATH"
uv run pytest
- name: Run tests (Unix)
if: steps.should_build.outputs.should_run == 'true' && matrix.container == null && matrix.os != 'windows-latest'
run: |
uv run pytest
- name: Run tests (Windows - skip problematic tests)
if: steps.should_build.outputs.should_run == 'true' && matrix.os == 'windows-latest'
run: |
uv run pytest --ignore=tests/test_endpoints.py --ignore=tests/test_analyse.py --ignore=tests/test_analyse_cache.py --ignore=tests/test_analyse_compressed.py --ignore=tests/test_compressed_index.py --ignore=tests/test_index.py --ignore=tests/test_parse.py --ignore=tests/test_seekable_zstd.py --ignore=tests/test_tree_endpoint.py
- name: Build with PyInstaller in container
if: steps.should_build.outputs.should_run == 'true' && matrix.container == 'ubuntu:20.04'
run: |
export PATH="$HOME/.cargo/bin:$PATH"
uv run pyinstaller rx.spec
- name: Build with PyInstaller
if: steps.should_build.outputs.should_run == 'true' && matrix.container == null
run: |
uv run pyinstaller rx.spec
- name: Verify binary exists
if: steps.should_build.outputs.should_run == 'true'
shell: bash
run: |
ls -lh dist/
if [ ! -f "${{ matrix.binary_path }}" ]; then
echo "Binary not found at ${{ matrix.binary_path }}"
exit 1
fi
- name: Test binary (Unix)
if: steps.should_build.outputs.should_run == 'true' && matrix.os != 'windows-latest'
run: |
chmod +x ${{ matrix.binary_path }}
${{ matrix.binary_path }} --version
- name: Test binary (Windows)
if: steps.should_build.outputs.should_run == 'true' && matrix.os == 'windows-latest'
run: |
${{ matrix.binary_path }} --version
- name: Upload artifact
if: steps.should_build.outputs.should_run == 'true'
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact_name }}
path: ${{ matrix.binary_path }}
if-no-files-found: error
- name: Upload to release (on release event)
if: steps.should_build.outputs.should_run == 'true' && github.event_name == 'release'
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ${{ matrix.binary_path }}
asset_name: ${{ matrix.artifact_name }}
asset_content_type: application/octet-stream
create-checksums:
name: Create checksums
needs: build
runs-on: ubuntu-latest
if: github.event_name == 'release'
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Create checksums
run: |
cd artifacts
find . -type f -exec sha256sum {} \; > ../checksums.txt
cat ../checksums.txt
- name: Upload checksums to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: checksums.txt
asset_name: checksums.txt
asset_content_type: text/plain