Build everything in one cargo run, and package for the AUR
Four cargo builds with four target directories compiled the GTK and GStreamer bindings four times; one build with a shared target directory takes a package build from about an hour to about seven minutes. Adds the ahfail binary and /etc/pam.d/ahfail to the install, the update_check option, an AUR PKGBUILD (offline build after cargo fetch --locked) and a tag-triggered workflow that publishes it and mirrors the PKGBUILD to the tarballz index. Claude-Session: https://claude.ai/code/session_012LCTmU2ewo8tnM1dByYAoG
This commit is contained in:
@@ -0,0 +1,96 @@
|
|||||||
|
name: Publish to AUR
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
aur:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: archlinux:base-devel
|
||||||
|
steps:
|
||||||
|
- name: Install base tools
|
||||||
|
run: pacman -Syu --noconfirm git openssh pacman-contrib nodejs sudo
|
||||||
|
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Extract version from tag
|
||||||
|
id: version
|
||||||
|
run: |
|
||||||
|
TAG="${GITHUB_REF#refs/tags/v}"
|
||||||
|
echo "version=$TAG" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "Publishing ahfail v$TAG to AUR"
|
||||||
|
|
||||||
|
- name: Configure SSH for AUR
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
echo "${{ secrets.AUR_SSH_PRIVATE_KEY }}" > ~/.ssh/aur
|
||||||
|
chmod 600 ~/.ssh/aur
|
||||||
|
ssh-keyscan -H aur.archlinux.org >> ~/.ssh/known_hosts 2>/dev/null
|
||||||
|
cat > ~/.ssh/config <<'EOF'
|
||||||
|
Host aur.archlinux.org
|
||||||
|
User aur
|
||||||
|
IdentityFile ~/.ssh/aur
|
||||||
|
StrictHostKeyChecking accept-new
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Create unprivileged build user
|
||||||
|
run: |
|
||||||
|
useradd -m builder
|
||||||
|
echo "builder ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
|
||||||
|
mkdir -p /home/builder/.ssh
|
||||||
|
cp -r ~/.ssh/. /home/builder/.ssh/
|
||||||
|
chown -R builder:builder /home/builder/.ssh
|
||||||
|
chmod 600 /home/builder/.ssh/aur
|
||||||
|
|
||||||
|
- name: Clone existing AUR repo (or init new)
|
||||||
|
run: |
|
||||||
|
git clone ssh://aur@aur.archlinux.org/ahfail.git aur-pkg 2>&1 || true
|
||||||
|
if [ ! -d aur-pkg/.git ]; then
|
||||||
|
mkdir -p aur-pkg
|
||||||
|
cd aur-pkg
|
||||||
|
git init -b master
|
||||||
|
git remote add origin ssh://aur@aur.archlinux.org/ahfail.git
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Render PKGBUILD for this release
|
||||||
|
run: |
|
||||||
|
cp packaging/aur/PKGBUILD packaging/aur/ahfail.install aur-pkg/
|
||||||
|
sed -i "s/^pkgver=.*/pkgver=${{ steps.version.outputs.version }}/" aur-pkg/PKGBUILD
|
||||||
|
sed -i "s/^pkgrel=.*/pkgrel=1/" aur-pkg/PKGBUILD
|
||||||
|
|
||||||
|
- name: Update checksums and regenerate .SRCINFO
|
||||||
|
run: |
|
||||||
|
chown -R builder:builder aur-pkg
|
||||||
|
cd aur-pkg
|
||||||
|
sudo -u builder updpkgsums
|
||||||
|
sudo -u builder makepkg --printsrcinfo > .SRCINFO
|
||||||
|
|
||||||
|
- name: Commit and push to AUR
|
||||||
|
run: |
|
||||||
|
cd aur-pkg
|
||||||
|
git config user.name "Asger Geel Weirsoe"
|
||||||
|
git config user.email "asger@weircon.dk"
|
||||||
|
git add PKGBUILD .SRCINFO ahfail.install
|
||||||
|
if git diff --staged --quiet; then
|
||||||
|
echo "No changes — nothing to push."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
git commit -m "Update to ${{ steps.version.outputs.version }}"
|
||||||
|
git push -u origin master
|
||||||
|
|
||||||
|
# Mirror the same PKGBUILD to https://asger.weirsøe.dk/tarballz/, the
|
||||||
|
# human-readable package index. The key is pinned on the web host to a
|
||||||
|
# forced command that can only write this one file, and a failure there
|
||||||
|
# must never turn an otherwise good AUR release red.
|
||||||
|
- name: Publish PKGBUILD to the tarballz index
|
||||||
|
continue-on-error: true
|
||||||
|
env:
|
||||||
|
TARBALLZ_SSH_KEY: ${{ secrets.TARBALLZ_SSH_KEY }}
|
||||||
|
run: |
|
||||||
|
printf '%s\n' "$TARBALLZ_SSH_KEY" > ~/.ssh/tarballz
|
||||||
|
chmod 600 ~/.ssh/tarballz
|
||||||
|
ssh -i ~/.ssh/tarballz -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new \
|
||||||
|
root@192.168.10.148 < aur-pkg/PKGBUILD
|
||||||
+35
-33
@@ -1,12 +1,13 @@
|
|||||||
project(
|
project(
|
||||||
'ahfail',
|
'ahfail',
|
||||||
['c', 'rust'],
|
['c', 'rust'],
|
||||||
version: '0.1.0',
|
version: '0.10.0',
|
||||||
meson_version: '>=1.3.0',
|
meson_version: '>=1.3.0',
|
||||||
default_options: ['warning_level=3', 'c_std=c11']
|
default_options: ['warning_level=3', 'c_std=c11']
|
||||||
)
|
)
|
||||||
|
|
||||||
ahfail_inc = include_directories('include')
|
ahfail_inc = include_directories('include')
|
||||||
|
|
||||||
cc = meson.get_compiler('c')
|
cc = meson.get_compiler('c')
|
||||||
m_dep = cc.find_library('m', required : false)
|
m_dep = cc.find_library('m', required : false)
|
||||||
gtk_dep = dependency('gtk+-3.0')
|
gtk_dep = dependency('gtk+-3.0')
|
||||||
@@ -20,47 +21,48 @@ resources = gnome.compile_resources(
|
|||||||
c_name: 'ahfail'
|
c_name: 'ahfail'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Each cargo target uses its own --target-dir to avoid parallel lock contention.
|
# All Rust artefacts come from ONE cargo invocation with one target directory.
|
||||||
cargo_target = custom_target(
|
# Four separate builds with four target directories compiled the whole GTK and
|
||||||
|
# GStreamer binding stack four times over (about an hour for a package build).
|
||||||
|
#
|
||||||
|
# -Dupdate_check=false (distro packages) builds without the ahfail-ui feature
|
||||||
|
# `update-check`, so the binaries never ask Gitea for new releases and the HTTP
|
||||||
|
# client is not compiled in at all.
|
||||||
|
cargo_features = get_option('update_check') ? '' : '--no-default-features'
|
||||||
|
|
||||||
|
cargo_all = custom_target(
|
||||||
'ahfail-cargo-build',
|
'ahfail-cargo-build',
|
||||||
input: ['crates/ahfail-gtklock/src/lib.rs', 'Cargo.toml'],
|
input: ['Cargo.toml', 'Cargo.lock'],
|
||||||
output: ['libahfail_module.a'],
|
output: ['libahfail_module.a', 'libahfail_pam.so', 'ahfail-display', 'ahfail'],
|
||||||
command: [
|
|
||||||
'sh', '-c', 'cargo build --release -p ahfail-gtklock --target-dir "@OUTDIR@/target-gtklock" && cp "@OUTDIR@/target-gtklock/release/libahfail_module.a" "@OUTPUT@"'
|
|
||||||
],
|
|
||||||
build_by_default: true
|
|
||||||
)
|
|
||||||
|
|
||||||
# PAM module (.so with C ABI — no GResources needed, Cargo self-contained via build.rs)
|
|
||||||
pam_cargo = custom_target(
|
|
||||||
'ahfail-pam-cargo-build',
|
|
||||||
input: ['crates/ahfail-pam/src/lib.rs', 'Cargo.toml'],
|
|
||||||
output: ['libahfail_pam.so'],
|
|
||||||
command: [
|
command: [
|
||||||
'sh', '-c',
|
'sh', '-c',
|
||||||
# Pass the absolute libdir so build.rs emits the correct AHFAIL_INSTALL_DIR.
|
# The PAM module's build.rs needs the absolute libdir to know where
|
||||||
# get_option('libdir') is relative ("lib"); prefix it to get an absolute path.
|
# ahfail-display is installed; get_option('libdir') alone is relative.
|
||||||
'AHFAIL_LIBDIR=' + get_option('prefix') / get_option('libdir') + ' cargo build --release -p ahfail-pam --target-dir "@OUTDIR@/target-pam" && cp "@OUTDIR@/target-pam/release/libahfail_pam.so" "@OUTPUT@"'
|
'AHFAIL_LIBDIR=' + get_option('prefix') / get_option('libdir')
|
||||||
|
+ ' cargo build --release --locked'
|
||||||
|
+ ' -p ahfail-gtklock -p ahfail-pam -p ahfail-display -p ahfail ' + cargo_features
|
||||||
|
+ ' --target-dir "@OUTDIR@/target"'
|
||||||
|
+ ' && cp "@OUTDIR@/target/release/libahfail_module.a" "@OUTPUT0@"'
|
||||||
|
+ ' && cp "@OUTDIR@/target/release/libahfail_pam.so" "@OUTPUT1@"'
|
||||||
|
+ ' && cp "@OUTDIR@/target/release/ahfail-display" "@OUTPUT2@"'
|
||||||
|
+ ' && cp "@OUTDIR@/target/release/ahfail" "@OUTPUT3@"'
|
||||||
],
|
],
|
||||||
build_by_default: true,
|
build_by_default: true,
|
||||||
|
build_always_stale: true, # cargo decides what is out of date, not meson
|
||||||
install: true,
|
install: true,
|
||||||
install_dir: get_option('libdir') / 'ahfail',
|
# module archive: linked below, not installed; PAM module + display binary:
|
||||||
|
# libdir/ahfail; the ahfail command: bindir.
|
||||||
|
install_dir: [false, get_option('libdir') / 'ahfail', get_option('libdir') / 'ahfail', get_option('bindir')],
|
||||||
install_mode: 'rwxr-xr-x'
|
install_mode: 'rwxr-xr-x'
|
||||||
)
|
)
|
||||||
|
cargo_target = cargo_all[0]
|
||||||
|
pam_cargo = cargo_all[1]
|
||||||
|
|
||||||
# Display binary (embeds GResources via its own build.rs using glib-compile-resources)
|
# The locker's own PAM service. Shipped as its own file, like swaylock and
|
||||||
display_cargo = custom_target(
|
# gtklock do, so no other package's PAM configuration is ever touched.
|
||||||
'ahfail-display-cargo-build',
|
install_data('data/pam.d/ahfail',
|
||||||
input: ['crates/ahfail-display/src/main.rs', 'Cargo.toml'],
|
install_dir: get_option('sysconfdir') / 'pam.d',
|
||||||
output: ['ahfail-display'],
|
install_mode: 'rw-r--r--'
|
||||||
command: [
|
|
||||||
'sh', '-c',
|
|
||||||
'cargo build --release -p ahfail-display --target-dir "@OUTDIR@/target-display" && cp "@OUTDIR@/target-display/release/ahfail-display" "@OUTPUT@"'
|
|
||||||
],
|
|
||||||
build_by_default: true,
|
|
||||||
install: true,
|
|
||||||
install_dir: get_option('libdir') / 'ahfail',
|
|
||||||
install_mode: 'rwxr-xr-x'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
libahfail = shared_library(
|
libahfail = shared_library(
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
option('update_check', type: 'boolean', value: true,
|
||||||
|
description: 'Let the binaries check Gitea for new releases. Distro packages set this to false.')
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
# Maintainer: Asger Geel Weirsoe <asger@weircon.dk>
|
||||||
|
pkgname=ahfail
|
||||||
|
pkgver=0.0.0
|
||||||
|
pkgrel=1
|
||||||
|
pkgdesc="Screen locker that says 'ah ah ah, you didn't say the magic word' on a wrong password"
|
||||||
|
arch=('x86_64')
|
||||||
|
url="https://gitea.weircon.dk/agw/gtk-ahfail"
|
||||||
|
license=('AGPL-3.0-only')
|
||||||
|
# gst-plugins-bad-libs: libgstplayer. gst-plugins-base/-good are runtime plugins
|
||||||
|
# (audio conversion, the mpg123 mp3 decoder) that namcap cannot see being used.
|
||||||
|
depends=('gtk3' 'gtk-session-lock' 'gstreamer' 'gst-plugins-bad-libs' 'gst-plugins-base'
|
||||||
|
'gst-plugins-good' 'pam' 'glib2' 'gdk-pixbuf2' 'cairo' 'pango' 'at-spi2-core' 'gst-plugins-base-libs' 'glibc' 'libgcc' 'libx11')
|
||||||
|
makedepends=('meson' 'ninja' 'cargo')
|
||||||
|
optdepends=('pipewire-pulse: raise the volume to 100% on a failed attempt (or libpulse)'
|
||||||
|
'libpulse: raise the volume to 100% on a failed attempt'
|
||||||
|
'swayidle: lock automatically on Wayland'
|
||||||
|
'xss-lock: lock automatically on X11'
|
||||||
|
'gtklock: legacy gtklock module (/usr/lib/gtklock/ahfail-module.so)')
|
||||||
|
backup=('etc/pam.d/ahfail')
|
||||||
|
install=ahfail.install
|
||||||
|
options=('!lto')
|
||||||
|
source=("$pkgname-$pkgver.tar.gz::$url/archive/v$pkgver.tar.gz")
|
||||||
|
sha256sums=('SKIP')
|
||||||
|
|
||||||
|
prepare() {
|
||||||
|
cd "$srcdir/gtk-ahfail"
|
||||||
|
export RUSTUP_TOOLCHAIN=stable
|
||||||
|
cargo fetch --locked --target "$(rustc -vV | sed -n 's/host: //p')"
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
cd "$srcdir/gtk-ahfail"
|
||||||
|
export RUSTUP_TOOLCHAIN=stable
|
||||||
|
export CARGO_NET_OFFLINE=true
|
||||||
|
arch-meson . build -Dupdate_check=false
|
||||||
|
meson compile -C build
|
||||||
|
}
|
||||||
|
|
||||||
|
package() {
|
||||||
|
cd "$srcdir/gtk-ahfail"
|
||||||
|
meson install -C build --destdir "$pkgdir"
|
||||||
|
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
_ahfail_msg() {
|
||||||
|
cat <<'MSG'
|
||||||
|
==> ahfail is its own screen locker and uses its own PAM service (/etc/pam.d/ahfail).
|
||||||
|
Nothing in your other PAM files has been changed.
|
||||||
|
|
||||||
|
Check your setup: ahfail doctor
|
||||||
|
See the effect safely: ahfail test
|
||||||
|
Lock the screen: ahfail
|
||||||
|
|
||||||
|
Lock automatically:
|
||||||
|
Wayland: swayidle -w timeout 300 'ahfail' before-sleep 'ahfail'
|
||||||
|
X11: xss-lock -- ahfail
|
||||||
|
|
||||||
|
The old PAM hook (auth optional .../libahfail_pam.so in e.g. /etc/pam.d/i3lock)
|
||||||
|
is no longer needed with `ahfail`. Remove that line yourself if you added it.
|
||||||
|
MSG
|
||||||
|
}
|
||||||
|
|
||||||
|
post_install() {
|
||||||
|
_ahfail_msg
|
||||||
|
}
|
||||||
|
|
||||||
|
post_upgrade() {
|
||||||
|
# Only when coming from before 0.10.0, when ahfail became its own locker;
|
||||||
|
# repeating the message on every update would just teach people to skip it.
|
||||||
|
if (( $(vercmp "$2" 0.10.0) < 0 )); then
|
||||||
|
_ahfail_msg
|
||||||
|
fi
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user