diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..fd7fb47 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,28 @@ +name: check + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +jobs: + check: + name: syntax and shellcheck + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + # The Makefile skips whatever is missing rather than failing, so the + # tools it looks for have to be here or the check checks less than it + # appears to. + - name: Install the tools the Makefile looks for + run: | + sudo apt-get update -qq + sudo apt-get install -y --no-install-recommends \ + shellcheck gettext scdoc + + - run: make check + + - name: Build the catalogs and the man page + run: make build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..66f9a17 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,156 @@ +name: release + +on: + push: + tags: ['v*'] + workflow_dispatch: + +permissions: + contents: write + +jobs: + deb: + name: Debian package + runs-on: ubuntu-latest + container: debian:stable + steps: + - name: Install the build tools + run: | + apt-get update -qq + apt-get install -y --no-install-recommends \ + ca-certificates git make gettext scdoc dpkg-dev + + - uses: actions/checkout@v4 + + - name: Check the tag against the Makefile + run: packaging/check-version.sh "${{ github.ref_name }}" + + - run: packaging/build-deb.sh + + - name: Look inside what was built + run: | + dpkg-deb --info dist/*.deb + dpkg-deb --contents dist/*.deb + + - uses: actions/upload-artifact@v4 + with: + name: deb + path: dist/*.deb + if-no-files-found: error + + rpm: + name: RPM package + runs-on: ubuntu-latest + container: fedora:latest + steps: + - name: Install the build tools + run: | + dnf install -y --setopt=install_weak_deps=False \ + git make gettext scdoc tar rpm-build rpm-sign systemd-rpm-macros + + - uses: actions/checkout@v4 + + - name: Check the tag against the Makefile + run: packaging/check-version.sh "${{ github.ref_name }}" + + - run: packaging/build-rpm.sh + + # Signed here rather than alongside the APT repository, because this is + # the one place with a native rpm-sign. + - name: Sign the package + env: + GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} + run: | + if [ -z "${GPG_PRIVATE_KEY:-}" ]; then + echo "No GPG_PRIVATE_KEY secret; leaving the package unsigned." + exit 0 + fi + printf '%s' "$GPG_PRIVATE_KEY" | gpg --batch --import + keyid="$(gpg --list-secret-keys --with-colons | awk -F: '/^sec:/ { print $5; exit }')" + rpmsign --define "_gpg_name $keyid" --addsign dist/*.rpm + rpm --checksig dist/*.rpm + + - name: Look inside what was built + run: | + rpm -qip dist/*.rpm + rpm -qlp dist/*.rpm + + - uses: actions/upload-artifact@v4 + with: + name: rpm + path: dist/*.rpm + if-no-files-found: error + + publish: + name: Release and repositories + needs: [deb, rpm] + if: startsWith(github.ref, 'refs/tags/v') + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/download-artifact@v4 + with: + path: incoming + merge-multiple: true + + - name: Attach the packages to the release + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release create "${{ github.ref_name }}" \ + --title "${{ github.ref_name }}" \ + --generate-notes \ + incoming/* \ + || gh release upload "${{ github.ref_name }}" incoming/* --clobber + + - name: Install the repository tools + run: | + sudo apt-get update -qq + sudo apt-get install -y --no-install-recommends \ + dpkg-dev apt-utils createrepo-c + + - name: Import the signing key + id: key + env: + GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} + run: | + if [ -z "${GPG_PRIVATE_KEY:-}" ]; then + echo "present=no" >> "$GITHUB_OUTPUT" + echo "::warning::No GPG_PRIVATE_KEY secret - the apt and dnf repositories were not updated. The packages are on the release." + exit 0 + fi + printf '%s' "$GPG_PRIVATE_KEY" | gpg --batch --import + echo "present=yes" >> "$GITHUB_OUTPUT" + + - name: Check out the published repositories + if: steps.key.outputs.present == 'yes' + uses: actions/checkout@v4 + with: + ref: gh-pages + path: pages + continue-on-error: true + + - name: Update the repositories + if: steps.key.outputs.present == 'yes' + run: | + # First release: the branch does not exist yet. + if [ ! -d pages/.git ]; then + rm -rf pages && mkdir pages + git -C pages init -q -b gh-pages + git -C pages remote add origin "https://github.com/${{ github.repository }}.git" + fi + packaging/publish-repos.sh pages incoming + + - name: Push them + if: steps.key.outputs.present == 'yes' + env: + GH_TOKEN: ${{ github.token }} + run: | + cd pages + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add -A + git diff --quiet --cached && { echo "nothing changed"; exit 0; } + git commit -q -m "Publish ${{ github.ref_name }}" + git push "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git" HEAD:gh-pages diff --git a/.gitignore b/.gitignore index 874ad4a..af3e12e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ # build artifacts po/*.mo doc/*.1 + +# packages +dist/ diff --git a/Makefile b/Makefile index bd0ebe5..3e818d1 100644 --- a/Makefile +++ b/Makefile @@ -41,12 +41,18 @@ LIBS := $(wildcard src/lib/*.sh) MSGFMT := $(shell command -v msgfmt 2>/dev/null) SCDOC := $(shell command -v scdoc 2>/dev/null) -.PHONY: all build install uninstall check clean +.PHONY: all build install uninstall check clean version all: build build: $(MOFILES) $(MANPAGE) +# The one place the version is written down, for everything that has to agree +# with it: the packaging scripts, and the release workflow checking that the +# tag it was handed says the same thing. +version: + @echo $(VERSION) + po/%.mo: po/%.po ifdef MSGFMT $(MSGFMT) --check --output-file=$@ $< diff --git a/README.md b/README.md index 75ed7d3..f1107e3 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,9 @@ paru -S middleclick-autoscroll # Arch and its derivatives middleclick-autoscroll enable ``` -There is no package for anything else yet, so elsewhere it is `make && sudo -make install` from a checkout and then the same one command. See -[Building from source](#building-from-source). +For Debian, Ubuntu, Fedora and openSUSE there is a package repository — see +[Installing](#installing) for the three lines that add it. Updates then arrive +with the rest of the system's. That is the whole setup. Nothing else has to be configured, and no file has to be edited. @@ -205,6 +205,51 @@ Run this before uninstalling the package. See `man middleclick-autoscroll` for the details. +## Installing + +**Arch, CachyOS, EndeavourOS, Manjaro** + +```bash +paru -S middleclick-autoscroll +``` + +**Debian, Ubuntu, Linux Mint, Pop!_OS** + +```bash +sudo install -d -m 0755 /etc/apt/keyrings +curl -fsSL https://felitendo.github.io/middleclick-autoscroll/KEY.gpg \ + | sudo gpg --dearmor -o /etc/apt/keyrings/middleclick-autoscroll.gpg +echo "deb [signed-by=/etc/apt/keyrings/middleclick-autoscroll.gpg] https://felitendo.github.io/middleclick-autoscroll/deb ./" \ + | sudo tee /etc/apt/sources.list.d/middleclick-autoscroll.list +sudo apt update && sudo apt install middleclick-autoscroll +``` + +**Fedora, RHEL, CentOS Stream** + +```bash +sudo curl -fsSL -o /etc/yum.repos.d/middleclick-autoscroll.repo \ + https://felitendo.github.io/middleclick-autoscroll/middleclick-autoscroll.repo +sudo dnf install middleclick-autoscroll +``` + +**openSUSE** + +```bash +sudo rpm --import https://felitendo.github.io/middleclick-autoscroll/KEY.gpg +sudo zypper addrepo --gpgcheck --refresh \ + https://felitendo.github.io/middleclick-autoscroll/rpm middleclick-autoscroll +sudo zypper install middleclick-autoscroll +``` + +Then `middleclick-autoscroll enable`, once. Every package is signed, and a new +version arrives with `apt upgrade`, `dnf upgrade` or `zypper up` like anything +else. Anywhere without a package, build it — [from source](#building-from-source) +— or take the `.deb` or the `.rpm` off the +[releases page](https://github.com/Felitendo/middleclick-autoscroll/releases). + +Run `middleclick-autoscroll disable` before removing the package: it puts back +everything that was changed. + ## Distributions Any of them. Nothing here is keyed to a distribution name — what differs is @@ -253,6 +298,11 @@ sudo make PREFIX=/usr/local install `make check` runs `bash -n` and, if installed, `shellcheck` over every script. +The `.deb` and the `.rpm` are built from the same `make install`, by +`packaging/build-deb.sh` and `packaging/build-rpm.sh`. See +[packaging/README.md](packaging/README.md) for how a release is made and how +the repositories are signed. + ## License GPL-3.0-or-later. diff --git a/packaging/README.md b/packaging/README.md new file mode 100644 index 0000000..86febab --- /dev/null +++ b/packaging/README.md @@ -0,0 +1,66 @@ +# Packaging and releases + +The Makefile installs everything; these only wrap what it produced. That is +deliberate — a packaging script that lists the files again is a second +description of the layout, and two descriptions drift. + +| | | +|---|---| +| `deb/control`, `deb/copyright` | metadata for the Debian binary package | +| `rpm/middleclick-autoscroll.spec` | the RPM spec | +| `build-deb.sh`, `build-rpm.sh` | build one package into `dist/` | +| `check-version.sh` | refuses a tag that disagrees with the Makefile | +| `publish-repos.sh` | regenerates the APT and RPM repositories | +| `pages/` | the landing page and the `.repo` file served from GitHub Pages | + +Neither package carries a maintainer script. The units are enabled per user by +the program itself, and there is nothing to do as root at install time. + +## Building one by hand + +```bash +packaging/build-deb.sh # needs dpkg-dev, gettext, scdoc +packaging/build-rpm.sh # needs rpm-build, gettext, scdoc, systemd-rpm-macros +``` + +Both take the version from `make version` unless one is passed as the first +argument. + +## Making a release + +1. Bump `VERSION` in the Makefile. +2. Commit, then `git tag vX.Y.Z && git push --tags`. + +The `release` workflow builds both packages in a Debian and a Fedora container, +refuses the tag if it disagrees with the Makefile, attaches the packages to a +GitHub release, and adds them to the APT and RPM repositories on the `gh-pages` +branch. Nothing else has to be done by hand. + +## Setting up the signing, once + +The repositories are signed, so this needs a key. Make one that exists for +nothing else — not a personal key — and give it no passphrase: it lives as an +encrypted repository secret, and `rpmsign` cannot be handed a passphrase +unattended. + +```bash +gpg --batch --passphrase '' --quick-generate-key \ + 'middleclick-autoscroll repository ' rsa4096 sign never + +gpg --armor --export-secret-keys 'middleclick-autoscroll repository' \ + | gh secret set GPG_PRIVATE_KEY +``` + +Then, in the repository settings, set **Pages** to deploy from a branch and +pick `gh-pages` at the root. The branch is created by the first release that +runs with the key in place. + +Without the secret the workflow still builds both packages and attaches them to +the release; it says so in the log and leaves the repositories alone. + +## What users end up with + +The public key is published as `KEY.gpg` beside the repositories, and the +landing page carries the setup lines for each distribution. After that, a new +version arrives with `apt upgrade`, `dnf upgrade` or `zypper up` like anything +else. diff --git a/packaging/build-deb.sh b/packaging/build-deb.sh new file mode 100755 index 0000000..42437c7 --- /dev/null +++ b/packaging/build-deb.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +# +# Builds the binary package for Debian, Ubuntu and their derivatives into +# dist/. +# +# Everything the package contains comes out of `make install`. This only wraps +# what that produced, so there is exactly one description of where a file goes +# and it is the Makefile - a packaging script that lists the files again is a +# second description, and the two drift. +# +# Needs: make, dpkg-deb, msgfmt (gettext), scdoc. + +set -euo pipefail + +here="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" +version="${1:-$(make -s -C "$here" version)}" +name=middleclick-autoscroll + +# A package without its man page or its translations is not a package this +# should be quietly willing to produce: the Makefile skips both when the tools +# are missing, and the result would look like a successful build. +for tool in msgfmt scdoc dpkg-deb; do + command -v "$tool" > /dev/null || { echo "$0: $tool is not installed" >&2; exit 1; } +done + +root="$(mktemp -d)" +trap 'rm -rf -- "$root"' EXIT + +make -C "$here" install \ + DESTDIR="$root" \ + PREFIX=/usr \ + VERSION="$version" \ + USERUNITDIR=/usr/lib/systemd/user + +install -d "$root/DEBIAN" +sed "s|@VERSION@|$version|g" "$here/packaging/deb/control" > "$root/DEBIAN/control" +install -Dm644 "$here/packaging/deb/copyright" \ + "$root/usr/share/doc/$name/copyright" + +# Relative to the package root, and DEBIAN/ itself is not part of the contents. +# Sorted in the C locale so the file comes out the same whatever the locale of +# the machine that built it. +( cd "$root" && find . -type f ! -path './DEBIAN/*' -printf '%P\0' \ + | LC_ALL=C sort -z | xargs -0 md5sum > DEBIAN/md5sums ) + +mkdir -p "$here/dist" +out="$here/dist/${name}_${version}_all.deb" +dpkg-deb --root-owner-group --build "$root" "$out" > /dev/null + +echo "$out" diff --git a/packaging/build-rpm.sh b/packaging/build-rpm.sh new file mode 100755 index 0000000..82ebf11 --- /dev/null +++ b/packaging/build-rpm.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# +# Builds the binary package for Fedora, RHEL, openSUSE and their derivatives +# into dist/. +# +# The spec takes the version as a macro rather than carrying one of its own, +# for the same reason the Debian control file has a placeholder: the Makefile +# is where the version is written down. +# +# Needs: rpmbuild, make, msgfmt (gettext), scdoc, systemd-rpm-macros. + +set -euo pipefail + +here="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" +version="${1:-$(make -s -C "$here" version)}" +name=middleclick-autoscroll + +command -v rpmbuild > /dev/null || { echo "$0: rpmbuild is not installed" >&2; exit 1; } + +top="$(mktemp -d)" +trap 'rm -rf -- "$top"' EXIT +mkdir -p "$top"/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS} + +# The working tree as it is, not as it was committed: a package built from a +# checkout has to contain what is in that checkout. +tar czf "$top/SOURCES/$name-$version.tar.gz" \ + --transform "s,^\\.,$name-$version," \ + --exclude=./.git --exclude=./dist --exclude=./po/'*.mo' \ + -C "$here" . + +rpmbuild \ + --define "_topdir $top" \ + --define "_version $version" \ + -bb "$here/packaging/rpm/$name.spec" > /dev/null + +mkdir -p "$here/dist" +cp "$top"/RPMS/noarch/*.rpm "$here/dist/" + +ls "$here/dist/$name-$version"*.rpm diff --git a/packaging/check-version.sh b/packaging/check-version.sh new file mode 100755 index 0000000..123b44c --- /dev/null +++ b/packaging/check-version.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# +# Refuses a release whose tag and Makefile disagree. +# +# The version is baked into the program at install time from the Makefile, and +# the packages take theirs from the same place - but the tag is what people see +# and what the release is named after. A tag that says something else produces +# a package called 1.0.4 containing a program that reports 1.0.3, and nothing +# would have complained. +# +# Anything that is not a v-tag - a run started by hand from a branch - is not a +# release and has nothing to check. + +set -euo pipefail + +here="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" +ref="${1:-}" + +case "$ref" in + v[0-9]*) ;; + *) + echo "not a release tag (${ref:-none}) - nothing to check against" + exit 0 + ;; +esac + +tag_version="${ref#v}" +make_version="$(make -s -C "$here" version)" + +if [[ $tag_version != "$make_version" ]]; then + echo "tag $ref says $tag_version, the Makefile says $make_version" >&2 + echo "Bump VERSION in the Makefile to match the tag, or retag." >&2 + exit 1 +fi + +echo "$ref matches the Makefile" diff --git a/packaging/deb/control b/packaging/deb/control new file mode 100644 index 0000000..7a98bf2 --- /dev/null +++ b/packaging/deb/control @@ -0,0 +1,24 @@ +Package: middleclick-autoscroll +Version: @VERSION@ +Section: utils +Priority: optional +Architecture: all +Maintainer: Felitendo +Depends: bash (>= 4.2), coreutils, findutils, grep, sed, mawk | gawk | original-awk +Recommends: gettext-base, systemd, desktop-file-utils +Homepage: https://github.com/Felitendo/middleclick-autoscroll +Description: middle-click autoscroll for Chromium-based applications + Blink - the engine inside Chromium, Electron and CEF - has had Windows-style + autoscroll for years: hold the middle mouse button, move the pointer, the page + scrolls. On Linux it is switched off, because middle click is already taken by + primary-selection paste. + . + This turns it back on for every application on the system that can do it, and + for anything installed later. There is no list of supported applications to + keep up to date: every launcher is examined, the ones running on Chromium + underneath are identified by what they ship rather than by their name, and the + argument goes wherever that particular application will actually read it. + . + Nothing outside the user's home directory is ever written to. Run + "middleclick-autoscroll disable" before removing this package, so that + everything it changed is put back. diff --git a/packaging/deb/copyright b/packaging/deb/copyright new file mode 100644 index 0000000..ed49dd1 --- /dev/null +++ b/packaging/deb/copyright @@ -0,0 +1,20 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: middleclick-autoscroll +Source: https://github.com/Felitendo/middleclick-autoscroll + +Files: * +Copyright: 2026 Felitendo +License: GPL-3+ + +License: GPL-3+ + This program is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + . + This program is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + PARTICULAR PURPOSE. See the GNU General Public License for more details. + . + On Debian systems the full text of the GNU General Public License version 3 can + be found in /usr/share/common-licenses/GPL-3. diff --git a/packaging/pages/index.html b/packaging/pages/index.html new file mode 100644 index 0000000..6ead1f5 --- /dev/null +++ b/packaging/pages/index.html @@ -0,0 +1,115 @@ + + + + + +middleclick-autoscroll + + + + +

