Compare commits

..

2 commits

Author SHA1 Message Date
Tom Foster
7406556550 feat(ci): Add Fedora RPM package build workflow
Following PR #950 which introduced the RPM spec and systemd unit files,
this adds a comprehensive CI workflow for building, signing, testing, and
publishing RPM packages. Includes GPG signing infrastructure with Ed25519
keys and automatic package registry deployment for stable, development,
and feature branch builds.

Add documentation for RPM installation methods, repository configuration,
and package management. Fix linting issues in spec file for pre-commit
compliance.
2025-08-30 20:30:28 +01:00
Tom Foster
609e239436 fix(fedora): Correct linting issues in RPM spec file
The Fedora RPM packaging files added in PR #950 weren't passing pre-commit
checks, causing CI failures for any branches rebased after that merge. This
applies prek linting fixes (typo correction, trailing whitespace removal,
and EOF newline) to ensure CI passes for all contributors.
2025-08-30 16:10:41 +01:00

View file

@ -5,11 +5,21 @@ concurrency:
cancel-in-progress: true
on:
workflow_dispatch:
push:
paths:
- '.forgejo/workflows/build-fedora.yml'
- 'fedora/**'
- 'src/**'
- 'Cargo.toml'
- 'Cargo.lock'
- '.forgejo/workflows/build-fedora.yml'
pull_request:
paths:
- 'fedora/**'
- 'src/**'
- 'Cargo.toml'
- 'Cargo.lock'
- '.forgejo/workflows/build-fedora.yml'
workflow_dispatch:
jobs:
build:
@ -124,9 +134,13 @@ jobs:
ls -la $HOME/rpmbuild/SRPMS/
- name: Setup GPG for RPM signing
if: success() && secrets.RPM_SIGNING_KEY != ''
run: |
echo "::group::🔐 Setting up GPG for RPM signing"
# 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
@ -141,8 +155,6 @@ jobs:
%__gpg /usr/bin/gpg
EOF
echo "::endgroup::"
- name: Build RPM from SRPM
run: |
# Find the SRPM file
@ -162,9 +174,12 @@ jobs:
--nocheck # Skip %check section to avoid test dependencies
- name: Sign RPM packages
if: success() && secrets.RPM_SIGNING_KEY != ''
run: |
echo "::group::✍️ Signing RPM packages"
# 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
# Sign all binary RPMs
find "$HOME/rpmbuild/RPMS" -name "*.rpm" -type f | while read rpm; do
@ -178,7 +193,50 @@ jobs:
rpmsign --addsign "$srpm" || echo "Warning: Failed to sign $srpm"
done
echo "::endgroup::"
- 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
curl -s https://forgejo.ellis.link/continuwuation/continuwuity/raw/branch/main/fedora/RPM-GPG-KEY-continuwuity.asc | rpm --import
# Verify all RPMs
find "$HOME/rpmbuild" -name "*.rpm" -type f | while read rpm; do
echo -n "Verifying $(basename $rpm): "
rpm --checksig "$rpm"
done
- 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: List built packages
run: |
@ -190,7 +248,6 @@ jobs:
find "$HOME/rpmbuild/SRPMS" -name "*.rpm" -type f -exec ls -la {} \;
- name: Collect artifacts
if: success()
run: |
mkdir -p artifacts
@ -217,7 +274,6 @@ jobs:
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" \
@ -231,15 +287,93 @@ jobs:
cp $BIN_RPM upload-bin/
- name: Upload binary RPM
if: success()
uses: https://code.forgejo.org/actions/upload-artifact@v3
with:
name: continuwuity
path: upload-bin/
- name: Upload debug RPM artifact
if: success()
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 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