ci: add an arch tarball with static opencv
This commit is contained in:
1 parent
0a48ba9338
commit
fd8449ea31
4 files changed
+209
-13
No files matched your search
@@ -127,9 +127,47 @@ jobs:
|
|||||||
dist/rpm-signer.asc
|
dist/rpm-signer.asc
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
|
tarball:
|
||||||
|
name: Arch Linux tarball
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
# Built on Arch itself, because the agent only fits the Qt it was built
|
||||||
|
# against. OpenCV is linked in, so no opencv here.
|
||||||
|
container: archlinux:latest
|
||||||
|
steps:
|
||||||
|
- name: Install the build tools
|
||||||
|
run: |
|
||||||
|
pacman -Syu --noconfirm --needed git base-devel cmake pkgconf curl zstd \
|
||||||
|
qt6-base qt6-declarative qt6-wayland layer-shell-qt ki18n \
|
||||||
|
pam systemd-libs gettext scdoc
|
||||||
|
|
||||||
|
- uses: actions/checkout@v7
|
||||||
|
|
||||||
|
- name: Check the tag against the Makefile
|
||||||
|
run: packaging/check-version.sh "${{ github.ref_name }}"
|
||||||
|
|
||||||
|
- run: packaging/build-opencv.sh
|
||||||
|
|
||||||
|
- run: packaging/build-tarball.sh
|
||||||
|
|
||||||
|
- name: Install it and run it
|
||||||
|
run: |
|
||||||
|
tar -xf dist/*.tar.zst --strip-components=1 -C /
|
||||||
|
for f in /usr/lib/face-unlock/* /usr/lib/security/pam_face_unlock.so; do
|
||||||
|
if ldd "$f" | grep 'not found'; then echo "$f is missing a library"; exit 1; fi
|
||||||
|
done
|
||||||
|
/usr/lib/face-unlock/face-unlockd --version
|
||||||
|
useradd -m tester
|
||||||
|
runuser -u tester -- face-unlock --version
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v7
|
||||||
|
with:
|
||||||
|
name: tarball
|
||||||
|
path: dist/*.tar.zst
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
publish:
|
publish:
|
||||||
name: Release and repositories
|
name: Release and repositories
|
||||||
needs: [deb, rpm]
|
needs: [deb, rpm, tarball]
|
||||||
if: startsWith(github.ref, 'refs/tags/v') || inputs.dry_run
|
if: startsWith(github.ref, 'refs/tags/v') || inputs.dry_run
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -152,9 +190,9 @@ jobs:
|
|||||||
gh release create "${{ github.ref_name }}" \
|
gh release create "${{ github.ref_name }}" \
|
||||||
--title "$(.github/release-notes.sh --title "${{ github.ref_name }}")" \
|
--title "$(.github/release-notes.sh --title "${{ github.ref_name }}")" \
|
||||||
--notes-file notes.md \
|
--notes-file notes.md \
|
||||||
incoming/*.deb incoming/*.rpm \
|
incoming/*.deb incoming/*.rpm incoming/*.tar.zst \
|
||||||
|| gh release upload "${{ github.ref_name }}" \
|
|| gh release upload "${{ github.ref_name }}" \
|
||||||
incoming/*.deb incoming/*.rpm --clobber
|
incoming/*.deb incoming/*.rpm incoming/*.tar.zst --clobber
|
||||||
|
|
||||||
- name: Install the repository tools
|
- name: Install the repository tools
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
+21
-10
@@ -8,13 +8,15 @@ description of the layout, and two descriptions drift.
|
|||||||
|---|---|
|
|---|---|
|
||||||
| `deb/control`, `deb/copyright` | metadata for the Debian binary package |
|
| `deb/control`, `deb/copyright` | metadata for the Debian binary package |
|
||||||
| `rpm/face-unlock.spec` | the RPM spec |
|
| `rpm/face-unlock.spec` | the RPM spec |
|
||||||
| `build-deb.sh`, `build-rpm.sh` | build one package into `dist/` |
|
| `build-deb.sh`, `build-rpm.sh`, `build-tarball.sh` | build one package into `dist/` |
|
||||||
|
| `build-opencv.sh` | builds the static OpenCV the Arch tarball links in |
|
||||||
| `check-version.sh` | refuses a tag that disagrees with the Makefile |
|
| `check-version.sh` | refuses a tag that disagrees with the Makefile |
|
||||||
| `publish-repos.sh` | regenerates the APT and RPM repositories |
|
| `publish-repos.sh` | regenerates the APT and RPM repositories |
|
||||||
| `pages/` | the landing page and the `.repo` file served from GitHub Pages |
|
| `pages/` | the landing page and the `.repo` file served from GitHub Pages |
|
||||||
|
|
||||||
The AUR package lives in [Felitendo/PKGBUILDS](https://github.com/Felitendo/PKGBUILDS/tree/main/face-unlock).
|
The AUR packages live in [Felitendo/PKGBUILDS](https://github.com/Felitendo/PKGBUILDS):
|
||||||
Its CI notices a new GitHub release, updates the checksum and pushes to the AUR.
|
`face-unlock` builds from source, `face-unlock-bin` takes the Arch tarball.
|
||||||
|
Its CI notices a new GitHub release, updates the checksums and pushes to the AUR.
|
||||||
|
|
||||||
Unlike the shell-only LoonixTools, this one is compiled. The packages are per
|
Unlike the shell-only LoonixTools, this one is compiled. The packages are per
|
||||||
architecture (amd64 and x86_64), and they need the Qt 6 and KDE Frameworks 6
|
architecture (amd64 and x86_64), and they need the Qt 6 and KDE Frameworks 6
|
||||||
@@ -28,6 +30,13 @@ against. The `.deb` is therefore built twice, in Debian 13 and in Ubuntu 26.04
|
|||||||
gets an APT repository of its own: `deb/trixie` and `deb/resolute`. The RPM is
|
gets an APT repository of its own: `deb/trixie` and `deb/resolute`. The RPM is
|
||||||
built on the current Fedora.
|
built on the current Fedora.
|
||||||
|
|
||||||
|
The Arch tarball (`face-unlock-<version>-arch-x86_64.tar.zst`) is built on Arch,
|
||||||
|
for the same reason. It holds a folder with the `make install` tree. Arch
|
||||||
|
changes the OpenCV soname with every new OpenCV, so OpenCV is linked in
|
||||||
|
statically (`build-opencv.sh`: only the modules the daemon uses, nothing it
|
||||||
|
would load at run time). Qt stays shared, so a new Qt minor version on Arch
|
||||||
|
needs a new release.
|
||||||
|
|
||||||
The two networks (YuNet and SFace, from the OpenCV model zoo) are not in the
|
The two networks (YuNet and SFace, from the OpenCV model zoo) are not in the
|
||||||
repository. `make models` downloads them and checks them against the
|
repository. `make models` downloads them and checks them against the
|
||||||
checksums in the Makefile. The RPM spec and the PKGBUILD list them as sources
|
checksums in the Makefile. The RPM spec and the PKGBUILD list them as sources
|
||||||
@@ -44,9 +53,10 @@ disables the socket.
|
|||||||
```bash
|
```bash
|
||||||
packaging/build-deb.sh # in a Debian 13 container, with the -dev packages from release.yml
|
packaging/build-deb.sh # in a Debian 13 container, with the -dev packages from release.yml
|
||||||
packaging/build-rpm.sh # in a Fedora container, with the -devel packages from the spec
|
packaging/build-rpm.sh # in a Fedora container, with the -devel packages from the spec
|
||||||
|
packaging/build-opencv.sh && packaging/build-tarball.sh # in an Arch container, with the packages from release.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
Both take the version from `make version` unless one is passed as the first
|
All three take the version from `make version` unless one is passed as the first
|
||||||
argument.
|
argument.
|
||||||
|
|
||||||
## Making a release
|
## Making a release
|
||||||
@@ -56,10 +66,11 @@ argument.
|
|||||||
2. Add the release to `CHANGELOG.md`, in the format CLAUDE.md describes.
|
2. Add the release to `CHANGELOG.md`, in the format CLAUDE.md describes.
|
||||||
3. Commit, then `git tag vX.Y.Z && git push --tags`.
|
3. Commit, then `git tag vX.Y.Z && git push --tags`.
|
||||||
|
|
||||||
The `release` workflow builds both packages in a Debian and a Fedora container,
|
The `release` workflow builds the packages in Debian, Ubuntu, Fedora and Arch
|
||||||
refuses the tag if it disagrees with the Makefile or has no changelog entry,
|
containers, refuses the tag if it disagrees with the Makefile or has no
|
||||||
attaches the packages to a GitHub release with the entry as its notes, and adds
|
changelog entry, attaches the packages to a GitHub release with the entry as
|
||||||
them to the APT and RPM repositories on the `gh-pages` branch.
|
its notes, and adds the deb and rpm files to the APT and RPM repositories on
|
||||||
|
the `gh-pages` branch.
|
||||||
|
|
||||||
## Trying the release path first
|
## Trying the release path first
|
||||||
|
|
||||||
@@ -67,7 +78,7 @@ them to the APT and RPM repositories on the `gh-pages` branch.
|
|||||||
gh workflow run release.yml -f dry_run=true
|
gh workflow run release.yml -f dry_run=true
|
||||||
```
|
```
|
||||||
|
|
||||||
Builds both packages, builds both repositories with a key generated on the
|
Builds the packages, builds both repositories with a key generated on the
|
||||||
spot, checks the signatures, and installs the packages back out of the
|
spot, checks the signatures, and installs the packages back out of the
|
||||||
repositories. Nothing is pushed and no release is made.
|
repositories. Nothing is pushed and no release is made.
|
||||||
|
|
||||||
@@ -81,7 +92,7 @@ gpg --armor --export-secret-keys 'face-unlock repository' \
|
|||||||
| gh secret set GPG_PRIVATE_KEY
|
| gh secret set GPG_PRIVATE_KEY
|
||||||
```
|
```
|
||||||
|
|
||||||
Without the secret the workflow still builds both packages and attaches them to
|
Without the secret the workflow still builds the packages and attaches them to
|
||||||
the release; it says so in the log and leaves the repositories alone.
|
the release; it says so in the log and leaves the repositories alone.
|
||||||
|
|
||||||
## Pointing Pages at it, once, in this order
|
## Pointing Pages at it, once, in this order
|
||||||
|
|||||||
Executable
+77
@@ -0,0 +1,77 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Builds the OpenCV the Arch tarball links in, as static libraries.
|
||||||
|
#
|
||||||
|
# Arch moves to a new OpenCV now and then, each with a new soname, and a
|
||||||
|
# daemon linked against the old one then no longer starts. Linked in
|
||||||
|
# statically, the daemon brings its own. Only the modules face-unlock uses are
|
||||||
|
# built, with OpenCV's own copies of zlib, libjpeg and libpng, so nothing is
|
||||||
|
# left to load at run time. The camera is read through V4L2, which OpenCV
|
||||||
|
# talks to directly.
|
||||||
|
#
|
||||||
|
# packaging/build-opencv.sh [PREFIX]
|
||||||
|
#
|
||||||
|
# Installs into PREFIX (build/opencv-static by default) and does nothing when
|
||||||
|
# PREFIX already holds what this script builds. Needs: cmake, a C++ compiler,
|
||||||
|
# curl.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
here="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
prefix="${1:-$here/build/opencv-static}"
|
||||||
|
|
||||||
|
# 4.x, like the deb and the rpm. The static dnn of 5.0.0 does not link
|
||||||
|
# (https://github.com/opencv/opencv/issues/29342).
|
||||||
|
version=4.14.0
|
||||||
|
sha256=ee8fb9b30eb60850431b4656447080e3737b56e45719c92b67f245950609f86e
|
||||||
|
|
||||||
|
# A change to this script is a different build.
|
||||||
|
stamp="$(sha256sum "${BASH_SOURCE[0]}" | cut -d' ' -f1)"
|
||||||
|
if [[ -f $prefix/.stamp && $(<"$prefix/.stamp") == "$stamp" ]]; then
|
||||||
|
echo "$prefix already has this OpenCV"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
# It is emptied before the install, so it has to be one of ours.
|
||||||
|
if [[ -e $prefix && ! -f $prefix/.stamp ]]; then
|
||||||
|
echo "$0: $prefix exists and was not made by this script" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
work="$(mktemp -d)"
|
||||||
|
trap 'rm -rf -- "$work"' EXIT
|
||||||
|
|
||||||
|
curl -fL --retry 3 -o "$work/opencv.tar.gz" \
|
||||||
|
"https://github.com/opencv/opencv/archive/refs/tags/$version.tar.gz"
|
||||||
|
echo "$sha256 $work/opencv.tar.gz" | sha256sum -c --quiet -
|
||||||
|
tar -xzf "$work/opencv.tar.gz" -C "$work"
|
||||||
|
src="$work/opencv-$version"
|
||||||
|
|
||||||
|
# BUILD_LIST adds what the listed modules need (calib3d, features2d, flann).
|
||||||
|
# The rest is switched off because it would be picked up from the system or
|
||||||
|
# downloaded: codecs, video backends, IPP and the other accelerators.
|
||||||
|
cmake -S "$src" -B "$work/build" \
|
||||||
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DCMAKE_INSTALL_PREFIX="$prefix" \
|
||||||
|
-DBUILD_SHARED_LIBS=OFF \
|
||||||
|
-DBUILD_LIST=core,imgproc,imgcodecs,videoio,objdetect,dnn \
|
||||||
|
-DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_EXAMPLES=OFF \
|
||||||
|
-DBUILD_DOCS=OFF -DBUILD_opencv_apps=OFF -DBUILD_JAVA=OFF \
|
||||||
|
-DBUILD_ZLIB=ON -DBUILD_JPEG=ON -DBUILD_PNG=ON -DBUILD_PROTOBUF=ON \
|
||||||
|
-DWITH_V4L=ON \
|
||||||
|
-DWITH_FFMPEG=OFF -DWITH_GSTREAMER=OFF -DWITH_OBSENSOR=OFF \
|
||||||
|
-DWITH_TIFF=OFF -DWITH_WEBP=OFF -DWITH_AVIF=OFF -DWITH_OPENEXR=OFF \
|
||||||
|
-DWITH_OPENJPEG=OFF -DWITH_JASPER=OFF \
|
||||||
|
-DWITH_IPP=OFF -DWITH_ITT=OFF -DWITH_OPENCL=OFF -DWITH_VA=OFF -DWITH_VA_INTEL=OFF \
|
||||||
|
-DWITH_LAPACK=OFF -DWITH_EIGEN=OFF -DWITH_FLATBUFFERS=OFF -DWITH_QUIRC=OFF -DWITH_ADE=OFF
|
||||||
|
cmake --build "$work/build" --parallel "$(nproc)"
|
||||||
|
|
||||||
|
rm -rf -- "$prefix"
|
||||||
|
cmake --install "$work/build"
|
||||||
|
|
||||||
|
# OpenCV installs the licences of the libraries in it, but not its own.
|
||||||
|
mv "$prefix"/share/licenses/opencv* "$prefix/share/licenses/opencv"
|
||||||
|
install -Dm644 "$src/LICENSE" "$prefix/share/licenses/opencv/LICENSE"
|
||||||
|
|
||||||
|
# A picture with a face, for the check that the models load and find one.
|
||||||
|
install -Dm644 "$src/samples/data/messi5.jpg" "$prefix/share/face-unlock-check/face.jpg"
|
||||||
|
echo "$stamp" > "$prefix/.stamp"
|
||||||
Executable
+70
@@ -0,0 +1,70 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Builds the tarball for Arch Linux into dist/. The AUR package
|
||||||
|
# face-unlock-bin is made from it.
|
||||||
|
#
|
||||||
|
# Like the deb and the rpm, it holds what `make install` produced, under a
|
||||||
|
# folder named like the tarball. One thing is different: OpenCV is linked in
|
||||||
|
# statically (packaging/build-opencv.sh), so a new OpenCV on Arch does not
|
||||||
|
# break the daemon. Qt stays shared. The agent uses Qt's private API, so the
|
||||||
|
# tarball fits the Qt that Arch had when it was built.
|
||||||
|
#
|
||||||
|
# Needs: make, cmake, a C++ compiler, the packages check.yml installs (without
|
||||||
|
# opencv), msgfmt (gettext), scdoc, curl, zstd, and the static OpenCV:
|
||||||
|
#
|
||||||
|
# packaging/build-opencv.sh && packaging/build-tarball.sh
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
here="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
version="${1:-$(make -s -C "$here" version)}"
|
||||||
|
opencv="${OPENCV_PREFIX:-$here/build/opencv-static}"
|
||||||
|
name="face-unlock-$version-arch-$(uname -m)"
|
||||||
|
|
||||||
|
for tool in msgfmt scdoc cmake readelf zstd; do
|
||||||
|
command -v "$tool" > /dev/null || { echo "$0: $tool is not installed" >&2; exit 1; }
|
||||||
|
done
|
||||||
|
opencv_dir="$(dirname "$(find "$opencv" -name OpenCVConfig.cmake -print -quit 2>/dev/null)")"
|
||||||
|
[[ $opencv_dir != . ]] || { echo "$0: no OpenCV in $opencv, run packaging/build-opencv.sh first" >&2; exit 1; }
|
||||||
|
|
||||||
|
root="$(mktemp -d)"
|
||||||
|
work="$(mktemp -d)"
|
||||||
|
trap 'rm -rf -- "$root" "$work"' EXIT
|
||||||
|
dest="$root/$name"
|
||||||
|
|
||||||
|
make -C "$here" models
|
||||||
|
make -C "$here" install \
|
||||||
|
DESTDIR="$dest" \
|
||||||
|
PREFIX=/usr \
|
||||||
|
VERSION="$version" \
|
||||||
|
BUILDDIR="$work/build" \
|
||||||
|
PAMDIR=/usr/lib/security \
|
||||||
|
SYSTEMUNITDIR=/usr/lib/systemd/system \
|
||||||
|
USERUNITDIR=/usr/lib/systemd/user \
|
||||||
|
CMAKE_FLAGS="-DOpenCV_DIR=$opencv_dir"
|
||||||
|
|
||||||
|
# The tests, and the models on a real face: the part a smaller OpenCV could
|
||||||
|
# break without anything else noticing.
|
||||||
|
ctest --test-dir "$work/build" --output-on-failure
|
||||||
|
face="$opencv/share/face-unlock-check/face.jpg"
|
||||||
|
"$work/build/test_images" "$dest/usr/share/face-unlock/models" "$face" "$face" | tee "$work/faces"
|
||||||
|
grep -q 'similarity' "$work/faces" || { echo "$0: the models found no face" >&2; exit 1; }
|
||||||
|
|
||||||
|
if readelf -d "$dest/usr/lib/face-unlock/face-unlockd" | grep -q 'libopencv'; then
|
||||||
|
echo "$0: the daemon still loads a shared OpenCV" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# The program is GPL, OpenCV and the libraries in it come with their own
|
||||||
|
# licences, and the copyright file names the models' authors and licences.
|
||||||
|
lic="$dest/usr/share/licenses/face-unlock"
|
||||||
|
install -Dm644 "$here/LICENSE" "$lic/LICENSE"
|
||||||
|
install -Dm644 "$here/packaging/deb/copyright" "$lic/copyright"
|
||||||
|
cp -r "$opencv/share/licenses/opencv" "$lic/opencv"
|
||||||
|
|
||||||
|
mkdir -p "$here/dist"
|
||||||
|
out="$here/dist/$name.tar.zst"
|
||||||
|
tar -C "$root" --owner=0 --group=0 --numeric-owner --sort=name \
|
||||||
|
-I 'zstd -19 -T0' -cf "$out" "$name"
|
||||||
|
|
||||||
|
echo "$out"
|
||||||
Reference in new issue
Block a user