Add rpm
All checks were successful
CI / test (push) Successful in 8m7s
Lint / test (push) Successful in 35s
Trivy / test (push) Successful in 18s

This commit is contained in:
Miguel Jacq 2025-12-24 15:26:41 +11:00
parent 4fda9833ed
commit 9b457278f9
Signed by: mig5
GPG key ID: 59B3F0C24135C6A9
6 changed files with 240 additions and 3 deletions

108
Dockerfile.rpmbuild Normal file
View file

@ -0,0 +1,108 @@
# syntax=docker/dockerfile:1
FROM fedora:42
# rpmbuild in a container does not auto-install BuildRequires. Since we're
# building directly in Docker (not mock), we pre-install the common deps that
# Fedora's pyproject macros will require for Bouquin.
#
# NOTE: bouquin also needs python3dist(sqlcipher4) at build time (because
# %pyproject_buildrequires includes runtime deps). That one is NOT in Fedora;
# we install it from /deps.
RUN set -eux; \
dnf -y update; \
dnf -y install \
rpm-build rpmdevtools \
redhat-rpm-config \
gcc \
make \
findutils \
tar \
gzip \
rsync \
python3 \
python3-devel \
python3-pip \
python3-setuptools \
python3-wheel \
pyproject-rpm-macros \
python3-rpm-macros \
python3-poetry-core \
desktop-file-utils \
python3-requests \
python3-markdown \
python3-pyside6 \
xcb-util-cursor ; \
dnf -y clean all
RUN set -eux; cat > /usr/local/bin/build-rpm <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
SRC="${SRC:-/src}"
WORKROOT="${WORKROOT:-/work}"
OUT="${OUT:-/out}"
DEPS_DIR="${DEPS_DIR:-/deps}"
# Install bouquin-sqlcipher4 from local rpm
# Filter out .src.rpm and debug* subpackages if present.
if [ -d "${DEPS_DIR}" ] && compgen -G "${DEPS_DIR}/*.rpm" > /dev/null; then
mapfile -t rpms < <(ls -1 "${DEPS_DIR}"/*.rpm | grep -vE '(\.src\.rpm$|-(debuginfo|debugsource)-)')
if [ "${#rpms[@]}" -gt 0 ]; then
echo "Installing dependency RPMs from ${DEPS_DIR}:"
printf ' - %s\n' "${rpms[@]}"
dnf -y install "${rpms[@]}"
dnf -y clean all
else
echo "NOTE: Only src/debug RPMs found in ${DEPS_DIR}; nothing installed." >&2
fi
else
echo "NOTE: No RPMs found in ${DEPS_DIR}. If the build fails with missing python3dist(sqlcipher4)," >&2
echo " mount your bouquin-sqlcipher4 RPM directory as -v <dir>:/deps" >&2
fi
mkdir -p "${WORKROOT}" "${OUT}"
WORK="${WORKROOT}/src"
rm -rf "${WORK}"
mkdir -p "${WORK}"
rsync -a --delete \
--exclude '.git' \
--exclude '.venv' \
--exclude 'dist' \
--exclude 'build' \
--exclude '__pycache__' \
--exclude '.pytest_cache' \
--exclude '.mypy_cache' \
"${SRC}/" "${WORK}/"
cd "${WORK}"
# Determine version from pyproject.toml unless provided
if [ -n "${VERSION:-}" ]; then
ver="${VERSION}"
else
ver="$(grep -m1 '^version = ' pyproject.toml | sed -E 's/version = "([^"]+)".*/\1/')"
fi
TOPDIR="${WORKROOT}/rpmbuild"
mkdir -p "${TOPDIR}"/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
tarball="${TOPDIR}/SOURCES/bouquin-${ver}.tar.gz"
tar -czf "${tarball}" --transform "s#^#bouquin/#" .
cp -v "rpm/bouquin.spec" "${TOPDIR}/SPECS/bouquin.spec"
rpmbuild -ba "${TOPDIR}/SPECS/bouquin.spec" \
--define "_topdir ${TOPDIR}" \
--define "upstream_version ${ver}"
shopt -s nullglob
cp -v "${TOPDIR}"/RPMS/*/*.rpm "${OUT}/" || true
cp -v "${TOPDIR}"/SRPMS/*.src.rpm "${OUT}/" || true
echo "Artifacts copied to ${OUT}"
EOF
RUN chmod +x /usr/local/bin/build-rpm
WORKDIR /work
ENTRYPOINT ["/usr/local/bin/build-rpm"]

View file

@ -101,6 +101,25 @@ sudo apt update
sudo apt install bouquin sudo apt install bouquin
``` ```
### Fedora 42
```bash
sudo rpm --import https://mig5.net/static/mig5.asc
sudo tee /etc/yum.repos.d/mig5.repo > /dev/null << 'EOF'
[mig5]
name=mig5 Repository
baseurl=https://rpm.mig5.net/rpm/$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mig5.net/static/mig5.asc
EOF
sudo dnf upgrade --refresh
sudo dnf install bouquin
```
### From PyPi/pip ### From PyPi/pip
* `pip install bouquin` * `pip install bouquin`

2
poetry.lock generated
View file

@ -640,4 +640,4 @@ zstd = ["backports-zstd (>=1.0.0)"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = ">=3.10,<3.14" python-versions = ">=3.10,<3.14"
content-hash = "0241cd7378c45e79da728a23b89defa18f776ada9af1e60f2a19b0d90f3a2c19" content-hash = "0ce61476b8c35f864d395ab3a4ee4645a1ad2e16aa800cba5e77e5bfee23d6a6"

View file

@ -13,8 +13,8 @@ include = ["bouquin/locales/*.json", "bouquin/keys/mig5.asc", "bouquin/fonts/Not
python = ">=3.10,<3.14" python = ">=3.10,<3.14"
pyside6 = ">=6.8.1,<7.0.0" pyside6 = ">=6.8.1,<7.0.0"
bouquin-sqlcipher4 = "^4.12.0" bouquin-sqlcipher4 = "^4.12.0"
requests = "^2.32.5" requests = "^2.32.3"
markdown = "^3.10" markdown = "^3.7"
[tool.poetry.scripts] [tool.poetry.scripts]
bouquin = "bouquin.__main__:main" bouquin = "bouquin.__main__:main"

View file

@ -69,4 +69,28 @@ for dist in ${DISTS[@]}; do
reprepro -b /home/user/git/repo includedeb "${release}" "${debfile}" reprepro -b /home/user/git/repo includedeb "${release}" "${debfile}"
done done
# RPM
sudo apt-get -y install createrepo-c rpm
docker build -f Dockerfile.rpmbuild -t bouquin-rpm:f42 --progress=plain .
docker run --rm -v "$PWD":/src -v "$PWD/dist/rpm":/out -v "$HOME/git/bouquin-sqlcipher4/dist/rpm":/deps:ro bouquin-rpm:f42
REPO_ROOT="${HOME}/git/repo_rpm"
RPM_REPO="${REPO_ROOT}/rpm/x86_64"
BUILD_OUTPUT="${HOME}/git/bouquin/dist"
REMOTE="letessier.mig5.net:/opt/repo_rpm"
KEYID="00AE817C24A10C2540461A9C1D7CDE0234DB458D"
echo "==> Updating RPM repo..."
mkdir -p "$RPM_REPO"
cp "${BUILD_OUTPUT}/rpm/"*.rpm "$RPM_REPO/"
createrepo_c "$RPM_REPO"
echo "==> Signing repomd.xml..."
qubes-gpg-client --local-user "$KEYID" --detach-sign --armor "$RPM_REPO/repodata/repomd.xml" > "$RPM_REPO/repodata/repomd.xml.asc"
echo "==> Syncing repo to server..."
rsync -aHPvz --exclude=.git --delete "$REPO_ROOT/" "$REMOTE/"
echo "Done!"
ssh wolverine.mig5.net "echo ${VERSION} | tee /opt/www/mig5.net/bouquin/version.txt" ssh wolverine.mig5.net "echo ${VERSION} | tee /opt/www/mig5.net/bouquin/version.txt"

86
rpm/bouquin.spec Normal file
View file

@ -0,0 +1,86 @@
# bouquin Fedora 42 RPM spec using Fedora's pyproject RPM macros (Poetry backend).
#
# NOTE: Bouquin depends on "bouquin-sqlcipher4" project, but the RPM actually
# provides the Python distribution/module as "sqlcipher4". To keep Fedora's
# auto-generated python3dist() Requires correct, we rewrite the dependency key in
# pyproject.toml at build time.
%global upstream_version 0.8.0
Name: bouquin
Version: %{upstream_version}
Release: 1%{?dist}.bouquin1
Summary: A simple, opinionated notebook application (Python/Qt/SQLCipher)
License: GPL-3.0-or-later
URL: https://git.mig5.net/mig5/bouquin
Source0: %{name}-%{version}.tar.gz
BuildArch: noarch
BuildRequires: pyproject-rpm-macros
BuildRequires: python3-devel
BuildRequires: python3-poetry-core
BuildRequires: desktop-file-utils
# Non-Python runtime dep (Fedora equivalent of Debian's libxcb-cursor0)
Requires: xcb-util-cursor
# Make sure private repo dependency is pulled in by package name as well.
Requires: python3-sqlcipher4 >= 4.12.0
%description
Bouquin is a simple, opinionated notebook application written in Python and Qt,
storing data using SQLCipher.
%prep
%autosetup -n bouquin
# Patch dependency name so Fedora's python dependency generator targets the
# provider from bouquin-sqlcipher4 RPM (python3dist(sqlcipher4)).
%{python3} - <<'PY'
from pathlib import Path
import re
p = Path("pyproject.toml")
txt = p.read_text(encoding="utf-8")
pattern = re.compile(r'(?ms)(^\[tool\.poetry\.dependencies\]\n.*?)(^\[|\Z)')
m = pattern.search(txt)
if not m:
raise SystemExit("Could not locate [tool.poetry.dependencies] in pyproject.toml")
deps_block = m.group(1)
deps_block2 = re.sub(r'(?m)^bouquin-sqlcipher4\s*=\s*(".*?")\s*$', r'sqlcipher4 = \1', deps_block)
if deps_block == deps_block2:
raise SystemExit("Did not find bouquin-sqlcipher4 dependency to rewrite")
p.write_text(txt[:m.start(1)] + deps_block2 + txt[m.end(1):], encoding="utf-8")
PY
desktop-file-validate debian/bouquin.desktop
%generate_buildrequires
%pyproject_buildrequires
%build
%pyproject_wheel
%install
%pyproject_install
%pyproject_save_files bouquin
# Desktop integration (mirrors debian/bouquin.install)
install -Dpm 0644 debian/bouquin.desktop %{buildroot}%{_datadir}/applications/bouquin.desktop
install -Dpm 0644 bouquin/icons/bouquin.svg %{buildroot}%{_datadir}/icons/hicolor/scalable/apps/bouquin.svg
%files -f %{pyproject_files}
%license LICENSE
%doc README.md CHANGELOG.md
%{_bindir}/bouquin
%{_datadir}/applications/bouquin.desktop
%{_datadir}/icons/hicolor/scalable/apps/bouquin.svg
%changelog
* Wed Dec 24 2025 Miguel Jacq <mig@mig5.net> - %{version}-%{release}
- Initial RPM packaging for Fedora 42