diff --git a/.forgejo/workflows/rpm-build.yml b/.forgejo/workflows/rpm-build.yml new file mode 100644 index 00000000..2fa5965d --- /dev/null +++ b/.forgejo/workflows/rpm-build.yml @@ -0,0 +1,329 @@ +name: Build RPM Package +concurrency: + group: "rpm-build-${{ github.ref }}" + cancel-in-progress: true + +on: + push: + paths: + - 'fedora/**' + - 'src/**' + - 'Cargo.toml' + - 'Cargo.lock' + - '.forgejo/workflows/rpm-build.yml' + pull_request: + paths: + - 'fedora/**' + - 'src/**' + - 'Cargo.toml' + - 'Cargo.lock' + - '.forgejo/workflows/rpm-build.yml' + workflow_dispatch: + +jobs: + rpm-build: + name: Build RPM Package + runs-on: fedora-latest + + steps: + - name: Detect Fedora version + id: fedora + run: | + VERSION=$(rpm -E %fedora) + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "Fedora version: $VERSION" + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # rpkg needs full history for git macros + + - name: Cache DNF packages + uses: actions/cache@v4 + with: + path: | + /var/cache/dnf + /var/cache/yum + key: dnf-fedora${{ steps.fedora.outputs.version }}-${{ hashFiles('fedora/continuwuity.spec.rpkg') }}-v1 + restore-keys: | + dnf-fedora${{ steps.fedora.outputs.version }}- + + - name: Install build dependencies + run: | + dnf install -y --setopt=keepcache=1 \ + wget \ + rpm-build \ + rpmdevtools \ + rpkg \ + cargo-rpm-macros \ + systemd-rpm-macros \ + clang \ + liburing-devel \ + rust \ + cargo \ + gcc \ + gcc-c++ \ + make \ + openssl-devel \ + pkg-config \ + python3-pip + + - name: Cache Cargo registry + uses: actions/cache@v4 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: cargo-fedora${{ steps.fedora.outputs.version }}-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + cargo-fedora${{ steps.fedora.outputs.version }}- + + - name: Setup sccache + uses: https://github.com/mozilla-actions/sccache-action@v0.0.9 + with: + token: ${{ secrets.GH_PUBLIC_RO }} + + - name: Configure sccache environment + run: | + echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV + echo "CMAKE_C_COMPILER_LAUNCHER=sccache" >> $GITHUB_ENV + echo "CMAKE_CXX_COMPILER_LAUNCHER=sccache" >> $GITHUB_ENV + + # Set sccache cache size limit + echo "SCCACHE_CACHE_SIZE=2G" >> $GITHUB_ENV + + - name: Setup build environment and build SRPM + run: | + # Configure git for rpkg + git config --global --add safe.directory "$GITHUB_WORKSPACE" + git config --global user.email "ci@continuwuity.org" + git config --global user.name "Continuwuity" + + # Setup RPM build tree + rpmdev-setuptree + + echo "::group::📦 Building source RPM with rpkg" + cd "$GITHUB_WORKSPACE" + + # Determine release suffix based on ref type and branch + if [[ "${{ github.ref }}" == "refs/tags/"* ]]; then + # Tags get clean version numbers for stable releases + RELEASE_SUFFIX="" + elif [ "${{ github.ref_name }}" = "main" ]; then + # Main branch gets .dev suffix + RELEASE_SUFFIX=".dev" + else + # Other branches get sanitized branch name as suffix + SAFE_BRANCH=$(echo "${{ github.ref_name }}" | sed 's/[^a-zA-Z0-9]/_/g' | cut -c1-20) + RELEASE_SUFFIX=".${SAFE_BRANCH}" + fi + + # Create a temporary spec file with the release suffix + if [ -n "$RELEASE_SUFFIX" ]; then + # Replace the Release line to include our suffix + sed "s/^Release:.*$/Release: 1${RELEASE_SUFFIX}%{?dist}/" \ + fedora/continuwuity.spec.rpkg > continuwuity.spec.rpkg + else + # Use the original spec file + ln -sf fedora/continuwuity.spec.rpkg continuwuity.spec.rpkg + fi + + # Build the SRPM + rpkg srpm --outdir "$HOME/rpmbuild/SRPMS" + + # List generated SRPM + echo "Generated SRPM:" + ls -la "$HOME/rpmbuild/SRPMS/" + echo "::endgroup::" + + - name: Build RPM from SRPM + run: | + # Find the SRPM file + SRPM=$(find "$HOME/rpmbuild/SRPMS" -name "*.src.rpm" | head -1) + + if [ -z "$SRPM" ]; then + echo "Error: No SRPM file found" + exit 1 + fi + + echo "Building from SRPM: $SRPM" + + # Build the binary RPM + # Note: Using rpmbuild directly since mock would need additional setup + rpmbuild --rebuild "$SRPM" \ + --define "_topdir $HOME/rpmbuild" \ + --define "_sourcedir $GITHUB_WORKSPACE" \ + --nocheck # Skip %check section to avoid test dependencies + + - name: List built packages + run: | + echo "Binary RPMs:" + find "$HOME/rpmbuild/RPMS" -name "*.rpm" -type f -exec ls -la {} \; + + echo "" + echo "Source RPMs:" + find "$HOME/rpmbuild/SRPMS" -name "*.rpm" -type f -exec ls -la {} \; + + - name: Test RPM installation + run: | + # Find the binary RPM + RPM=$(find "$HOME/rpmbuild/RPMS" -name "continuwuity-*.rpm" ! -name "*.src.rpm" | head -1) + + if [ -z "$RPM" ]; then + echo "Error: No binary RPM file found" + exit 1 + fi + + echo "Testing installation of: $RPM" + + # Dry run first + rpm -qpi "$RPM" + echo "" + rpm -qpl "$RPM" + + # Actually install it (would need --nodeps if dependencies aren't met) + dnf install -y "$RPM" || rpm -ivh --nodeps "$RPM" + + # Verify installation + rpm -qa | grep continuwuity + + # Check that the binary exists + [ -f /usr/bin/conduwuit ] && echo "✅ Binary installed successfully" + [ -f /usr/lib/systemd/system/conduwuit.service ] && echo "✅ Systemd service installed" + [ -f /etc/conduwuit/conduwuit.toml ] && echo "✅ Config file installed" + + - name: Collect artifacts + if: success() + run: | + mkdir -p artifacts + + # Copy all RPMs to artifacts directory + find "$HOME/rpmbuild/RPMS" -name "*.rpm" -type f -exec cp {} artifacts/ \; + find "$HOME/rpmbuild/SRPMS" -name "*.rpm" -type f -exec cp {} artifacts/ \; + + # Create metadata file + cd artifacts + echo "Build Information:" > BUILD_INFO.txt + echo "==================" >> BUILD_INFO.txt + echo "Git commit: ${{ github.sha }}" >> BUILD_INFO.txt + echo "Git branch: ${{ github.ref_name }}" >> BUILD_INFO.txt + echo "Build date: $(date -u +%Y-%m-%d_%H:%M:%S_UTC)" >> BUILD_INFO.txt + echo "" >> BUILD_INFO.txt + echo "Package contents:" >> BUILD_INFO.txt + echo "-----------------" >> BUILD_INFO.txt + for rpm in *.rpm; do + echo "" >> BUILD_INFO.txt + echo "File: $rpm" >> BUILD_INFO.txt + rpm -qpi "$rpm" 2>/dev/null | grep -E "^(Name|Version|Release|Architecture|Size)" >> BUILD_INFO.txt + done + + ls -la + + - name: Upload binary RPM artifact + if: success() + run: | + # Find the main binary RPM (exclude debug and source RPMs) + BIN_RPM=$(find artifacts -name "continuwuity-*.rpm" \ + ! -name "*debuginfo*" \ + ! -name "*debugsource*" \ + ! -name "*.src.rpm" \ + -type f) + + # Create temp directory for this artifact + mkdir -p upload-bin + cp $BIN_RPM upload-bin/ + + - name: Upload binary RPM + if: success() + uses: actions/upload-artifact@v3 + with: + name: continuwuity + path: upload-bin/ + + - name: Upload debug RPM artifact + if: success() + uses: actions/upload-artifact@v3 + with: + name: continuwuity-debug + path: artifacts/*debuginfo*.rpm + + - name: Publish to RPM Package Registry + if: success() && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') + run: | + + # Find the binary RPM (exclude source RPMs) + RPM=$(find artifacts -name "continuwuity-*.rpm" ! -name "*.src.rpm" | head -1) + + if [ -z "$RPM" ]; then + echo "No binary RPM found to publish" + exit 0 + fi + + # Extract version from RPM filename + RPM_BASENAME=$(basename "$RPM") + echo "Publishing: $RPM_BASENAME" + + # Determine the group based on ref type and branch + if [[ "${{ github.ref }}" == "refs/tags/"* ]]; then + GROUP="stable" + elif [ "${{ github.ref_name }}" = "main" ]; then + GROUP="dev" + else + # Use sanitized branch name as group for feature branches + GROUP=$(echo "${{ github.ref_name }}" | sed 's/[^a-zA-Z0-9]/-/g' | tr '[:upper:]' '[:lower:]' | cut -c1-30) + fi + + # Extract package info from RPM for deletion + PACKAGE_INFO=$(rpm -qpi "$RPM" 2>/dev/null) + PACKAGE_NAME=$(echo "$PACKAGE_INFO" | grep "^Name" | awk '{print $3}') + PACKAGE_VERSION=$(echo "$PACKAGE_INFO" | grep "^Version" | awk '{print $3}') + PACKAGE_RELEASE=$(echo "$PACKAGE_INFO" | grep "^Release" | awk '{print $3}') + PACKAGE_ARCH=$(echo "$PACKAGE_INFO" | grep "^Architecture" | awk '{print $2}') + + # Full version includes release + FULL_VERSION="${PACKAGE_VERSION}-${PACKAGE_RELEASE}" + + # Try to delete existing package first (ignore errors if it doesn't exist) + echo "Removing any existing package: $PACKAGE_NAME-$FULL_VERSION.$PACKAGE_ARCH" + curl -X DELETE \ + -H "Authorization: token ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}" \ + "https://forgejo.ellis.link/api/packages/continuwuation/rpm/$GROUP/package/$PACKAGE_NAME/$FULL_VERSION/$PACKAGE_ARCH" \ + || echo "Package didn't exist or deletion failed (this is OK)" + + # Upload to Forgejo package registry + # Using the RPM registry endpoint with group support + curl --fail-with-body \ + -X PUT \ + -H "Authorization: token ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}" \ + -H "Content-Type: application/x-rpm" \ + -T "$RPM" \ + "https://forgejo.ellis.link/api/packages/continuwuation/rpm/$GROUP/upload" + + echo "" + echo "✅ Published to: https://forgejo.ellis.link/continuwuation/-/packages/rpm/continuwuity/" + echo "Group: $GROUP" + + # Also upload the SRPM + SRPM=$(find artifacts -name "*.src.rpm" | head -1) + if [ -n "$SRPM" ]; then + echo "" + echo "Publishing source RPM: $(basename "$SRPM")" + + # Extract SRPM info for deletion + SRPM_INFO=$(rpm -qpi "$SRPM" 2>/dev/null) + SRPM_ARCH=$(echo "$SRPM_INFO" | grep "^Architecture" | awk '{print $2}') + + # Try to delete existing SRPM first (using same name/version as binary RPM) + echo "Removing any existing SRPM: $PACKAGE_NAME-$FULL_VERSION.$SRPM_ARCH" + curl -X DELETE \ + -H "Authorization: token ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}" \ + "https://forgejo.ellis.link/api/packages/continuwuation/rpm/$GROUP/package/$PACKAGE_NAME/$FULL_VERSION/$SRPM_ARCH" \ + || echo "SRPM didn't exist or deletion failed (this is OK)" + + curl --fail-with-body \ + -X PUT \ + -H "Authorization: token ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}" \ + -H "Content-Type: application/x-rpm" \ + -T "$SRPM" \ + "https://forgejo.ellis.link/api/packages/continuwuation/rpm/$GROUP/upload" + fi diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index fa097238..8936a1ef 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -10,6 +10,7 @@ - [Kubernetes](deploying/kubernetes.md) - [Arch Linux](deploying/arch-linux.md) - [Debian](deploying/debian.md) + - [Fedora](deploying/fedora.md) - [FreeBSD](deploying/freebsd.md) - [TURN](turn.md) - [Appservices](appservices.md) diff --git a/docs/deploying/fedora.md b/docs/deploying/fedora.md new file mode 100644 index 00000000..084c19d9 --- /dev/null +++ b/docs/deploying/fedora.md @@ -0,0 +1,189 @@ +# RPM Installation Guide + +Continuwuity is available as RPM packages for Fedora, RHEL, and compatible distributions. + +## Quick install (stable) + +For the latest stable version from release tags: + +```bash +# Add the Continuwuity repository +sudo dnf config-manager addrepo --from-repofile=https://forgejo.ellis.link/api/packages/continuwuation/rpm/stable/continuwuation.repo + +# Install Continuwuity +sudo dnf install continuwuity + +# Enable automatic updates (optional) +sudo dnf install dnf-automatic +sudo systemctl enable --now dnf-automatic.timer +``` + +## Development builds + +For development builds from the main branch: + +```bash +# Add the dev repository +sudo dnf config-manager addrepo --from-repofile=https://forgejo.ellis.link/api/packages/continuwuation/rpm/dev/continuwuation.repo + +# Install Continuwuity +sudo dnf install continuwuity +``` + +## Feature branch builds + +Feature branches are published to their own groups. For example, for branch `tom/new-feature`: + +```bash +# Add the branch-specific repository (replace branch name) +sudo dnf config-manager addrepo --from-repofile=https://forgejo.ellis.link/api/packages/continuwuation/rpm/tom-new-feature/continuwuation.repo + +# Install Continuwuity +sudo dnf install continuwuity +``` + +Note: Branch names are sanitized (slashes become hyphens, lowercase only). + +## Direct package installation + +To install a specific version without adding the repository: + +```bash +# Latest stable release +sudo dnf install https://forgejo.ellis.link/api/packages/continuwuation/rpm/stable/continuwuity + +# Latest development build (main branch) +sudo dnf install https://forgejo.ellis.link/api/packages/continuwuation/rpm/dev/continuwuity + +# Specific feature branch (replace branch-name) +sudo dnf install https://forgejo.ellis.link/api/packages/continuwuation/rpm/branch-name/continuwuity +``` + +## Managing automatic updates + +### Option 1: DNF Automatic (recommended) + +```bash +# Install dnf-automatic +sudo dnf install dnf-automatic + +# Configure update policy +sudo nano /etc/dnf/automatic.conf +# Set: apply_updates = yes + +# Enable the service +sudo systemctl enable --now dnf-automatic.timer +``` + +### Option 2: Manual updates + +```bash +# Check for updates +sudo dnf check-update continuwuity + +# Update to latest version +sudo dnf update continuwuity +``` + +## Switching between channels + +```bash +# List enabled repositories +dnf repolist | grep continuwuation + +# Disable current repository (use actual repo name from above) +sudo dnf config-manager --set-disabled continuwuation-stable +# or +sudo dnf config-manager --set-disabled continuwuation-dev +# or for feature branches +sudo dnf config-manager --set-disabled continuwuation-branch-name + +# Enable desired repository +sudo dnf config-manager --set-enabled continuwuation-stable +# or +sudo dnf config-manager --set-enabled continuwuation-dev + +# Update to the new channel's version +sudo dnf update continuwuity +``` + +## Verifying installation + +```bash +# Check installed version +rpm -q continuwuity + +# View package information +rpm -qi continuwuity + +# List installed files +rpm -ql continuwuity + +# Verify package integrity +rpm -V continuwuity +``` + +## Systemd service management + +Continuwuity includes a systemd service file: + +```bash +# Start the service +sudo systemctl start conduwuit + +# Enable on boot +sudo systemctl enable conduwuit + +# Check status +sudo systemctl status conduwuit + +# View logs +sudo journalctl -u conduwuit -f +``` + +## Uninstallation + +```bash +# Stop and disable the service +sudo systemctl stop conduwuit +sudo systemctl disable conduwuit + +# Remove the package +sudo dnf remove continuwuity + +# Remove the repository (optional) +sudo rm /etc/yum.repos.d/continuwuation-*.repo +``` + +## Troubleshooting + +### GPG key issues + +If you encounter GPG key errors, you can temporarily disable GPG checking: + +```bash +sudo dnf --nogpgcheck install continuwuity +``` + +### Repository metadata issues + +Clear and rebuild the cache: + +```bash +sudo dnf clean all +sudo dnf makecache +``` + +### Finding specific versions + +List all available versions: + +```bash +dnf --showduplicates list continuwuity +``` + +Install a specific version: + +```bash +sudo dnf install continuwuity- +``` diff --git a/fedora/continuwuity.spec.rpkg b/fedora/continuwuity.spec.rpkg index 19edf701..4ff7dbe6 100644 --- a/fedora/continuwuity.spec.rpkg +++ b/fedora/continuwuity.spec.rpkg @@ -1,6 +1,5 @@ -# This should be run using rpkg-util: https://docs.pagure.org/rpkg-util +# This should be run using rpkg: https://docs.pagure.org/rpkg # it requires Internet access and is not suitable for Fedora main repos -# TODO: rpkg-util is no longer maintained, find a replacement Name: continuwuity Version: {{{ git_repo_version }}} @@ -38,7 +37,7 @@ sed -i 's/^offline = true$//' .cargo/config.toml %cargo_build # Here's the one legally required mystery incantation in this file. -# Some of our dependencies have source files which are (for some reason) marked as excutable. +# Some of our dependencies have source files which are (for some reason) marked as executable. # Files in .cargo/registry/ are copied into /usr/src/ by the debuginfo machinery # at the end of the build step, and then the BRP shebang mangling script checks # the entire buildroot to find executable files, and fails the build because @@ -46,7 +45,7 @@ sed -i 's/^offline = true$//' .cargo/config.toml # So we have to clear the executable bit on all of them before that happens. find .cargo/registry/ -executable -name "*.rs" -exec chmod -x {} + -# TODO: this fails currently because it's forced to run in offline mode +# TODO: this fails currently because it's forced to run in offline mode # {cargo_license -- --no-dev} > LICENSE.dependencies %install @@ -77,4 +76,4 @@ install -Dpm0644 conduwuit-example.toml %{buildroot}%{_sysconfdir}/conduwuit/con %systemd_postun_with_restart conduwuit.service %changelog -{{{ git_repo_changelog }}} \ No newline at end of file +{{{ git_repo_changelog }}}