Build all five G15 packages and add native Gitea push CI
Debian 13 packages / build (push) Failing after 1m20s

This commit is contained in:
Mikhail Yevchenko committed 2026-09-07 16:23:19 +03:00
1 parent 085e5b488f
commit ef5d81fd20
9 files changed
+83 -28

No files matched your search

+34
View File
@@ -0,0 +1,34 @@
name: Debian 13 packages
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: https://github.com/actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
persist-credentials: false
submodules: recursive
- name: Build, test and rebuild all five sources
shell: bash
run: |
set -euo pipefail
for script in packaging/*.sh packaging/overlays/v1/*.sh; do bash -n "$script"; done
mkdir -p "$RUNNER_TEMP/debs"
bash packaging/run.sh "$RUNNER_TEMP/debs"
docker run --rm --mount "type=bind,src=$PWD/packaging,dst=/checks/packaging,readonly" \
-w /checks g15-packaging shellcheck packaging/*.sh packaging/overlays/v1/*.sh
test -z "$(git submodule foreach --quiet --recursive 'git status --porcelain')"
- name: Upload verified binaries and standalone sources
uses: https://github.com/actions/upload-artifact@ff15f0306b3f739f7b6fd43fb5d26cd321bd4de5 # v3 (Gitea artifact protocol)
with:
name: debian13-amd64
path: ${{ runner.temp }}/debs/*
if-no-files-found: error
+3
View File
@@ -1,5 +1,7 @@
name: Debian 13 packages name: Debian 13 packages
on: on:
push:
branches: [main]
pull_request: pull_request:
paths: paths:
- 'packaging/**' - 'packaging/**'
@@ -12,6 +14,7 @@ on:
- 'libg15render' - 'libg15render'
- 'g15daemon' - 'g15daemon'
- 'g15macro' - 'g15macro'
- 'g15stats'
workflow_dispatch: workflow_dispatch:
release: release:
types: [published] types: [published]
+10 -6
View File
@@ -1,8 +1,7 @@
# G15 tools: Debian 13 development and packages # G15 tools: Debian 13 development and packages
This outer repository builds and packages four pinned Git submodules: `libg15`, This outer repository builds and packages five pinned Git submodules: `libg15`,
`libg15render`, `g15daemon`, and `g15macro`. A fifth submodule, `g15stats`, is `libg15render`, `g15daemon`, `g15macro`, and `g15stats`.
present but is not integrated into the build or packaging pipeline.
Initialize a fresh clone with Initialize a fresh clone with
`git submodule update --init --recursive`. Builds reject missing, dirty, or `git submodule update --init --recursive`. Builds reject missing, dirty, or
misaligned submodules; they export committed, unpatched Debian sources and misaligned submodules; they export committed, unpatched Debian sources and
@@ -12,18 +11,23 @@ never modify submodule working trees or refs.
Create an empty directory outside the checkout (for example with `mktemp -d`) Create an empty directory outside the checkout (for example with `mktemp -d`)
and run `bash packaging/run.sh /absolute/path/to/that-directory`. and run `bash packaging/run.sh /absolute/path/to/that-directory`.
The runner uses disposable Debian 13 Docker containers to build all four The runner uses disposable Debian 13 Docker containers to build all five
projects in dependency order, install their own development packages before projects in dependency order, install their own development packages before
downstream builds, test distro replacement, and rebuild all four source packages downstream builds, test distro replacement, and rebuild all five source packages
without the checkout mounted. It mounts only an allowlist of build inputs; without the checkout mounted. It mounts only an allowlist of build inputs;
`.vscode` is not exposed to release build containers. `.vscode` is not exposed to release build containers.
Outputs include eight binary packages, debug symbols, four standalone Debian Outputs include nine binary packages, debug symbols, five standalone Debian
source packages, build metadata, submodule provenance and checksums. See source packages, build metadata, submodule provenance and checksums. See
`packaging/NOTES.md` for versions, overlays, QA and release behavior. The old `packaging/NOTES.md` for versions, overlays, QA and release behavior. The old
outer `git archive` ZIP is not a source distribution: it omits submodule content. outer `git archive` ZIP is not a source distribution: it omits submodule content.
Use the verified Debian source artifacts instead. Use the verified Debian source artifacts instead.
Gitea Actions builds all five projects on pushes to `main` and manual dispatch.
Successful runs provide the `debian13-amd64` artifact, including binaries,
standalone sources and `SHA256SUMS`. An `ubuntu-latest` runner with local Docker
and matching workspace mount paths is required; see `packaging/NOTES.md`.
**Safety limitation:** legacy macro memory/configuration handling has known **Safety limitation:** legacy macro memory/configuration handling has known
preexisting defects. Compatibility overlays do not repair the macro engine. preexisting defects. Compatibility overlays do not repair the macro engine.
Do not run it as root or use untrusted configuration. Build and install tests Do not run it as root or use untrusted configuration. Build and install tests
+1 -1
View File
@@ -2,7 +2,7 @@ FROM debian:trixie-slim
ENV DEBIAN_FRONTEND=noninteractive ENV DEBIAN_FRONTEND=noninteractive
RUN printf 'deb-src http://deb.debian.org/debian trixie main\n' > /etc/apt/sources.list.d/g15-source.list \ RUN printf 'deb-src http://deb.debian.org/debian trixie main\n' > /etc/apt/sources.list.d/g15-source.list \
&& apt-get update \ && apt-get update \
&& apt-get install -y --no-install-recommends build-essential autoconf automake libtool pkg-config debhelper dpkg-dev libusb-1.0-0-dev git ca-certificates fakeroot lintian devscripts dh-sequence-movetousr libfreetype-dev libxtst-dev quilt shellcheck \ && apt-get install -y --no-install-recommends build-essential autoconf automake libtool pkg-config debhelper dpkg-dev libusb-1.0-0-dev git ca-certificates fakeroot lintian devscripts dh-sequence-movetousr libfreetype-dev libxtst-dev libgtop2-dev quilt shellcheck \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
WORKDIR /work WORKDIR /work
CMD ["bash", "packaging/container-build.sh"] CMD ["bash", "packaging/container-build.sh"]
+16 -10
View File
@@ -9,7 +9,7 @@ API keys or `.env` are needed. Build scripts install packages and require a
disposable root container; do not run them in the hardware-enabled devcontainer. disposable root container; do not run them in the hardware-enabled devcontainer.
`G15_BUILD_IMAGE` optionally changes the shared image tag. `G15_BUILD_IMAGE` optionally changes the shared image tag.
`run.sh` builds `packaging/Dockerfile`, mounts only Git metadata, the four `run.sh` builds `packaging/Dockerfile`, mounts only Git metadata, the five
submodules and `packaging/` read-only, then runs build and lifecycle tests. submodules and `packaging/` read-only, then runs build and lifecycle tests.
A second fresh container mounts only artifacts and `rebuild.sh`, proving that A second fresh container mounts only artifacts and `rebuild.sh`, proving that
the source packages do not need this repository. All working sources are in the source packages do not need this repository. All working sources are in
@@ -19,12 +19,12 @@ allowlisted mount layout. No container receives USB, uinput or a Docker socket.
## Sources, patches and versions ## Sources, patches and versions
Order: `libg15`, `libg15render`, `g15daemon`, `g15macro`. Each stage installs Order: `libg15`, `libg15render`, `g15daemon`, `g15macro`, `g15stats`. Each stage installs
its own runtime and development packages before the next stage resolves build its own runtime and development packages before the next stage resolves build
dependencies. The base image does not supply distro G15 development packages. dependencies. The base image does not supply distro G15 development packages.
Each of these four build submodules must match its indexed gitlink and be clean. Each of these five build submodules must match its indexed gitlink and be clean.
The additional `g15stats` submodule is not built, packaged or recorded in package Stats uses its committed modern Debian packaging without an outer overlay;
provenance. Git the image includes its `libgtop2-dev` build dependency. Git
archives export immutable HEADs, not working-tree contents. No checkout, archives export immutable HEADs, not working-tree contents. No checkout,
patching, committing, ref updates or pushing occurs in submodules. patching, committing, ref updates or pushing occurs in submodules.
@@ -52,7 +52,7 @@ The inherited `dh_installsystemd --no-start` remains in force.
Versions use `<upstream>+g15.git<12-character-commit>-1`. Macro's upstream Versions use `<upstream>+g15.git<12-character-commit>-1`. Macro's upstream
version is 1.0.5 (configure.ac), not the historical Debian changelog's 1.0.3. version is 1.0.5 (configure.ac), not the historical Debian changelog's 1.0.3.
Tests require versions above every available trixie candidate, including binNMUs. Tests require versions above every available trixie candidate, including binNMUs.
There is no trixie macro candidate: macro is tested as a fresh installation, There are no trixie macro or stats candidates: both are tested as fresh installations,
not falsely reported as a distro upgrade. Increment the local Debian revision not falsely reported as a distro upgrade. Increment the local Debian revision
when changing overlays for an already-published source commit. Git hashes are when changing overlays for an already-published source commit. Git hashes are
identifiers, not monotonically increasing versions between local releases. identifiers, not monotonically increasing versions between local releases.
@@ -65,9 +65,9 @@ binary reproducibility. Keep complete released artifacts. No signing is performe
## Outputs and gates ## Outputs and gates
Eight packages: `libg15-1`, `libg15-dev`, `libg15render1`, `libg15render-dev`, Nine packages: `libg15-1`, `libg15-dev`, `libg15render1`, `libg15render-dev`,
`g15daemon`, `libg15daemon-client1t64`, `libg15daemon-client-dev`, `g15macro`; `g15daemon`, `libg15daemon-client1t64`, `libg15daemon-client-dev`, `g15macro`, `g15stats`;
plus five debug-symbol packages on amd64. Each of the four sources has a `.dsc`, plus six debug-symbol packages on amd64. Each of the five sources has a `.dsc`,
orig tarball, Debian tarball, `.buildinfo` and `.changes`. `SUBMODULES` records orig tarball, Debian tarball, `.buildinfo` and `.changes`. `SUBMODULES` records
pins and `SHA256SUMS` covers all artifacts. The outer Git ZIP is not a substitute. pins and `SHA256SUMS` covers all artifacts. The outer Git ZIP is not a substitute.
@@ -77,7 +77,13 @@ SONAMEs, executable linking, development headers/linking, t64 fields, service
and udev installation, macro help/version and purge cleanup. Source rebuilds and udev installation, macro help/version and purge cleanup. Source rebuilds
install newly rebuilt dependencies, not binaries from the first build. install newly rebuilt dependencies, not binaries from the first build.
CI uses recursive checkout on relevant PRs, manual dispatch and published Gitea CI (`.gitea/workflows/debian.yml`) builds on every push to `main` and
manual dispatch, using an `ubuntu-latest` runner with local Docker Engine.
The runner must expose the same workspace paths to Docker for read-only mounts.
It uploads `debian13-amd64` artifacts using the Gitea-compatible v3 protocol;
download the artifact from the successful run and check `SHA256SUMS`.
Gitea does not run the GitHub CLI release job or publish release assets.
GitHub CI uses recursive checkout on main pushes, relevant PRs, manual dispatch and published
releases. Build permissions are read-only; a separate write-permission job releases. Build permissions are read-only; a separate write-permission job
downloads the verified artifact and checks checksums before uploading release downloads the verified artifact and checks checksums before uploading release
assets. All actions are commit-pinned. Existing assets are not overwritten. assets. All actions are commit-pinned. Existing assets are not overwritten.
+10 -4
View File
@@ -14,15 +14,15 @@ trap 'rm -rf "$work"' EXIT
export DEB_BUILD_OPTIONS=${DEB_BUILD_OPTIONS:-parallel=2} export DEB_BUILD_OPTIONS=${DEB_BUILD_OPTIONS:-parallel=2}
export DEBFULLNAME='G15 packaging contributors' DEBEMAIL='noreply@example.invalid' export DEBFULLNAME='G15 packaging contributors' DEBEMAIL='noreply@example.invalid'
git config --global --add safe.directory "$root" git config --global --add safe.directory "$root"
for source in libg15 libg15render g15daemon g15macro; do for source in libg15 libg15render g15daemon g15macro g15stats; do
git config --global --add safe.directory "$root/$source" git config --global --add safe.directory "$root/$source"
pin=$(git -C "$root" ls-files --stage -- "$source" | awk '$1 == 160000 {print $2}') pin=$(git -C "$root" ls-files --stage -- "$source" | awk '$1 == 160000 {print $2}')
[[ -n $pin && $(git -C "$root/$source" rev-parse HEAD) == "$pin" ]] [[ -n $pin && $(git -C "$root/$source" rev-parse HEAD) == "$pin" ]]
[[ -z $(git -C "$root/$source" status --porcelain --untracked-files=all) ]] [[ -z $(git -C "$root/$source" status --porcelain --untracked-files=all) ]]
done done
git -C "$root" submodule status --recursive -- libg15 libg15render g15daemon g15macro > "$out/SUBMODULES" git -C "$root" submodule status --recursive -- libg15 libg15render g15daemon g15macro g15stats > "$out/SUBMODULES"
if grep -q '^[+U-]' "$out/SUBMODULES"; then echo 'Submodule pin mismatch or missing module' >&2; exit 1; fi if grep -q '^[+U-]' "$out/SUBMODULES"; then echo 'Submodule pin mismatch or missing module' >&2; exit 1; fi
for source in libg15 libg15render g15daemon g15macro; do for source in libg15 libg15render g15daemon g15macro g15stats; do
mkdir "$work/$source" mkdir "$work/$source"
cd "$work/$source" cd "$work/$source"
sha=$(git -C "$root/$source" rev-parse HEAD) sha=$(git -C "$root/$source" rev-parse HEAD)
@@ -40,7 +40,9 @@ for source in libg15 libg15render g15daemon g15macro; do
tree=$PWD/$source-$upstream tree=$PWD/$source-$upstream
tar --sort=name --mtime="@$SOURCE_DATE_EPOCH" --owner=0 --group=0 --numeric-owner \ tar --sort=name --mtime="@$SOURCE_DATE_EPOCH" --owner=0 --group=0 --numeric-owner \
--exclude="$source-$upstream/debian" -cJf "${source}_${upstream}.orig.tar.xz" "$source-$upstream" --exclude="$source-$upstream/debian" -cJf "${source}_${upstream}.orig.tar.xz" "$source-$upstream"
if [[ $source != g15stats ]]; then
(cd "$tree" && bash "$root/packaging/overlays/v1/apply.sh" "$source" "$root") (cd "$tree" && bash "$root/packaging/overlays/v1/apply.sh" "$source" "$root")
fi
if [[ $source == g15daemon ]]; then if [[ $source == g15daemon ]]; then
mkdir official mkdir official
(cd official && apt-get source --download-only g15daemon=1.9.5.3-14.1 && dpkg-source --skip-patches -x ./*.dsc source) (cd official && apt-get source --download-only g15daemon=1.9.5.3-14.1 && dpkg-source --skip-patches -x ./*.dsc source)
@@ -50,9 +52,13 @@ for source in libg15 libg15render g15daemon g15macro; do
cd "$tree" cd "$tree"
sed -i "s/^Maintainer:.*/Maintainer: $DEBFULLNAME <$DEBEMAIL>/" debian/control sed -i "s/^Maintainer:.*/Maintainer: $DEBFULLNAME <$DEBEMAIL>/" debian/control
dch --newversion "$version" --distribution trixie --force-distribution \ dch --newversion "$version" --distribution trixie --force-distribution \
"Export $source commit $sha; apply documented outer packaging overlay v1." "Export $source commit $sha; see README.local-build for packaging policy."
sed -i "0,/^ -- /s/^ -- .*/ -- $DEBFULLNAME <$DEBEMAIL> $(date -u -R -d "@$SOURCE_DATE_EPOCH")/" debian/changelog sed -i "0,/^ -- /s/^ -- .*/ -- $DEBFULLNAME <$DEBEMAIL> $(date -u -R -d "@$SOURCE_DATE_EPOCH")/" debian/changelog
if [[ $source == g15stats ]]; then
printf '%s\n' 'Uses committed Debian packaging without an outer overlay.' > debian/README.local-build
else
cp "$root/packaging/overlays/v1/README.md" debian/README.local-build cp "$root/packaging/overlays/v1/README.md" debian/README.local-build
fi
apt-get build-dep -y . apt-get build-dep -y .
dpkg-buildpackage -us -uc -sa dpkg-buildpackage -us -uc -sa
cd .. cd ..
+2 -2
View File
@@ -8,7 +8,7 @@ out=$(realpath "${1:?artifact directory}")
work=$(mktemp -d) work=$(mktemp -d)
trap 'rm -rf "$work"' EXIT trap 'rm -rf "$work"' EXIT
export DEB_BUILD_OPTIONS=parallel=2 export DEB_BUILD_OPTIONS=parallel=2
for source in libg15 libg15render g15daemon g15macro; do for source in libg15 libg15render g15daemon g15macro g15stats; do
mkdir "$work/$source" mkdir "$work/$source"
cd "$work/$source" cd "$work/$source"
dsc=("$out/${source}_"*.dsc) dsc=("$out/${source}_"*.dsc)
@@ -20,4 +20,4 @@ for source in libg15 libg15render g15daemon g15macro; do
cd .. cd ..
apt-get install -y ./*.deb apt-get install -y ./*.deb
done done
echo 'PASS: all four source artifacts rebuilt standalone in dependency order.' echo 'PASS: all five source artifacts rebuilt standalone in dependency order.'
+1 -1
View File
@@ -10,7 +10,7 @@ image=${G15_BUILD_IMAGE:-g15-packaging}
docker build -t "$image" -f "$root/packaging/Dockerfile" "$root/packaging" docker build -t "$image" -f "$root/packaging/Dockerfile" "$root/packaging"
# Allowlist mounts: .vscode and other unrelated local files are not exposed. # Allowlist mounts: .vscode and other unrelated local files are not exposed.
mounts=() mounts=()
for path in .git .gitmodules packaging libg15 libg15render g15daemon g15macro; do for path in .git .gitmodules packaging libg15 libg15render g15daemon g15macro g15stats; do
mounts+=(--mount "type=bind,src=$root/$path,dst=/work/$path,readonly") mounts+=(--mount "type=bind,src=$root/$path,dst=/work/$path,readonly")
done done
docker run --rm "${mounts[@]}" --mount "type=bind,src=$out,dst=/out" "$image" docker run --rm "${mounts[@]}" --mount "type=bind,src=$out,dst=/out" "$image"
+6 -4
View File
@@ -6,7 +6,9 @@ export LC_ALL=C
out=$(realpath "${1:?artifact directory required}") out=$(realpath "${1:?artifact directory required}")
cd "$out" cd "$out"
sha256sum -c SHA256SUMS sha256sum -c SHA256SUMS
packages=(libg15-1 libg15-dev libg15render1 libg15render-dev g15daemon libg15daemon-client1t64 libg15daemon-client-dev g15macro) packages=(libg15-1 libg15-dev libg15render1 libg15render-dev g15daemon libg15daemon-client1t64 libg15daemon-client-dev g15macro g15stats)
[[ $(find . -maxdepth 1 -name '*.dsc' | wc -l) == 5 ]]
[[ $(wc -l < SUBMODULES) == 5 ]]
distro=() distro=()
for package in "${packages[@]}"; do for package in "${packages[@]}"; do
files=("${package}"_*.deb) files=("${package}"_*.deb)
@@ -17,8 +19,8 @@ for package in "${packages[@]}"; do
dpkg --compare-versions "$(dpkg-deb -f "${files[0]}" Version)" gt "$candidate" dpkg --compare-versions "$(dpkg-deb -f "${files[0]}" Version)" gt "$candidate"
distro+=("$package=$candidate") distro+=("$package=$candidate")
else else
[[ $package == g15macro ]] || exit 1 [[ $package == g15macro || $package == g15stats ]] || exit 1
echo 'g15macro has no trixie candidate; fresh installation only.' echo "$package has no trixie candidate; fresh installation only."
fi fi
done done
lintian --fail-on error ./*.changes lintian --fail-on error ./*.changes
@@ -43,7 +45,7 @@ smoke() {
files=("${package}"_*.deb) files=("${package}"_*.deb)
[[ $(dpkg-query -W -f='${Version}' "$package") == "$(dpkg-deb -f "${files[0]}" Version)" ]] [[ $(dpkg-query -W -f='${Version}' "$package") == "$(dpkg-deb -f "${files[0]}" Version)" ]]
done done
for binary in /usr/sbin/g15daemon /usr/bin/g15macro; do for binary in /usr/sbin/g15daemon /usr/bin/g15macro /usr/bin/g15stats; do
ldd "$binary" > "$scratch/ldd" ldd "$binary" > "$scratch/ldd"
cat "$scratch/ldd" cat "$scratch/ldd"
if grep -q 'not found' "$scratch/ldd"; then exit 1; fi if grep -q 'not found' "$scratch/ldd"; then exit 1; fi