middleclick-autoscroll

+

+ Middle-click autoscroll — hold the middle mouse button, move the pointer, the + page scrolls — in every Chromium-based application on the system, and in + anything installed later. +

+ +

+ This page is the package repository. Set it up once and every new version + arrives with the rest of your system updates. The + source and the + documentation are on GitHub. +

+ +

Debian, Ubuntu, Linux Mint, Pop!_OS

+
sudo install -d -m 0755 /etc/apt/keyrings
+curl -fsSL @BASEURL@/KEY.gpg \
+  | sudo gpg --dearmor -o /etc/apt/keyrings/middleclick-autoscroll.gpg
+echo "deb [signed-by=/etc/apt/keyrings/middleclick-autoscroll.gpg] @BASEURL@/deb ./" \
+  | sudo tee /etc/apt/sources.list.d/middleclick-autoscroll.list
+sudo apt update
+sudo apt install middleclick-autoscroll
+ +

Fedora, RHEL, CentOS Stream

+
sudo curl -fsSL -o /etc/yum.repos.d/middleclick-autoscroll.repo \
+  @BASEURL@/middleclick-autoscroll.repo
+sudo dnf install middleclick-autoscroll
+ +

openSUSE

+
sudo rpm --import @BASEURL@/KEY.gpg
+sudo zypper addrepo --gpgcheck --refresh @BASEURL@/rpm middleclick-autoscroll
+sudo zypper install middleclick-autoscroll
+ +

