The snapshot component is date plus the number of commits since version.txt
last changed, so every build of the same tip on the same day produces the same
version string. The repo operator reports 96% of version+dist pairs published
more than once, and 1.39.34~20260912.22-bookworm1 uploaded six times in about
half an hour, each upload overwriting the last with different bytes.
Nothing on the repo server can close that. Reindexing shrinks the window but a
client that read Packages before a republish and fetched the .deb after it still
gets a hash mismatch, because the version no longer identifies the content.
Append GITHUB_RUN_ID and GITHUB_RUN_ATTEMPT, which are unique per build and
never reused. Outside Actions the string is unchanged, so a local build still
produces the version it always did.
Checked that the longer string still sorts after the versions already published
and before the next version.txt bump, with dpkg --compare-versions and
rpm.vercmp.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UkQwahn9pi1y4wJe9BTxjM
The upload target in do_debian_package.sh still pointed at
zmrepo.connortechnology.com. ZoneMinder infrastructure should live under
zoneminder.com, so the hostname no longer implies the repo is one person's
personal box.
zmrepo.zoneminder.com already resolves to the same host (158.69.226.113), so
this is a rename in front of unchanged infrastructure. Nothing moves and no
existing client configuration breaks.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The amd64 and aarch64 deb workflows build the same distro matrix, so both
produced zoneminder-doc_<version>_all.deb and uploaded it to the same
mini-dinstall incoming directory at the same time, racing each other and
offering mini-dinstall the same file twice.
Add a binary-arch build type to do_debian_package.sh that runs debuild -B,
and use it from the aarch64 workflow. The arm .changes then references only
arm64 packages and the arch-independent debs come from amd64 alone.
Every CI runner is 64bit, so nothing in CI exercised the 32bit SharedData
layout that zmc/zma/zms, ZoneMinder::Memory and web/includes/Monitor.php
all have to agree on. The i386 alignment divergence that broke the 32bit
build was only caught downstream.
utils/check-shareddata-abi.py lifts the struct body and its static_asserts
out of zm_monitor.h, compiles them standalone at -m32 and -m64, and
requires the size and every member offset to match. Compiling only the
struct avoids needing a 32bit copy of the ffmpeg, mysql and curl headers;
gcc-multilib alone is enough and the check takes about a second, so it
runs before the build rather than after it.
The expected size is never duplicated in the script. It comes from the
assertions in the header, so there is one source of truth and the script
cannot drift from it. Removing the assertions is itself reported as a
failure, since deleting the guard is the tempting way to silence a 32bit
build error.
Verified by reverting the epadding members, which reproduces the original
downstream failure (880 == 888) and additionally names capture_fps,
startup_time and control_state, and by deleting the assertions, which is
reported as a missing guard.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Add fedora:44 to the build matrix in build-rpm-packages.yml and
build-rpm-packages-aarch64.yml, and to the DISTROS list in
utils/zmrepo_mkdirs.sh so the repo tree gets an rpm/master/fedora/44
directory for the deploy rsync.
Fall back to rpmfusion-free-release-rawhide.noarch.rpm in the x86_64
workflow when the versioned release RPM is missing, matching what the
aarch64 workflow already does. Fedora 44 is rawhide, so
rpmfusion-free-release-44.noarch.rpm does not exist yet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NZhAPb2indRrLWSEJ87kf8
The initial utils/check-homoglyphs.py expressed the Cyrillic/Greek ranges as
literal characters in its regex and used a literal Cyrillic C in an example
string, so the script flagged itself and CI Homoglyphs failed on master.
Express the character-class bounds with \u escapes and describe the example by
codepoint only, keeping the file pure ASCII while matching the same ranges.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KQipwf632JGgNH4W7p8cqs
Cyrillic/Greek characters that look like ASCII letters keep landing in the
tree from pasted contributions (discussions #4993, #4678, PR #4678), breaking
lookups and getting corrupted by reverse proxies. utils/check-homoglyphs.py
scans the git-tracked source for characters in the Cyrillic (U+0400-U+04FF)
and Greek (U+0370-U+03FF) blocks and exits non-zero on any hit, excluding
translations (web/lang/) and vendored/minified assets where they are
legitimate. A CI Homoglyphs workflow runs it on push and pull request, and it
can be run locally with python3 utils/check-homoglyphs.py.
refs https://github.com/ZoneMinder/zoneminder/discussions/4993
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KQipwf632JGgNH4W7p8cqs
The build-rpm-packages workflows deploy with easingthemes/ssh-deploy using
rsync args -rltgoDzvO, which does not create missing parent directories on
the remote. When the zmrepo directory tree was deleted the deploy step
failed.
--mkpath is not a viable fix: it is parsed by the local rsync in the build
container, and Rocky 8 ships rsync 3.1.3 which predates the flag (3.2.3+).
Add a pre-deploy step that creates rpm/master/<family>/<releasever>/<arch>/
over ssh with mkdir -p, which has no rsync version dependency. Also add
utils/zmrepo_mkdirs.sh to recreate the full tree manually.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two changes that together stop the .orig.tar.gz from landing in
mini-dinstall's incoming dir and causing cross-distro filename
collisions:
- do_debian_package.sh: quote DEBUILD assignment so the -b flag is
actually passed to debuild. Without quotes, bash parsed it as
"run -b with DEBUILD=debuild as one-shot env", dropping the binary
flag and falling back to a full source build that included the orig
tarball in .changes.
- build-deb-packages{,-aarch64}.yml: drop *.dsc, *.tar.xz, *.tar.gz
from the artifact collection mv. Only .deb, .buildinfo, and .changes
are needed for binary uploads.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Allow specifying a local git directory to clone from without pulling it
first. Accepts -l=DIR / --local-source=DIR flag or a trailing positional
argument that is an existing directory. Skips all git pull operations on
the source, using the directory contents as-is.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>