From b934898f51a2d3fa80ece879ef5fc2774a7f5881 Mon Sep 17 00:00:00 2001 From: Jade Ellis Date: Sun, 31 Aug 2025 00:25:41 +0100 Subject: [PATCH 1/4] chore: Update renovate config, limit cargo updates --- .editorconfig | 4 ++ renovate.json | 115 ++++++++++++++++++++++++-------------------------- 2 files changed, 60 insertions(+), 59 deletions(-) diff --git a/.editorconfig b/.editorconfig index 3e7fd1b8..95843e73 100644 --- a/.editorconfig +++ b/.editorconfig @@ -26,3 +26,7 @@ max_line_length = 98 [*.yml] indent_size = 2 indent_style = space + +[*.json] +indent_size = 4 +indent_style = space diff --git a/renovate.json b/renovate.json index deb428af..68d21b9d 100644 --- a/renovate.json +++ b/renovate.json @@ -1,62 +1,59 @@ { - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended" - ], - "lockFileMaintenance": { - "enabled": true, - "schedule": [ - "at any time" + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["config:recommended"], + "lockFileMaintenance": { + "enabled": true, + "schedule": ["at any time"] + }, + "nix": { + "enabled": true + }, + "labels": ["Dependencies", "Dependencies/Renovate"], + "ignoreDeps": [ + "tikv-jemallocator", + "tikv-jemalloc-sys", + "tikv-jemalloc-ctl", + "opentelemetry", + "opentelemetry_sdk", + "opentelemetry-jaeger", + "tracing-opentelemetry" + ], + "github-actions": { + "enabled": true, + "managerFilePatterns": [ + "/(^|/)\\.forgejo/workflows/[^/]+\\.ya?ml$/", + "/(^|/)\\.forgejo/actions/[^/]+/action\\.ya?ml$/", + "/(^|/)\\.github/workflows/[^/]+\\.ya?ml$/", + "/(^|/)\\.github/actions/[^/]+/action\\.ya?ml$/" + ] + }, + "packageRules": [ + { + "description": "Batch minor and patch GitHub Actions updates", + "matchManagers": ["github-actions"], + "matchUpdateTypes": ["minor", "patch"], + "groupName": "github-actions-non-major" + }, + { + "description": "Group Rust toolchain updates into a single PR", + "matchManagers": ["custom.regex"], + "matchPackageNames": ["rust", "rustc", "cargo"], + "groupName": "rust-toolchain" + }, + { + "description": "Group lockfile updates into a single PR", + "matchUpdateTypes": ["lockFileMaintenance"], + "groupName": "lockfile-maintenance" + }, + { + "description": "Batch patch-level Rust dependency updates", + "matchManagers": ["cargo"], + "matchUpdateTypes": ["patch"], + "groupName": "rust-patch-updates" + }, + { + "matchManagers": ["cargo"], + "prConcurrentLimit": 5 + } ] - }, - "nix": { - "enabled": true - }, - "labels": [ - "Dependencies", - "Dependencies/Renovate" - ], - "ignoreDeps": [ - "tikv-jemallocator", - "tikv-jemalloc-sys", - "tikv-jemalloc-ctl", - "opentelemetry", - "opentelemetry_sdk", - "opentelemetry-jaeger", - "tracing-opentelemetry" - ], - "github-actions": { - "enabled": true, - "fileMatch": [ - "(^|/)\\.forgejo/workflows/[^/]+\\.ya?ml$", - "(^|/)\\.forgejo/actions/[^/]+/action\\.ya?ml$", - "(^|/)\\.github/workflows/[^/]+\\.ya?ml$", - "(^|/)\\.github/actions/[^/]+/action\\.ya?ml$" - ] - }, - "packageRules": [ - { - "description": "Batch minor and patch GitHub Actions updates", - "matchManagers": ["github-actions"], - "matchUpdateTypes": ["minor", "patch"], - "groupName": "github-actions-non-major" - }, - { - "description": "Group Rust toolchain updates into a single PR", - "matchManagers": ["regex"], - "matchPackageNames": ["rust", "rustc", "cargo"], - "groupName": "rust-toolchain" - }, - { - "description": "Group lockfile updates into a single PR", - "matchUpdateTypes": ["lockFileMaintenance"], - "groupName": "lockfile-maintenance" - }, - { - "description": "Batch patch-level Rust dependency updates", - "matchManagers": ["cargo"], - "matchUpdateTypes": ["patch"], - "groupName": "rust-patch-updates" - } - ] } From e87c461b8d1d03d9e7b7b727f9a2fe8456c7338e Mon Sep 17 00:00:00 2001 From: Jade Ellis Date: Sun, 31 Aug 2025 00:38:47 +0100 Subject: [PATCH 2/4] feat: Cache renovate data, RO GitHub token --- .forgejo/workflows/renovate.yml | 69 ++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 10 deletions(-) diff --git a/.forgejo/workflows/renovate.yml b/.forgejo/workflows/renovate.yml index e8522bec..0152b387 100644 --- a/.forgejo/workflows/renovate.yml +++ b/.forgejo/workflows/renovate.yml @@ -39,24 +39,73 @@ jobs: renovate: name: Renovate runs-on: ubuntu-latest + container: + image: ghcr.io/renovatebot/renovate:41 + options: --tmpfs /tmp:exec steps: - name: Checkout uses: actions/checkout@v4 + with: + show-progress: false + + - name: print node heap + run: /usr/local/renovate/node -e 'console.log(`node heap limit = ${require("v8").getHeapStatistics().heap_size_limit / (1024 * 1024)} Mb`)' + + - name: Restore renovate repo cache + uses: https://github.com/actions/cache@v4 + with: + path: | + /tmp/renovate/cache/renovate/repository + key: repo-cache-${{ github.run_id }} + restore-keys: | + repo-cache- + + - name: Restore renovate package cache + uses: https://github.com/actions/cache@v4 + with: + path: | + /tmp/renovate/cache/renovate/renovate-cache-sqlite + key: package-cache-${{ github.run_id }} + restore-keys: | + package-cache- - name: Self-hosted Renovate - uses: https://github.com/renovatebot/github-action@v40.1.0 + uses: https://github.com/renovatebot/github-action@v43.0.9 env: LOG_LEVEL: ${{ inputs.logLevel || 'info' }} - RENOVATE_AUTODISCOVER: 'false' - RENOVATE_BINARY_SOURCE: 'install' RENOVATE_DRY_RUN: ${{ inputs.dryRun || 'false' }} - RENOVATE_ENDPOINT: ${{ github.server_url }}/api/v1 - RENOVATE_GIT_TIMEOUT: 60000 - RENOVATE_GIT_URL: 'endpoint' - RENOVATE_GITHUB_TOKEN_WARN: 'false' - RENOVATE_ONBOARDING: 'false' - RENOVATE_PLATFORM: 'forgejo' - RENOVATE_PR_COMMITS_PER_RUN_LIMIT: 3 + + RENOVATE_PLATFORM: forgejo + RENOVATE_ENDPOINT: ${{ github.server_url }} + RENOVATE_AUTODISCOVER: 'false' RENOVATE_REPOSITORIES: '["${{ github.repository }}"]' + + RENOVATE_GIT_TIMEOUT: 60000 + RENOVATE_REQUIRE_CONFIG: 'required' + RENOVATE_ONBOARDING: 'false' + + RENOVATE_PR_COMMITS_PER_RUN_LIMIT: 3 + + RENOVATE_GITHUB_TOKEN_WARN: 'false' RENOVATE_TOKEN: ${{ secrets.RENOVATE_TOKEN }} + GITHUB_COM_TOKEN: ${{ secrets.GH_PUBLIC_RO }} + + RENOVATE_REPOSITORY_CACHE: 'enabled' + RENOVATE_X_SQLITE_PACKAGE_CACHE: true + + - name: Save renovate repo cache + if: always() && env.RENOVATE_DRY_RUN != 'full' + uses: https://github.com/actions/cache@v4 + with: + path: | + /tmp/renovate/cache/renovate/repository + key: repo-cache-${{ github.run_id }} + + - name: Save renovate package cache + if: always() && env.RENOVATE_DRY_RUN != 'full' + uses: https://github.com/actions/cache@v4 + with: + path: | + /tmp/renovate/cache/renovate/renovate-cache-sqlite + key: package-cache-${{ github.run_id }} From 5cce02484146e62b34e7228f603cb42559c76eff Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sun, 31 Aug 2025 00:44:28 +0000 Subject: [PATCH 3/4] chore(deps): update https://github.com/reproducible-containers/buildkit-cache-dance action to v3.3.0 --- .forgejo/workflows/release-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/release-image.yml b/.forgejo/workflows/release-image.yml index 04fc9de9..58d6cab2 100644 --- a/.forgejo/workflows/release-image.yml +++ b/.forgejo/workflows/release-image.yml @@ -161,7 +161,7 @@ jobs: var-lib-apt-${{ matrix.slug }} key: var-lib-apt-${{ matrix.slug }} - name: inject cache into docker - uses: https://github.com/reproducible-containers/buildkit-cache-dance@v3.1.0 + uses: https://github.com/reproducible-containers/buildkit-cache-dance@v3.3.0 with: cache-map: | { From 4b78ab39e0461377608cf3b5d079c202c8e04f64 Mon Sep 17 00:00:00 2001 From: Tom Foster Date: Sun, 31 Aug 2025 18:23:38 +0100 Subject: [PATCH 4/4] feat(ci): Add Fedora RPM package build workflow Build and publish RPM packages for Fedora using rpkg and official rust-packaging macros. GPG sign packages with Ed25519 repository key and deploy to Forgejo package registry. Package organisation works around Forgejo's one-file-per-version limit: - Binary packages: base group (stable/dev/branch-name) - Debug packages: GROUP-debug - Source packages: GROUP-src Workflow triggers on pushes to relevant paths and version tags (v*). Tagged releases use clean version numbers (v1.2.3 becomes 1.2.3-1) while branch builds use git SHA versioning. Include GPG public key for package verification and documentation for RPM repository configuration and installation methods. --- .forgejo/workflows/build-fedora.yml | 480 ++++++++++++++++++++++++++++ docs/SUMMARY.md | 1 + docs/deploying/fedora.md | 201 ++++++++++++ fedora/RPM-GPG-KEY-continuwuity.asc | 16 + fedora/continuwuity.spec.rpkg | 3 +- 5 files changed, 699 insertions(+), 2 deletions(-) create mode 100644 .forgejo/workflows/build-fedora.yml create mode 100644 docs/deploying/fedora.md create mode 100644 fedora/RPM-GPG-KEY-continuwuity.asc diff --git a/.forgejo/workflows/build-fedora.yml b/.forgejo/workflows/build-fedora.yml new file mode 100644 index 00000000..4c5931a3 --- /dev/null +++ b/.forgejo/workflows/build-fedora.yml @@ -0,0 +1,480 @@ +name: Build / Fedora RPM + +concurrency: + group: "build-fedora-${{ github.ref }}" + cancel-in-progress: true + +on: + push: + branches: + - '**' + tags: + - 'v*' + paths: + - 'fedora/**' + - 'src/**' + - 'Cargo.toml' + - 'Cargo.lock' + - '.forgejo/workflows/build-fedora.yml' + workflow_dispatch: + +jobs: + build: + 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 with full history + uses: https://code.forgejo.org/actions/checkout@v4 + with: + fetch-depth: 0 + + + - name: Cache DNF packages + uses: https://code.forgejo.org/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: Cache Cargo registry + uses: https://code.forgejo.org/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: Cache Rust build dependencies + uses: https://code.forgejo.org/actions/cache@v4 + with: + path: | + ~/rpmbuild/BUILD/*/target/release/deps + ~/rpmbuild/BUILD/*/target/release/build + ~/rpmbuild/BUILD/*/target/release/.fingerprint + ~/rpmbuild/BUILD/*/target/release/incremental + key: rust-deps-fedora${{ steps.fedora.outputs.version }}-${{ hashFiles('**/Cargo.lock') }} + restore-keys: | + rust-deps-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 + echo "SCCACHE_CACHE_SIZE=10G" >> $GITHUB_ENV + # Aggressive GC since cache restores don't increment counter + echo "CARGO_INCREMENTAL_GC_TRIGGER=5" >> $GITHUB_ENV + + - name: Install build dependencies + run: | + dnf install -y --setopt=keepcache=1 \ + wget \ + rpm-build \ + rpm-sign \ + rpmdevtools \ + rpkg \ + cargo-rpm-macros \ + systemd-rpm-macros \ + clang \ + liburing-devel \ + rust \ + cargo \ + gcc \ + gcc-c++ \ + make \ + openssl-devel \ + pkg-config \ + python3-pip + + - 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 + + cd "$GITHUB_WORKSPACE" + + # Determine release suffix and version based on ref type and branch + if [[ "${{ github.ref }}" == "refs/tags/"* ]]; then + # Tags get clean version numbers for stable releases + RELEASE_SUFFIX="" + TAG_NAME="${{ github.ref_name }}" + # Extract version from tag (remove v prefix if present) + TAG_VERSION=$(echo "$TAG_NAME" | sed 's/^v//') + + # Create spec file with tag version + sed -e "s/^Version:.*$/Version: $TAG_VERSION/" \ + -e "s/^Release:.*$/Release: 1%{?dist}/" \ + fedora/continuwuity.spec.rpkg > continuwuity.spec.rpkg + elif [ "${{ github.ref_name }}" = "main" ]; then + # Main branch gets .dev suffix + RELEASE_SUFFIX=".dev" + + # Replace the Release line to include our suffix + sed "s/^Release:.*$/Release: 1${RELEASE_SUFFIX}%{?dist}/" \ + fedora/continuwuity.spec.rpkg > continuwuity.spec.rpkg + 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}" + + # Replace the Release line to include our suffix + sed "s/^Release:.*$/Release: 1${RELEASE_SUFFIX}%{?dist}/" \ + fedora/continuwuity.spec.rpkg > continuwuity.spec.rpkg + fi + + # Build the SRPM + rpkg srpm --outdir "$HOME/rpmbuild/SRPMS" + + # Show SRPM info + ls -la $HOME/rpmbuild/SRPMS/ + + - name: Setup GPG for RPM signing + run: | + # Skip if no signing key is configured + if [ -z "${{ secrets.RPM_SIGNING_KEY }}" ]; then + echo "No RPM signing key configured - skipping signing setup" + exit 0 + fi + + # Import the signing key + echo "${{ secrets.RPM_SIGNING_KEY }}" | gpg --batch --import + + # Get the key ID (look for the sec line, not the uid line) + KEY_ID=$(gpg --list-secret-keys --keyid-format=long | grep "^sec" | head -1 | awk '{print $2}' | cut -d'/' -f2) + echo "Using GPG key: $KEY_ID" + + # Configure RPM macros for signing + cat > ~/.rpmmacros << EOF + %_signature gpg + %_gpg_name $KEY_ID + %__gpg /usr/bin/gpg + EOF + + - 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 + rpmbuild --rebuild "$SRPM" \ + --define "_topdir $HOME/rpmbuild" \ + --define "_sourcedir $GITHUB_WORKSPACE" \ + --nocheck # Skip %check section to avoid test dependencies + + - name: Sign RPM packages + run: | + # Skip if no signing key is configured + if [ -z "${{ secrets.RPM_SIGNING_KEY }}" ]; then + echo "No RPM signing key configured - skipping package signing" + exit 0 + fi + + # Track signing failures + FAILED_COUNT=0 + TOTAL_COUNT=0 + + # Export GPG_TTY to avoid terminal warnings + export GPG_TTY=/dev/null + + # Sign all RPMs (binary and source) + for rpm in $(find "$HOME/rpmbuild" -name "*.rpm" -type f); do + echo "Signing: $(basename $rpm)" + TOTAL_COUNT=$((TOTAL_COUNT + 1)) + + # Use expect or provide empty passphrase via stdin for batch signing + if ! echo "" | rpmsign --addsign "$rpm" 2>&1; then + echo "ERROR: Failed to sign $rpm" + FAILED_COUNT=$((FAILED_COUNT + 1)) + fi + done + + # Fail if any RPMs failed to sign + if [ "$FAILED_COUNT" -gt 0 ]; then + echo "ERROR: Failed to sign $FAILED_COUNT out of $TOTAL_COUNT RPMs" + exit 1 + fi + + echo "Successfully signed all $TOTAL_COUNT RPMs" + + - name: Verify RPM signatures + run: | + # Skip if no signing key is configured + if [ -z "${{ secrets.RPM_SIGNING_KEY }}" ]; then + echo "No RPM signing key configured - skipping signature verification" + exit 0 + fi + + # Import our public key for verification + echo "Importing GPG public key for verification..." + rpm --import fedora/RPM-GPG-KEY-continuwuity.asc + + # Track verification failures + FAILED_COUNT=0 + TOTAL_COUNT=0 + + # Verify all RPMs + for rpm in $(find "$HOME/rpmbuild" -name "*.rpm" -type f); do + echo -n "Verifying $(basename $rpm): " + TOTAL_COUNT=$((TOTAL_COUNT + 1)) + + if rpm --checksig "$rpm"; then + echo " ✓" + else + echo " ✗ FAILED" + FAILED_COUNT=$((FAILED_COUNT + 1)) + fi + done + + # Fail if any RPMs failed verification + if [ "$FAILED_COUNT" -gt 0 ]; then + echo "ERROR: $FAILED_COUNT out of $TOTAL_COUNT RPMs failed signature verification" + exit 1 + fi + + echo "Successfully verified all $TOTAL_COUNT RPM signatures" + + - name: Test RPM installation + run: | + # Find the main binary RPM (exclude debug and source RPMs) + RPM=$(find "$HOME/rpmbuild/RPMS" -name "continuwuity-*.rpm" \ + ! -name "*debuginfo*" \ + ! -name "*debugsource*" \ + ! -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: 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: Collect artifacts + 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 + 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 + uses: https://code.forgejo.org/actions/upload-artifact@v3 + with: + name: continuwuity + path: upload-bin/ + + - name: Upload debug RPM artifact + uses: https://code.forgejo.org/actions/upload-artifact@v3 + with: + name: continuwuity-debug + path: artifacts/*debuginfo*.rpm + + - name: Publish to RPM Package Registry + if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }} + run: | + # Find the main binary RPM (exclude debug and source RPMs) + RPM=$(find artifacts -name "continuwuity-*.rpm" \ + ! -name "*debuginfo*" \ + ! -name "*debugsource*" \ + ! -name "*.src.rpm" \ + -type f | 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" + # For tags, extract the tag name for version info + TAG_NAME="${{ github.ref_name }}" + 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 binary RPM to: https://forgejo.ellis.link/continuwuation/-/packages/rpm/continuwuity/" + echo "Group: $GROUP" + + # Upload debug RPMs to separate group + DEBUG_RPMS=$(find artifacts -name "*debuginfo*.rpm" -o -name "*debugsource*.rpm") + if [ -n "$DEBUG_RPMS" ]; then + echo "" + echo "Publishing debug RPMs to group: ${GROUP}-debug" + + for DEBUG_RPM in $DEBUG_RPMS; do + echo "Publishing: $(basename "$DEBUG_RPM")" + + # Extract debug RPM info + DEBUG_INFO=$(rpm -qpi "$DEBUG_RPM" 2>/dev/null) + DEBUG_NAME=$(echo "$DEBUG_INFO" | grep "^Name" | awk '{print $3}') + DEBUG_VERSION=$(echo "$DEBUG_INFO" | grep "^Version" | awk '{print $3}') + DEBUG_RELEASE=$(echo "$DEBUG_INFO" | grep "^Release" | awk '{print $3}') + DEBUG_ARCH=$(echo "$DEBUG_INFO" | grep "^Architecture" | awk '{print $2}') + DEBUG_FULL_VERSION="${DEBUG_VERSION}-${DEBUG_RELEASE}" + + # Try to delete existing debug package first + curl -X DELETE \ + -H "Authorization: token ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}" \ + "https://forgejo.ellis.link/api/packages/continuwuation/rpm/${GROUP}-debug/package/$DEBUG_NAME/$DEBUG_FULL_VERSION/$DEBUG_ARCH" \ + || echo "Debug package didn't exist or deletion failed (this is OK)" + + # Upload debug RPM + curl --fail-with-body \ + -X PUT \ + -H "Authorization: token ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}" \ + -H "Content-Type: application/x-rpm" \ + -T "$DEBUG_RPM" \ + "https://forgejo.ellis.link/api/packages/continuwuation/rpm/${GROUP}-debug/upload" + done + + echo "✅ Published debug RPMs to group: ${GROUP}-debug" + fi + + # Also upload the SRPM to separate group + SRPM=$(find artifacts -name "*.src.rpm" | head -1) + if [ -n "$SRPM" ]; then + echo "" + echo "Publishing source RPM: $(basename "$SRPM")" + echo "Publishing to group: ${GROUP}-src" + + # Extract SRPM info + SRPM_INFO=$(rpm -qpi "$SRPM" 2>/dev/null) + SRPM_NAME=$(echo "$SRPM_INFO" | grep "^Name" | awk '{print $3}') + SRPM_VERSION=$(echo "$SRPM_INFO" | grep "^Version" | awk '{print $3}') + SRPM_RELEASE=$(echo "$SRPM_INFO" | grep "^Release" | awk '{print $3}') + SRPM_FULL_VERSION="${SRPM_VERSION}-${SRPM_RELEASE}" + + # Try to delete existing SRPM first + echo "Removing any existing SRPM: $SRPM_NAME-$SRPM_FULL_VERSION.src" + curl -X DELETE \ + -H "Authorization: token ${{ secrets.BUILTIN_REGISTRY_PASSWORD || secrets.GITHUB_TOKEN }}" \ + "https://forgejo.ellis.link/api/packages/continuwuation/rpm/${GROUP}-src/package/$SRPM_NAME/$SRPM_FULL_VERSION/src" \ + || 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}-src/upload" + + echo "✅ Published source RPM to group: ${GROUP}-src" + 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..0130809b --- /dev/null +++ b/docs/deploying/fedora.md @@ -0,0 +1,201 @@ +# RPM Installation Guide + +Continuwuity is available as RPM packages for Fedora, RHEL, and compatible distributions. + +The RPM packaging files are maintained in the `fedora/` directory: +- `continuwuity.spec.rpkg` - RPM spec file using rpkg macros for building from git +- `continuwuity.service` - Systemd service file for the server +- `RPM-GPG-KEY-continuwuity.asc` - GPG public key for verifying signed packages + +RPM packages built by CI are signed with our GPG key (Ed25519, ID: `5E0FF73F411AAFCA`). + +```bash +# Import the signing key +sudo rpm --import https://forgejo.ellis.link/continuwuation/continuwuity/raw/branch/main/fedora/RPM-GPG-KEY-continuwuity.asc + +# Verify a downloaded package +rpm --checksig continuwuity-*.rpm +``` + +## Installation methods + +**Stable releases** (recommended) + +```bash +# Add the repository and install +sudo dnf config-manager addrepo --from-repofile=https://forgejo.ellis.link/api/packages/continuwuation/rpm/stable/continuwuation.repo +sudo dnf install continuwuity +``` + +**Development builds** from main branch + +```bash +# Add the dev repository and install +sudo dnf config-manager addrepo --from-repofile=https://forgejo.ellis.link/api/packages/continuwuation/rpm/dev/continuwuation.repo +sudo dnf install continuwuity +``` + +**Feature branch builds** (example: `tom/new-feature`) + +```bash +# Branch names are sanitized (slashes become hyphens, lowercase only) +sudo dnf config-manager addrepo --from-repofile=https://forgejo.ellis.link/api/packages/continuwuation/rpm/tom-new-feature/continuwuation.repo +sudo dnf install continuwuity +``` + +**Direct installation** without adding repository + +```bash +# Latest stable release +sudo dnf install https://forgejo.ellis.link/api/packages/continuwuation/rpm/stable/continuwuity + +# Latest development build +sudo dnf install https://forgejo.ellis.link/api/packages/continuwuation/rpm/dev/continuwuity + +# Specific feature branch +sudo dnf install https://forgejo.ellis.link/api/packages/continuwuation/rpm/branch-name/continuwuity +``` + +**Manual repository configuration** (alternative method) + +```bash +cat << 'EOF' | sudo tee /etc/yum.repos.d/continuwuity.repo +[continuwuity] +name=Continuwuity - Matrix homeserver +baseurl=https://forgejo.ellis.link/api/packages/continuwuation/rpm/stable +enabled=1 +gpgcheck=1 +gpgkey=https://forgejo.ellis.link/continuwuation/continuwuity/raw/branch/main/fedora/RPM-GPG-KEY-continuwuity.asc +EOF + +sudo dnf install continuwuity +``` + +## Package management + +**Automatic updates** with DNF Automatic + +```bash +# Install and configure +sudo dnf install dnf-automatic +sudo nano /etc/dnf/automatic.conf # Set: apply_updates = yes +sudo systemctl enable --now dnf-automatic.timer +``` + +**Manual updates** + +```bash +# Check for updates +sudo dnf check-update continuwuity + +# Update to latest version +sudo dnf update continuwuity +``` + +**Switching channels** (stable/dev/feature branches) + +```bash +# List enabled repositories +dnf repolist | grep continuwuation + +# Disable current repository +sudo dnf config-manager --set-disabled continuwuation-stable # or -dev, or branch name + +# Enable desired repository +sudo dnf config-manager --set-enabled continuwuation-dev # or -stable, or branch name + +# 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 +``` + +## Service management and removal + +**Systemd service commands** + +```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 errors**: Temporarily disable GPG checking + +```bash +sudo dnf --nogpgcheck install continuwuity +``` + +**Repository metadata issues**: Clear and rebuild cache + +```bash +sudo dnf clean all +sudo dnf makecache +``` + +**Finding specific versions** + +```bash +# List all available versions +dnf --showduplicates list continuwuity + +# Install a specific version +sudo dnf install continuwuity- +``` + +## Building locally + +Build the RPM locally using rpkg: + +```bash +# Install dependencies +sudo dnf install rpkg rpm-build cargo-rpm-macros systemd-rpm-macros + +# Clone the repository +git clone https://forgejo.ellis.link/continuwuation/continuwuity.git +cd continuwuity + +# Build SRPM +rpkg srpm + +# Build RPM +rpmbuild --rebuild *.src.rpm +``` diff --git a/fedora/RPM-GPG-KEY-continuwuity.asc b/fedora/RPM-GPG-KEY-continuwuity.asc new file mode 100644 index 00000000..031128ac --- /dev/null +++ b/fedora/RPM-GPG-KEY-continuwuity.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mDMEaLM5LhYJKwYBBAHaRw8BAQdAlnMcp/fMzYfwqeExDsEx2qfZg8NjamGh0slC +9bkUpQW0O0NvbnRpbnV3dWl0eSBDSSAoUlBNIFBhY2thZ2UgU2lnbmluZykgPGNp +QGNvbnRpbnV3dWl0eS5vcmc+iJYEExYIAD4WIQShcq3anZQUJ0FNTm1eD/c/QRqv +ygUCaLM5LgIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRBeD/c/ +QRqvyk3QAQCjurJLpDANckZflsEVRwxDOUCrED4LdyWpbOuVmhGikwD/fGwkpdUa +ngP1l+bhlprJN5J1P5UOeNZtKce0vFZaBwC4MwRoszkuFgkrBgEEAdpHDwEBB0CJ +RpQlzJt/TdYx8AOkNIYan6qbxijjjpZWDIbZp95CfIj1BBgWCAAmFiEEoXKt2p2U +FCdBTU5tXg/3P0Ear8oFAmizOS4CGwIFCQPCZwAAgQkQXg/3P0Ear8p2IAQZFggA +HRYhBN/tBNmxKe70FHf4CRoGaPIa/K9qBQJoszkuAAoJEBoGaPIa/K9qf7EBAJ9D +pdKRji4gy9LWR3w9Ha7Tekmw7kSPGYLZlkDqjiuCAQCCupMGB9r2XPc2/G/KIV+7 +HpWfIANhPsCn1Q9kcloCCIv9AQCy+xDsdtkOw7JnB4g1EKfPlPhN6j3Cjk1vlG2N +WN/p2AEAkozKVDAbvWEi/s7W9DNWckXm1SS0Og/sv5nGV8okIg4= +=dxDr +-----END PGP PUBLIC KEY BLOCK----- diff --git a/fedora/continuwuity.spec.rpkg b/fedora/continuwuity.spec.rpkg index f2efa383..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 }}}