Compare commits

..

1 commit

Author SHA1 Message Date
Tom Foster
0ab7e5aef5 ci: Add Fedora RPM build workflow with GPG signing
Implement comprehensive CI workflow for building and signing Fedora RPM
packages. When RPM_SIGNING_KEY secret is configured, packages are
automatically signed with GPG and signature verified. Public key
distributed via repository for user package verification.

Includes complete RPM installation documentation with repository setup,
package management, and troubleshooting guidance. Documentation
integrated into mdBook site for better discoverability.
2025-08-30 19:37:04 +01:00

View file

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