Arch, CachyOS, EndeavourOS, Manjaro

+
paru -S middleclick-autoscroll
+ +

Then, once

+
middleclick-autoscroll enable
+

+ That is the whole setup. Nothing else has to be configured and no file has to + be edited. Run middleclick-autoscroll disable before removing the + package — it puts back everything that was changed. +

+ +
+ GPL-3.0-or-later. Packages are signed; the public key is + KEY.gpg. +
+ + + diff --git a/packaging/pages/middleclick-autoscroll.repo b/packaging/pages/middleclick-autoscroll.repo new file mode 100644 index 0000000..5e742c2 --- /dev/null +++ b/packaging/pages/middleclick-autoscroll.repo @@ -0,0 +1,7 @@ +[middleclick-autoscroll] +name=middleclick-autoscroll +baseurl=@BASEURL@/rpm +enabled=1 +gpgcheck=1 +repo_gpgcheck=1 +gpgkey=@BASEURL@/KEY.gpg diff --git a/packaging/publish-repos.sh b/packaging/publish-repos.sh new file mode 100755 index 0000000..2dfd2fb --- /dev/null +++ b/packaging/publish-repos.sh @@ -0,0 +1,88 @@ +#!/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 +# +# 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" diff --git a/packaging/rpm/middleclick-autoscroll.spec b/packaging/rpm/middleclick-autoscroll.spec new file mode 100644 index 0000000..9733550 --- /dev/null +++ b/packaging/rpm/middleclick-autoscroll.spec @@ -0,0 +1,72 @@ +# Built with `packaging/build-rpm.sh`, which passes the version in rather than +# editing this file: the Makefile is where the version is written down, and two +# places that have to agree are one place too many. +%global upstream_version %{?_version}%{!?_version:1.0.3} + +Name: middleclick-autoscroll +Version: %{upstream_version} +Release: 1%{?dist} +Summary: Middle-click autoscroll for Chromium-based applications + +License: GPL-3.0-or-later +URL: https://github.com/Felitendo/middleclick-autoscroll +Source0: %{name}-%{version}.tar.gz + +BuildArch: noarch +BuildRequires: make +BuildRequires: gettext +BuildRequires: scdoc +# For %{_userunitdir}, which is where the watcher's user units belong. +BuildRequires: systemd-rpm-macros + +Requires: bash >= 4.2 +Requires: coreutils +Requires: findutils +Requires: grep +Requires: sed +Requires: gawk + +# The interface falls back to English without gettext and picks up new +# applications at the next `apply` without systemd, so neither is required. +Recommends: /usr/bin/gettext +Recommends: systemd +Recommends: desktop-file-utils + +%description +Blink - the engine inside Chromium, Electron and CEF - has had Windows-style +autoscroll for years: hold the middle mouse button, move the pointer, the page +scrolls. On Linux it is switched off, because middle click is already taken by +primary-selection paste. + +This turns it back on for every application on the system that can do it, and +for anything installed later. There is no list of supported applications to keep +up to date: every launcher is examined, the ones running on Chromium underneath +are identified by what they ship rather than by their name, and the argument goes +wherever that particular application will actually read it. + +Nothing outside the user's home directory is ever written to. Run +"middleclick-autoscroll disable" before removing this package, so that everything +it changed is put back. + +%prep +%autosetup -n %{name}-%{version} + +%build +%make_build VERSION=%{upstream_version} + +%install +%make_install PREFIX=%{_prefix} VERSION=%{upstream_version} \ + USERUNITDIR=%{_userunitdir} + +%find_lang %{name} + +%files -f %{name}.lang +%license LICENSE +%doc %{_datadir}/doc/%{name}/README.md +%{_bindir}/%{name} +%{_datadir}/%{name}/ +%{_userunitdir}/%{name}.path +%{_userunitdir}/%{name}.service +%{_mandir}/man1/%{name}.1* + +%changelog