Skip to content

Fix lintian and rpmlint findings in built packages - #41

Merged
tillkruss merged 13 commits into
mainfrom
lintian-packaging-fixes
Jul 28, 2026
Merged

Fix lintian and rpmlint findings in built packages#41
tillkruss merged 13 commits into
mainfrom
lintian-packaging-fixes

Conversation

@tillkruss

Copy link
Copy Markdown
Member

Adds a proper changelog (closes #4) and clears the packaging-metadata findings reported by lintian 2.122 and rpmlint.

Verified empirically: built one package from every family (deb base/multi/ls, rpm single/multi/ls) at v0.40.0 with the current scripts, applied these changes, rebuilt, and diffed linter output.

8 tags cleared, 0 regressions.

Tag Format Occurrences
extended-description-is-empty deb 330
description-synopsis-starts-with-article deb 330
synopsis-is-a-sentence deb 330
no-copyright-file deb 330
syntax-error-in-debian-changelog deb 330
summary-ended-with-dot rpm 126
no-documentation rpm 126
useless-provides rpm 126

(Counts are per release across the full 330 deb + 126 rpm matrix.)

Changes

Changelog (#4)build/changelog.sh renders both formats from the cachewerk/relay releases feed. The formats differ and deb entries embed the binary package name, so the deb side is a template with @PKG@ substituted per package. Bullets are re-wrapped to 76 columns, or the release notes trip debian-changelog-line-too-long. Releases newer than the tag being built are dropped, and the script fails if the tag has no published release rather than emitting a changelog for the wrong version.

Rendered on the runner, not in the container — the fpm image has no jq or python3, so this needs no image rebuild. Both repos are public, so GITHUB_TOKEN is enough.

Description — real extended description; synopsis no longer starts with an article or ends with a period. Two traps worth knowing about:

  • The variable must not be named pkg_*. main() runs unset ${!pkg_@} before every package, which silently blanks it and turns a warning into description-synopsis-is-empty.
  • No apostrophes. args is flattened and re-evaluated via bash -c "fpm $args …", so a ' anywhere in a value is a build-breaking syntax error.

Copyright — ships /usr/share/doc/<pkg>/copyright from the tarball's LICENSE, prefixed with a copyright notice (the bare EULA has none, which trips copyright-without-copyright-notice). The year derives from the binary mtime so the file stays reproducible.

useless-provides — all nine rpm configs set --provides to the package's own name, which rpm already provides implicitly. Confirmed with rpm -qp --provides.

Deliberately not fixed

  • conffile tags (non-etc-file-marked-as-conffile, file-in-usr-marked-as-conffile) — looks like an easy win, but I tested an actual upgrade: install, edit the ini, upgrade. dpkg preserves the edit; conffiles outside /etc work fine. Dropping --config-files would silence the tag and start overwriting user config on every upgrade.
  • invalid-license — cannot be cleared without misstating the license. rpmlint validates against Fedora's approved-license allowlist; both Proprietary and LicenseRef-Proprietary are rejected by 2.6.1. The only accepted near-match, "Redistributable, no modification permitted", would assert redistribution rights the EULA does not grant.
  • usr/local / opt paths — required by LiteSpeed and remi.
  • non-coherent-filenamerepos.yml routes artifacts by matching *el7*/*el8*/*el9* in the filename.
  • package-contains-timestamped-gzip — inherent to --source-date-epoch-default.
  • unknown-field License/Vendor — fpm always emits these into deb control.
  • unstripped-binary-or-object, hardening-no-bindnow, exit-in-shared-library — properties of the prebuilt binary, not this repo.

Unrelated upstream finding

relay.so contains the misspelling certifcate (→ certificate), flagged by lintian's binary spellchecker. Worth a separate issue against cachewerk/relay.

Testing

No CI covers package contents, so this was verified by hand:

docker run --rm -v $PWD/build:/root/build fpm-local /bin/bash -c "cd /root/build && ./fpm.sh v0.40.0"
lintian --display-info --display-experimental --pedantic build/dist/*.deb
rpmlint build/dist/*.rpm

The first Build packages run on this branch is the real check — the changelog step is new and has not run in Actions.

🤖 Generated with Claude Code

https://claude.ai/code/session_015PwyVggCYKS72z4uS36A2D

Adds a real changelog (closes #4) and clears the packaging metadata
findings reported by lintian 2.122 and rpmlint. Verified by building one
package from every family (deb base/multi/ls, rpm single/multi/ls) at
v0.40.0 and diffing linter output before and after: 8 tags cleared, no
regressions.

- Render deb and rpm changelogs from the cachewerk/relay releases feed.
  The two formats differ and deb entries embed the binary package name,
  so the deb side is a template substituted per package. Bullets are
  re-wrapped to 76 columns to avoid debian-changelog-line-too-long, and
  releases newer than the tag being built are dropped.

- Give packages a real extended description. The synopsis no longer
  starts with an article or ends with a period.

- Ship /usr/share/doc/<pkg>/copyright built from the tarball LICENSE,
  prefixed with a copyright notice. The year comes from the binary mtime
  so the file stays reproducible.

- Drop --provides from the rpm configs. Every one of them set it to the
  package's own name, which rpm already provides implicitly.

Clears: extended-description-is-empty, no-copyright-file,
synopsis-is-a-sentence, description-synopsis-starts-with-article,
syntax-error-in-debian-changelog, useless-provides, no-documentation,
summary-ended-with-dot.

Left alone: the usr/local and opt paths are required by LiteSpeed and
remi; the conffile tags are a policy preference, and dropping
--config-files would overwrite user config on upgrade; invalid-license
cannot be cleared without misstating a proprietary license.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015PwyVggCYKS72z4uS36A2D
Copilot AI review requested due to automatic review settings July 28, 2026 18:38

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses packaging-metadata linter findings (lintian/rpmlint) by improving generated package metadata and introducing autogenerated changelogs derived from upstream GitHub releases.

Changes:

  • Remove redundant RPM --provides values by dropping pkg_provides from all RPM config variants.
  • Add richer package description text and ship /usr/share/doc/<pkg>/copyright from the upstream LICENSE content.
  • Introduce build/changelog.sh and a GitHub Actions step to render Debian/RPM changelogs from the cachewerk/relay releases feed.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
build/src/rpm/config.single.el7.sh Remove redundant pkg_provides in RPM single build (el7).
build/src/rpm/config.single.el8.sh Remove redundant pkg_provides in RPM single build (el8).
build/src/rpm/config.single.el9.sh Remove redundant pkg_provides in RPM single build (el9).
build/src/rpm/config.multi.el7.sh Remove redundant pkg_provides in RPM multi build (el7).
build/src/rpm/config.multi.el8.sh Remove redundant pkg_provides in RPM multi build (el8).
build/src/rpm/config.multi.el9.sh Remove redundant pkg_provides in RPM multi build (el9).
build/src/rpm/config.ls.el7.sh Remove redundant pkg_provides in RPM LiteSpeed build (el7).
build/src/rpm/config.ls.el8.sh Remove redundant pkg_provides in RPM LiteSpeed build (el8).
build/src/rpm/config.ls.el9.sh Remove redundant pkg_provides in RPM LiteSpeed build (el9).
build/helpers.sh Add extended description, copyright/doc generation, and pass generated changelog paths into fpm.
build/changelog.sh New script to render Debian/RPM changelogs from GitHub releases JSON.
.github/workflows/package.yml Add runner-side changelog rendering step before containerized packaging run.
.gitignore Ignore generated changelog artifacts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread build/helpers.sh Outdated
Comment on lines +109 to +115
# changelogs: deb entries embed the binary package name, rpm entries do not
if [[ "$type" == "deb" ]]; then
sed "s/@PKG@/$pkg_name/g" /root/build/changelog.deb.tpl > /tmp/changelog-$pkg_name.deb
args+=("--deb-changelog /tmp/changelog-$pkg_name.deb")
else
args+=("--rpm-changelog /root/build/changelog.rpm")
fi
Comment thread build/changelog.sh Outdated
- Omit `Vendor` from debs. It is a real rpm tag but not a valid Debian
  control field. fpm guards the deb line with `!vendor.empty?`, so an
  explicit empty value drops it; rpm keeps the vendor. The same trick does
  not work on `License` -- that line is emitted unconditionally, so an empty
  value would add `empty-field` on top of the existing `unknown-field`.

- Describe php-relay as a metapackage. It ships no files of its own, and the
  word "metapackage" is what tells lintian to skip its empty-package and
  arch-dependent-files checks. Avoids needing `Architecture: all`, which
  would break the arch suffix rename in deb-repo.sh.

- Stamp packages with the release date instead of the binary mtime. fpm
  stamps the gzipped changelog with the source date epoch, and lintian flags
  the package when that is newer than the newest changelog entry. On v0.40.0
  the binary mtime was 206s later than the release, so every deb tripped it.

Clears: unknown-field (Vendor), empty-binary-package,
package-contains-no-arch-dependent-files, package-contains-timestamped-gzip.

Cumulative with the previous commit: 12 tags, no regressions, verified by
building one package from every family and diffing linter output.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015PwyVggCYKS72z4uS36A2D
Copilot AI review requested due to automatic review settings July 28, 2026 19:36
@tillkruss

Copy link
Copy Markdown
Member Author

Pushed c7e6de3 with three more fixes found by a deeper pass. Cumulative: 12 tags cleared, still zero regressions.

Tag Format Occurrences
unknown-field (Vendor) deb 330
package-contains-timestamped-gzip deb 330
empty-binary-package deb 22
package-contains-no-arch-dependent-files deb 22

Vendor — a real rpm tag but not a valid Debian control field. fpm guards the deb line with !vendor.empty?, so --vendor '' drops it; rpm keeps it. Explicit empty is required, since omitting the flag leaves fpm's default Vendor: none. The same trick does not work on License — that line is emitted unconditionally, so an empty value adds empty-field on top of the existing unknown-field, turning 1 warning into 2.

php-relay as a metapackage — it ships no files of its own. The literal word "metapackage" is what trips lintian's is_meta_package predicate, which gates both the empty-package and arch-dependent-files checks. So a description change clears both, and Architecture: all isn't needed — which is fortunate, because it would have broken the -amd64_amd64 rename in deb-repo.sh:17-22.

package-contains-timestamped-gzip — I originally wrote this off as inherent to reproducible builds. It isn't. fpm stamps the gzipped changelog with the source date epoch, and lintian only fires when that is newer than the newest changelog entry. helpers.sh was using the tarball's relay.so mtime, which on v0.40.0 is 206s later than the release (1785260475 vs 1785260269) — so all 330 debs tripped it. Now both come from the release date, which also makes mtimes uniform across the matrix instead of varying per tarball.

Still outstanding

unstripped-binary-or-object is the largest remaining item — 196 occurrences (28 deb E: + 168 rpm W:) and roughly a 54% size reduction. It's deliberately not in this PR: stripping a proprietary binary is a call for the Relay team, not a packaging decision. If wanted, it needs strip -R .comment (plain strip just trades the tag for binary-has-unneeded-section) and binutils-multiarch in fpm.Dockerfile, or cross-stripping aarch64 fails and set -e aborts the matrix.

The rest are structural and correctly left alone: usr/local/opt paths, the conffile tags, unknown-field License, non-coherent-filename, and the upstream binary properties.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

build/helpers.sh:73

  • fpm_build() now hard-depends on /root/build/changelog.epoch (and the rendered changelog files) but there’s no guard, so local runs will fail with a non-obvious cat/sed error if the new Render changelogs step wasn’t executed. Add an explicit check with a clear error message before first use.
  # Debian policy requires /usr/share/doc/<pkg>/copyright; rpm wants documentation.
  # The year comes from the release date so the file stays reproducible.
  mkdir -p $dest_path/usr/share/doc/$pkg_name
  {
    echo "Copyright (C) 2021-$(date -u -d @$(cat /root/build/changelog.epoch) +%Y) CacheWerk, Inc."

build/helpers.sh:91

  • args always includes a default --description, but build/src/deb/config.base.sh now adds its own --description (metapackage wording). Passing --description twice relies on fpm’s option parsing order; it’s safer to only add the default description when the per-package config did not already provide one.

    "--maintainer 'Relay Team <hello@cachewerk.com>'"
    "--description '$relay_description'"
    "--url 'https://relay.so'"

Closes #1, closes #3. Also closes #2, which tracked the same removal and
upgrade correctness as #1.

after-remove-multi.sh is the counterpart to after-install-multi.sh, which
is the only script that enables the module. Without it, removing the
package left relay enabled pointing at a deleted relay.so, so PHP emitted
a startup warning on every invocation:

  PHP Warning:  PHP Startup: Unable to load dynamic library 'relay.so'

It follows what Debian's own PHP extension packages do in postrm: dismod
on remove, sweep leftover symlinks on purge, and guard on `$1` so an
upgrade does not disable the extension. Every call tolerates failure --
by the time postrm runs the PHP tooling may already be gone, and nothing
here may block removal.

relay-pkg.so statically links hiredis and ck, so their notices now ship
in the copyright file. Verified against the binary rather than assumed:
redisConnect and ck_rhs_init are in the symbol table, while lz4 and zstd
are dlopen'd at runtime and jemalloc is absent entirely, so neither is
bundled and neither needs a notice. The plain relay.so used on noble,
plucky and trixie links hiredis and ck dynamically and is covered by the
distribution's own packages, so the notices are conditional on the
binary variant.

ck's license also carries an Apache-2.0 notice for src/ck_hp.c, which
needs the shipped copy referenced rather than the notice standing alone.

Verified on Debian trixie with real PHP 8.4: install enables cli and fpm
and the extension loads, upgrade leaves it enabled, remove disables it
cleanly, purge leaves nothing behind, and PHP still starts without
warnings afterwards.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015PwyVggCYKS72z4uS36A2D
Copilot AI review requested due to automatic review settings July 28, 2026 19:54
@tillkruss

Copy link
Copy Markdown
Member Author

Pushed 29c0396 — this PR now closes #1, #2, #3, #4 and most of #10.

#1 / #2 — deb removal script

after-install-multi.sh is the only script that enables the module, and it had no counterpart. Reproduced the bug on Debian trixie with real PHP 8.4 — after apt remove php8.4-relay, the symlink survives and PHP warns on every invocation:

PHP Warning:  PHP Startup: Unable to load dynamic library 'relay.so'
(tried: /usr/lib/php/20240924/relay.so: cannot open shared object file)

after-remove-multi.sh follows Debian's own PHP extension packages (checked against php8.4-curl's postrm): dismod on remove, sweep leftover symlinks on purge, guard on $1 so upgrades don't disable the extension. Every call tolerates failure — by the time postrm runs the PHP tooling may already be gone, and nothing here may block removal.

Full lifecycle, native arm64, real PHP:

step cli fpm ini
before install no no no
after install YES YES YES
after upgrade YES YES YES
after remove no no YES
after purge no no no

php -m lists relay after install; php -r runs clean after removal; no leftover symlinks under /etc/php.

Only the multi family needs this — base and ls never call phpenmod.

#3 — bundled library licenses

Determined by inspecting the binary rather than trusting the 2021 issue comment:

Library Linkage Notice needed
hiredis static (redisConnect in symtab) yes
ck static (ck_rhs_init) yes
lz4 / zstd dlopen("liblz4.so.1") no
jemalloc absent from all three binaries no

So the scope is narrower than #3's original list. Notices are conditional on $pkg_binary — the plain relay.so used on noble/plucky/trixie links hiredis and ck dynamically and is covered by the distro's own packages.

ck's license also carries an Apache-2.0 notice for src/ck_hp.c; that needs /usr/share/common-licenses/Apache-2.0 referenced or lintian raises copyright-not-using-common-license-for-apache2. Caught and fixed. Vendored files under build/licenses/ are pristine upstream copies — the Debian pointer is emitted from helpers.sh.

Cumulative: 12 lintian/rpmlint tags cleared, zero regressions.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

build/helpers.sh:143

  • The generated changelog files are now required at build time, but this block doesn’t verify they exist. If /root/build/changelog.deb.tpl or /root/build/changelog.rpm is missing, the build will fail mid-run (sed: no such file / fpm missing changelog) without telling the user they need to run the new changelog rendering step first.
  if [[ "$type" == "deb" ]]; then
    sed "s/@PKG@/$pkg_name/g" /root/build/changelog.deb.tpl > /tmp/changelog-$pkg_name.deb
    args+=("--deb-changelog /tmp/changelog-$pkg_name.deb")
  else
    args+=("--rpm-changelog /root/build/changelog.rpm")

build/helpers.sh:75

  • fpm_build now assumes /root/build/changelog.epoch exists; if the workflow step is skipped (or a contributor runs build/fpm.sh locally without pre-rendering changelogs), this will fail later with a confusing cat/date error. Add an explicit existence check with a clear message before using the file so packaging fails fast and explains how to generate it.
  {
    echo "Copyright (C) 2021-$(date -u -d @$(cat /root/build/changelog.epoch) +%Y) CacheWerk, Inc."
    echo "All rights reserved."
    echo

build/src/deb/after-remove-multi.sh:3

  • This maintainer script says it must not abort removals, but set -e can still terminate the script on an unexpected non-zero exit (e.g. future helper changes, missing commands, or a failing rm/readlink). For Debian maintainer scripts it’s safer to avoid set -e here and explicitly tolerate failures where needed.
set -e

The lsphp packages install into /usr/local/lsws, because that is where
LiteSpeed keeps its bundled PHP. That is not something this repo can
change, and the ini has to stay a conffile despite living outside /etc or
a user's settings would be overwritten on every upgrade. Both are correct
behaviour, so declare them instead of leaving them reported as defects.

Clears 5 tags across the deb matrix: dir-in-usr-local, file-in-usr-local,
file-in-unusual-dir, file-in-usr-marked-as-conffile and
non-etc-file-marked-as-conffile. Verified every override matches, so
lintian reports no unused-override.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015PwyVggCYKS72z4uS36A2D
Copilot AI review requested due to automatic review settings July 28, 2026 20:05
Since v0.40.0 Relay dlopens liblz4 and libzstd at startup rather than
linking them -- neither appears in the NEEDED entries of relay.so or
relay-pkg.so -- but the packages still required them outright, so every
install pulled in libraries Relay only optionally uses.

They are now Recommends, which apt installs by default, so in practice
nobody loses compression; --no-install-recommends users and container
builds can opt out, which is the point.

el7 keeps them as hard requires. Weak dependencies arrived in rpm 4.12
and el7 ships 4.11.3, so a Recommends there is read and then ignored,
which would silently stop installing them for exactly the users least
likely to notice. Verified on centos:7 that such a package still parses
and installs; it simply drops the tag. The cost is that
explicit-lib-dependency stays on the el7 rpms.

Clears explicit-lib-dependency on el8 and el9.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015PwyVggCYKS72z4uS36A2D
@tillkruss

Copy link
Copy Markdown
Member Author

Pushed e40441a and 21c55e1.

Lintian overrides

The lsphp packages install into /usr/local/lsws because that is where LiteSpeed keeps its bundled PHP, and the ini must stay a conffile despite living outside /etc or user settings get overwritten on upgrade. Both are correct behaviour, now declared rather than reported as defects.

Clears 5 tags: dir-in-usr-local, file-in-usr-local, file-in-unusual-dir, file-in-usr-marked-as-conffile, non-etc-file-marked-as-conffile. Verified every override matches — lintian reports no unused-override.

lz4 / zstd demoted to weak dependencies

Since v0.40.0 Relay dlopens these at startup rather than linking them. Confirmed against the binaries — neither relay.so nor relay-pkg.so has an lz4/zstd NEEDED entry, only dlopen("liblz4.so.1") strings. But the packages still required them outright, so every install pulled in libraries Relay only optionally uses.

Target Before After explicit-lib-dependency
deb Depends Recommends n/a
rpm el8/el9 Requires Recommends 3 → 0
rpm el7 Requires unchanged stays

apt installs Recommends by default, so nobody loses compression in practice — but --no-install-recommends users and container builds can now opt out, which is the correct semantic for a dlopen'd library.

el7 deliberately keeps hard requires. Weak dependencies arrived in rpm 4.12; el7 ships 4.11.3. Verified on a real centos:7 that a package carrying Recommends still parses and installs there — rpm just ignores the tag. That means a Recommends would silently stop installing lz4/zstd for exactly the users least equipped to diagnose it, so el7 keeps Requires and retains the explicit-lib-dependency warning.

Where the deb matrix now stands

E unstripped-binary-or-object    <- needs a vendor decision
I hardening-no-bindnow           <- upstream compile flag
W unknown-field (License)        <- fpm emits it unconditionally

17 tags cleared cumulatively, zero regressions.

One assumption worth confirming before merge: this presumes Relay degrades gracefully when relay.ini requests lz4/zstd and the library is absent. If it errors instead, these should go back to Depends everywhere.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 19 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

build/helpers.sh:73

  • fpm_build now unconditionally reads /root/build/changelog.epoch (for copyright year and --source-date-epoch-default). If the changelog render step was skipped (e.g. local runs or reruns), this will fail with a generic cat: ... No such file and abort the build under set -e. Add an explicit preflight check with a clear error so the failure mode is actionable.
  # Debian policy requires /usr/share/doc/<pkg>/copyright; rpm wants documentation.
  # The year comes from the release date so the file stays reproducible.
  mkdir -p $dest_path/usr/share/doc/$pkg_name
  {
    echo "Copyright (C) 2021-$(date -u -d @$(cat /root/build/changelog.epoch) +%Y) CacheWerk, Inc."

build/src/deb/after-remove-multi.sh:3

  • This maintainer script says it must not abort package removal, but set -e can still cause unexpected exits on unanticipated errors (e.g. missing utilities, edge-case failures in substitutions). Since failures are intentionally tolerated below, disable -e here to align behavior with the comment and avoid blocking removals.
set -e

Copilot AI review requested due to automatic review settings July 28, 2026 20:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 19 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

build/helpers.sh:71

  • fpm_build now unconditionally reads /root/build/changelog.* (for copyright year, --source-date-epoch-default, and --deb/--rpm-changelog). If these files weren't generated first (e.g., local ./fpm.sh <tag> runs), the build will fail with a generic cat: ... No such file error. Add a clear preflight check with an actionable message.
  # Debian policy requires /usr/share/doc/<pkg>/copyright; rpm wants documentation.
  # The year comes from the release date so the file stays reproducible.
  mkdir -p $dest_path/usr/share/doc/$pkg_name

.github/workflows/package.yml:46

  • The changelog-render step fetches releases from repos/${{ github.repository_owner }}/relay, but the changelog generator and PR description reference cachewerk/relay. In forks or other owners this will likely 404 and the build will fail before packaging.
          gh api --paginate 'repos/${{ github.repository_owner }}/relay/releases?per_page=100' \
            | jq -s 'add' > /tmp/releases.json
          ./build/changelog.sh /tmp/releases.json '${{ github.event.inputs.tag }}' build

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015PwyVggCYKS72z4uS36A2D
Copilot AI review requested due to automatic review settings July 28, 2026 20:16
tillkruss and others added 4 commits July 28, 2026 13:17
Updated the description in fpm_args to remove mention of companion extensions.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015PwyVggCYKS72z4uS36A2D

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 19 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

build/src/deb/config.base.sh:30

  • The comment says this metapackage “ships no files”, but the build now always writes /usr/share/doc/<pkg>/copyright in helpers.sh, so this package will ship at least that doc file. Updating the comment avoids future confusion about why lintian’s empty-package checks are (now) satisfied.
)

build/src/deb/config.base.sh:30

  • helpers.sh always adds a --description argument, and this config adds another --description for the metapackage. That works only if fpm deterministically uses the last occurrence, but it’s brittle and makes it easy to accidentally end up with the wrong description if argument order changes. Prefer passing exactly one description by adding a per-package override variable (e.g., pkg_description) that helpers.sh uses when set, instead of emitting --description from config files.
    build/helpers.sh:72
  • The build now hard-depends on /root/build/changelog.epoch (and later the rendered changelog files). If those files haven’t been rendered (e.g., a local ./fpm.sh run without the new workflow step), the script currently fails with a generic cat: ... No such file or directory due to set -e. Add an explicit preflight check with a clear error so failures are actionable.
  mkdir -p $dest_path/usr/share/doc/$pkg_name
  {
    echo "Copyright (C) 2021-$(date -u -d @$(cat /root/build/changelog.epoch) +%Y) CacheWerk, Inc."
    echo "All rights reserved."

Copilot AI review requested due to automatic review settings July 28, 2026 20:22

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 19 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

build/helpers.sh:72

  • fpm_build now requires /root/build/changelog.epoch (and later changelog templates) to exist. When it’s missing, the script fails via cat under set -e with a low-signal error. Add an explicit existence check with a clear message before first use, and quote the date -d argument so it’s parsed consistently.
  mkdir -p $dest_path/usr/share/doc/$pkg_name
  {
    echo "Copyright (C) 2021-$(date -u -d @$(cat /root/build/changelog.epoch) +%Y) CacheWerk, Inc."
    echo "All rights reserved."

Comment on lines 24 to 28
fpm_args=(
"--deb-pre-depends 'php-common'"
"--after-install /root/build/src/deb/after-install.sh"
"--description $'Relay metapackage for PHP $php_version\nThis dependency metapackage pulls in the Relay extension for PHP\n$php_version.'"
)
tillkruss and others added 2 commits July 28, 2026 13:29
Leads with the product positioning rather than a generic summary.

The synopsis keeps its leading article and trailing period, so
description-synopsis-starts-with-article, synopsis-is-a-sentence and
summary-ended-with-dot are reported again. Debian wants a noun phrase
there; dropping "The" and the period would clear all three.

Note the text has to stay ASCII. A multiplication sign in the description
aborts every rpm build -- fpm's rpm.erb raises Encoding::CompatibilityError
mixing ASCII-8BIT and US-ASCII once a changelog is attached.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015PwyVggCYKS72z4uS36A2D
Generated changelogs now land in build/changelog/ as deb.tpl, rpm and
epoch, so they need one ignore rule instead of three. They could not be
globbed where they were: /build/changelog.* would also have matched the
tracked changelog.sh.

The two per-format source rules fold into one glob. Seven entries become
four, all still needed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015PwyVggCYKS72z4uS36A2D
Copilot AI review requested due to automatic review settings July 28, 2026 20:29
Drops the leading article and trailing period, which Debian disallows in
a synopsis. Clears description-synopsis-starts-with-article,
synopsis-is-a-sentence and summary-ended-with-dot.

changelog.sh gains -u and -o pipefail. pipefail is the one that matters:
every output file is written through `jq | wrap_bullets`, and awk exits 0
regardless, so a jq failure would leave a silently truncated changelog
and the script would carry on. Reproduced before fixing. -u turns a
missing argument into an immediate error instead of an empty path.

Not applied elsewhere: helpers.sh reads unset variables by design
(pkg_provides, pkg_lintian_overrides), and after-remove-multi.sh must
never abort a package removal.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015PwyVggCYKS72z4uS36A2D

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 19 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (4)

build/src/deb/config.base.sh:28

  • The new --description $'...' element expands to a string containing literal newlines but is not shell-quoted when later flattened into bash -c "fpm $args ...". That can split the fpm command across multiple lines (and also relies on $php_version expansion at execution time), which is likely to break the build for the base metapackage.
fpm_args=(
  "--deb-pre-depends 'php-common'"
  "--after-install /root/build/src/deb/after-install.sh"
  "--description $'Relay metapackage for PHP $php_version\nThis dependency metapackage pulls in the Relay extension for PHP\n$php_version.'"
)

build/helpers.sh:71

  • fpm_build now assumes /root/build/changelog/{epoch,deb.tpl,rpm} exist. If the changelog step is skipped (e.g., local runs or other automation), the build will fail with non-obvious cat/sed errors. Add an explicit preflight check with a clear error message before first use.
  mkdir -p $dest_path/usr/share/doc/$pkg_name
  {
    echo "Copyright (C) 2021-$(date -u -d @$(cat /root/build/changelog/epoch) +%Y) CacheWerk, Inc."
    echo "All rights reserved."

build/changelog.sh:10

  • build/changelog.sh uses pipelines where a jq failure can be masked because set -e does not fail the script on earlier pipeline commands by default. Enabling pipefail makes changelog rendering fail fast and avoids silently writing empty/partial changelogs.
set -euo pipefail

build/helpers.sh:8

  • relay_description is passed to fpm via --description and its first line becomes the deb synopsis / rpm summary. As written it starts with an article (“The”) and ends with a period, which is exactly what lintian (description-synopsis-starts-with-article, synopsis-is-a-sentence) and rpmlint (summary-ended-with-dot) warn about, contradicting the PR goal of clearing those findings.
read -r -d '' relay_description <<'DESCRIPTION' || true
Fastest Redis client for PHP
100x faster cache reads, near-zero bandwidth, no code changes required.
Relay keeps a partial replica of the Redis or Valkey data set inside the
PHP process, avoiding network round trips.

Copilot AI review requested due to automatic review settings July 28, 2026 20:35
@tillkruss
tillkruss merged commit edc90d4 into main Jul 28, 2026
1 check passed
@tillkruss
tillkruss deleted the lintian-packaging-fixes branch July 28, 2026 20:36
This was referenced Jul 28, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 18 out of 19 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

build/src/deb/config.base.sh:28

  • The new metapackage description uses $'...\n...' inside the config array, which expands to literal newlines without shell quoting. When helpers.sh flattens args and runs bash -c "fpm $args ...", those newlines split the command and break --description parsing (and can even terminate the fpm command early). Wrap the description in quotes in the string passed to bash -c so it stays a single argument.
fpm_args=(
  "--deb-pre-depends 'php-common'"
  "--after-install /root/build/src/deb/after-install.sh"
  "--description $'Relay metapackage for PHP $php_version\nThis dependency metapackage pulls in the Relay extension for PHP\n$php_version.'"
)

build/helpers.sh:71

  • fpm_build now unconditionally reads /root/build/changelog/{epoch,deb.tpl,rpm}, but build/fpm.sh doesn't render them. When they are missing (e.g., local runs), the build fails with a cryptic cat/sed error mid-build. Add an explicit existence check with a clear message before the first use.
  mkdir -p $dest_path/usr/share/doc/$pkg_name
  {
    echo "Copyright (C) 2021-$(date -u -d @$(cat /root/build/changelog/epoch) +%Y) CacheWerk, Inc."
    echo "All rights reserved."

build/changelog.sh:88

  • With set -e, the final grep -c command substitutions will cause the script to exit if they ever match 0 lines (grep returns status 1 on no matches), even though writing 0 entries is not itself an execution error. Make the greps non-fatal so the status message can't fail the build.
# the source date epoch must not be newer than the newest changelog entry
echo "$filtered" | jq -r '.[0].published_at | fromdateiso8601' > "$out/epoch"

echo "Wrote $(grep -c '^@PKG@' "$out/deb.tpl") deb entries, $(grep -c '^\* ' "$out/rpm") rpm entries"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Include proper changelog

2 participants