Files
middleclick-autoscroll/packaging/publish-repos.sh
T
Felitendo a053b4e555 feat: packages and a signed repository for Debian and Fedora
The code works on those distributions now; there was still nothing to
install. This adds the two packages and, more to the point, somewhere for
them to live that hands out updates - a package a user has to notice a new
version of and download again is not much better than a checkout.

Both are built from `make install` and nothing else. A packaging script that
lists the installed files a second time is a second description of the
layout, and the two drift the first time a file moves; here the Makefile
stays the only place that says where anything goes. The .deb is staged and
wrapped with dpkg-deb, the .rpm goes through a spec whose %install is the
same make invocation. Both are architecture-independent, so one file each
covers Debian, Ubuntu and their derivatives on one side and Fedora, RHEL and
openSUSE on the other.

The version is not written down twice either. The Makefile has it, the
control file and the spec take it as a placeholder, and check-version.sh
refuses a tag that disagrees - otherwise a v1.0.4 release quietly ships a
program that reports 1.0.3.

The release workflow builds both in a Debian and a Fedora container, signs
the RPM where there is a native rpm-sign, attaches both to the GitHub
release, and then adds them to an APT and a DNF repository on gh-pages,
regenerating the indexes over every version ever published so that pinning
and going back to one still work. Missing the signing key is not an error:
it builds, it says in the log that the repositories were left alone, and the
packages are still on the release.

There is also a check workflow, which is the first time shellcheck actually
runs on this.

Neither package carries a maintainer script. The units are enabled per user
by the program itself, so there is nothing for a package to do as root - and
nothing it could do about the changes in a user's home either, which is why
both descriptions say to run `disable` before removing.

packaging/README.md has the two things that cannot be automated: making the
signing key, and pointing Pages at the branch.
2026-08-24 10:40:15 +02:00

89 lines
3.4 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Puts the packages that were just built into the APT and RPM repositories on
# the gh-pages branch, and regenerates the indexes over everything that is
# there.
#
# Old versions are kept rather than replaced. An index built over all of them
# is what lets somebody pin a version or go back to one, and it costs a few
# hundred kilobytes.
#
# Usage: publish-repos.sh <gh-pages checkout> <directory of new packages>
#
# Needs: dpkg-dev, apt-utils, createrepo-c, gpg, and a secret key already
# imported - its id is taken from the keyring.
set -euo pipefail
pages="$(cd -- "$1" && pwd)"
incoming="$(cd -- "$2" && pwd)"
here="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
base_url="${MCA_REPO_URL:-https://felitendo.github.io/middleclick-autoscroll}"
keyid="$(gpg --list-secret-keys --with-colons | awk -F: '/^sec:/ { print $5; exit }')"
[[ -n $keyid ]] || { echo "$0: no secret key in the keyring" >&2; exit 1; }
mkdir -p "$pages/deb" "$pages/rpm"
cp -- "$incoming"/*.deb "$pages/deb/"
cp -- "$incoming"/*.rpm "$pages/rpm/"
# ---------------------------------------------------------------------------
# APT
# ---------------------------------------------------------------------------
# A flat repository: the packages and their index sit in one directory and the
# sources line ends in "./". There is one distribution here and it is the same
# package for all of them, so the suite and component machinery of a pool
# layout would describe nothing.
(
cd "$pages/deb"
# The old index must be gone before the new one is written: apt-ftparchive
# hashes every file in the directory, and a Release that hashes the
# previous Release is a Release that cannot be verified.
rm -f Packages Packages.gz Release Release.gpg InRelease
dpkg-scanpackages --multiversion . > Packages
gzip -9kf Packages
apt-ftparchive \
-o APT::FTPArchive::Release::Origin=middleclick-autoscroll \
-o APT::FTPArchive::Release::Label=middleclick-autoscroll \
-o APT::FTPArchive::Release::Suite=stable \
-o APT::FTPArchive::Release::Codename=stable \
-o APT::FTPArchive::Release::Architectures=all \
-o APT::FTPArchive::Release::Components=main \
release . > Release
# Both signatures: InRelease is what current apt fetches, Release.gpg is
# what an older one falls back to.
gpg --batch --yes --local-user "$keyid" --clearsign --output InRelease Release
gpg --batch --yes --local-user "$keyid" --detach-sign --armor --output Release.gpg Release
)
# ---------------------------------------------------------------------------
# RPM
# ---------------------------------------------------------------------------
(
cd "$pages/rpm"
createrepo_c --quiet --update .
rm -f repodata/repomd.xml.asc
gpg --batch --yes --local-user "$keyid" --detach-sign --armor repodata/repomd.xml
)
# ---------------------------------------------------------------------------
# The key and the landing page
# ---------------------------------------------------------------------------
gpg --armor --export "$keyid" > "$pages/KEY.gpg"
sed "s|@BASEURL@|$base_url|g" "$here/packaging/pages/index.html" > "$pages/index.html"
sed "s|@BASEURL@|$base_url|g" "$here/packaging/pages/middleclick-autoscroll.repo" \
> "$pages/middleclick-autoscroll.repo"
# Pages would otherwise hand the whole directory to Jekyll, which drops every
# file whose name starts with an underscore and can rewrite the rest.
touch "$pages/.nojekyll"
echo "signed with $keyid"
ls -1 "$pages/deb" "$pages/rpm"