Skip to content

Debian packaging via per-component Makefiles + fpm#347

Merged
runleveldev merged 42 commits into
mainfrom
rgingras/feature/nfpm-packaging
Jun 19, 2026
Merged

Debian packaging via per-component Makefiles + fpm#347
runleveldev merged 42 commits into
mainfrom
rgingras/feature/nfpm-packaging

Conversation

@runleveldev

@runleveldev runleveldev commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

Introduces Debian packaging for the three deployable components using per-component Makefiles + fpm publishes them to GitHub Releases as a flat APT repository, and rebuilds the container images to install those packages. The same component build commands are reused by local development (compose), the images, and CI.

Packages

Directory Package Arch Contents
create-a-container/ opensource-server amd64 Manager web app, job runner, systemd units
mie-opensource-landing/ opensource-docs all Prebuilt documentation site
pull-config/ opensource-agent all pull-config engine, instances, error pages

Everything installs under the /opt/opensource-server prefix (matching existing runtime references). opensource-server depends on opensource-agent + opensource-docs (the manager's rendered nginx config serves their files).

What's included

  • Per-component Makefiles with a uniform contract — deps, build (default goal), install (DESTDIR/PREFIX-aware), dev, and deb/rpm/apk. VERSION is derived from git tags inline. The top-level Makefile delegates to all three and collects packages into dist/. make clean removes staging, build outputs, and built packages.
  • nfpm.yaml per component — packages the staged tree via ${DESTDIR} interpolation (expand: true), so the config stays DRY and supports any DESTDIR. opensource-server ships its systemd units and enables them via a postinstall script; the logrotate drop-in is a config file. Distro-integration files live under create-a-container/contrib/.
  • images/builder — runs make deb (Node.js, uv, nfpm) to produce the packages as an artifact-only stage. The docs/agent/manager images install them via RUN --mount=from=builder (no extra layers) and stage the release APT source so apt upgrade tracks future releases.
  • CIrelease.yml (on v* tags) builds the packages, generates flat-repo metadata (Packages, Packages.gz) and *_latest.deb aliases, and attaches them to the release. build-images.yml now tags :latest only on non-prerelease releases.
  • Developer docs — new developers/release-pipeline.md plus stale-doc refreshes.
  • LICENSE — Apache-2.0.

Behavioral changes worth noting

  • container-creator-init.service (provisions a local PostgreSQL) moved from the package to the manager image, since the package only suggests postgresql and works with a remote database too. The package ships container-creator + job-runner.
  • Fixed a latent unit bug: the access-log directory is created on demand via the correct LogsDirectory directive (was the invalid LogDirectory, which systemd silently ignored).
  • :latest images now track non-prerelease releases instead of every merge to main.

Install / update (admins)

# One-off:
curl -fsSLO https://github.com/mieweb/opensource-server/releases/latest/download/opensource-agent_latest.deb
apt install -y ./opensource-agent_latest.deb

# Or as an apt source (also baked into the images):
echo 'Types: deb
URIs: https://github.com/mieweb/opensource-server/releases/latest/download/
Suites: ./
Trusted: yes' > /etc/apt/sources.list.d/opensource-server.sources
apt update && apt install opensource-server

Migrating an existing (non-package) system to packages

Existing deployments run from an in-place tree at /opt/opensource-server
(a git checkout built with the old make install), with systemd units in
/etc/systemd/system/. The packages own files under /opt/opensource-server/<component>/
and ship units in /usr/lib/systemd/system/, so the old in-place files must be
removed first or dpkg will refuse to overwrite files it does not own.

The good news: the package layout uses the same prefix and the same config
paths
, so stateful config is preserved across the switch:

  • /etc/default/container-creator (manager DB credentials) — kept; the packaged
    container-creator/job-runner units read the same file, so the existing
    database keeps working (local or remote).
  • /etc/pull-config.d/* and /etc/cron.d/pull-config (agent) — these are
    conffiles in the package; local customizations are preserved on install.
  • /var/log/opensource-server — recreated on demand by the unit's LogsDirectory.

Steps (run on the target container/host)

# 1. Stop the running services.
systemctl stop container-creator job-runner || true

# 2. Back up the config you want to keep (paranoia; the package preserves these).
cp -a /etc/default/container-creator /root/container-creator.env.bak 2>/dev/null || true
cp -a /etc/pull-config.d /root/pull-config.d.bak 2>/dev/null || true

# 3. Remove the old in-place units and disable them so they don't shadow the
#    packaged units in /usr/lib/systemd/system.
rm -f /etc/systemd/system/container-creator.service \
      /etc/systemd/system/job-runner.service
systemctl daemon-reload

# 4. Remove the old in-place tree so the package can own /opt/opensource-server.
#    The old install put the whole repo (or a bind mount) here; the package only
#    writes to component subdirs, so clear the lot. Config lives in /etc and is
#    untouched (do NOT remove /etc/default/container-creator or /etc/pull-config.d).
rm -rf /opt/opensource-server

# 5. Add the release APT source and install the package(s) for this role.
#    `releases/latest/download/` serves the newest non-prerelease release. To
#    pin a specific release (or a prerelease, which `latest` skips), use the tag
#    URL instead, e.g. https://github.com/mieweb/opensource-server/releases/download/2026.6.3/
cat >/etc/apt/sources.list.d/opensource-server.sources <<'EOF'
Types: deb
URIs: https://github.com/mieweb/opensource-server/releases/latest/download/
Suites: ./
Trusted: yes
EOF
apt update

# Manager (pulls in opensource-agent + opensource-docs automatically):
apt install -y opensource-server
# Agent-only node:
#   apt install -y opensource-agent
# Docs-only node:
#   apt install -y opensource-docs

Notes:

  • On a manager, the local PostgreSQL provisioning unit
    (container-creator-init.service) is part of the image, not the package. On
    a bare-metal/LXC host that already has /etc/default/container-creator, it is
    not needed — the existing DB config is reused. For a brand-new manager without
    that file, provision the database and write /etc/default/container-creator
    yourself (local or remote), then start container-creator.
  • After this, updates are just apt update && apt upgrade (the source tracks the
    latest non-prerelease release).
  • If dpkg still reports a conflict on a specific file under
    /opt/opensource-server, a leftover from the old tree was missed — remove that
    path and re-run apt install.

Verification

  • All three packages build via make deb; inspected metadata, deps, conffiles, scripts, modes, and the node_modules/.bin/sequelize symlink.
  • Built and boot-tested all three images against the real release source: docs serves :80, agent has pull-config + cron, manager has all units active (incl. the image-owned init), app on :3000, DB provisioned, /var/log/opensource-server auto-created, and apt update works inside the final image.
  • Migration tested end-to-end: launched the pre-package manager image (:main), seeded DB state (a marker row; 53 applied migrations), then ran the migration steps above against the 2026.6.3 prerelease (via its tag URL). Result: apt install opensource-server succeeded with no dpkg file conflicts, units moved to /usr/lib/systemd/system and were enabled + restarted by the postinstall, the app returned 200, and all DB state and /etc/default/container-creator credentials were preserved (marker row intact, migration count unchanged, password identical). Agent (pull-config/cron/nginx/dnsmasq), docs site, and error-pages were all functional afterward.

Notes / follow-ups

  • The bootstrap v2026.6.2 release needed a manual Packages.gz upload (GitHub rejects the empty uncompressed Packages; apt uses the .gz). Future releases generate both automatically.
  • GPG signing of the APT repo is out of scope (Trusted: yes for now).

Draft for review — happy to split into smaller PRs if preferred.

@runleveldev runleveldev force-pushed the rgingras/feature/nfpm-packaging branch from 228b852 to 3f506d4 Compare June 14, 2026 18:23
@runleveldev runleveldev changed the title Debian packaging via per-component Makefiles + nfpm Debian packaging via per-component Makefiles + fpm Jun 14, 2026
This was linked to issues Jun 15, 2026
@runleveldev runleveldev requested a review from Copilot June 16, 2026 12:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 introduces a packaging-and-release pipeline that builds the three deployable components as OS packages (via per-component Makefiles + fpm), publishes them to GitHub Releases as a flat APT repository, and updates the Docker images to install those packages instead of copying/building the repo in-image.

Changes:

  • Added per-component packaging Makefiles (+ fpm metadata) and a shared package-version helper derived from git describe.
  • Added a builder image and Docker Bake wiring so docs/agent/manager images install .deb artifacts produced by the builder stage.
  • Added/updated CI + developer docs to publish release assets (debs + Packages/Packages.gz) and document the release pipeline.

Reviewed changes

Copilot reviewed 31 out of 34 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
pull-config/Makefile New component Makefile: stages pull-config + instances + error pages and builds packages via fpm.
pull-config/install.sh Removes the legacy imperative install script (replaced by Makefile install).
pull-config/.gitignore Ignores component packaging artifacts (.pkg/, built packages).
pull-config/.fpm Defines opensource-agent package metadata and Debian dependencies.
package-version New helper to derive format-specific package versions from git tags/describe output.
mie-opensource-landing/zensical.toml Adds “Release Pipeline” to docs navigation.
mie-opensource-landing/Makefile New component Makefile to build/stage docs site and package with fpm.
mie-opensource-landing/docs/developers/release-pipeline.md New developer documentation describing packaging, images, and release workflow.
mie-opensource-landing/docs/developers/pull-config.md Updates pull-config docs to reflect Makefile-based build/packaging.
mie-opensource-landing/docs/developers/docker-images.md Updates image docs to describe installing packaged payloads via builder context.
mie-opensource-landing/.gitignore Ignores docs packaging artifacts and built packages.
mie-opensource-landing/.fpm Defines opensource-docs package metadata.
Makefile Replaces old install targets with delegation to component Makefiles and adds package collection to dist/.
LICENSE Adds Apache-2.0 license text.
images/opensource-server.sources Adds an APT source file pointing at releases/latest/download/ (trusted).
images/manager/Dockerfile Installs packaged manager/docs artifacts from builder output; enables init unit; keeps PG install.
images/manager/container-creator-init.service Adjusts init sequencing and runs sequelize migrations + seeds on first boot.
images/docs/Dockerfile Installs nginx + opensource-docs from builder output; stages the APT source file.
images/docker-bake.hcl Adds a builder target and wires it as a context for docs/agent/manager builds.
images/builder/Dockerfile New artifact-only image that builds the three .deb packages into /dist.
images/agent/Dockerfile Installs opensource-agent package from builder output; stages the APT source file.
create-a-container/Makefile New component Makefile: builds client bundle, stages runtime tree + units + logrotate, packages with fpm.
create-a-container/contrib/systemd/job-runner.service Adds packaged job-runner systemd unit.
create-a-container/contrib/systemd/container-creator.service Fixes log directory creation by using LogsDirectory.
create-a-container/contrib/preremove.sh Adds pre-removal script to stop/disable units on package removal.
create-a-container/contrib/postinstall.sh Adds post-install script to enable and (when applicable) restart units.
create-a-container/contrib/opensource-server.logrotate Adds packaged logrotate config for /var/log/opensource-server/*.log.
create-a-container/.gitignore Ignores component packaging artifacts and built packages.
create-a-container/.fpm Defines opensource-server package metadata, deps, scripts, and conffile.
compose.yml Tweaks dev install commands for create-a-container (server deps omit dev; client deps installed explicitly).
.gitignore Ignores top-level dist/ artifacts.
.github/workflows/release.yml New workflow: builds packages via bake, generates Packages/Packages.gz, uploads to the release.
.github/workflows/build-images.yml Updates triggers and “latest” tagging behavior to align with non-prerelease releases.
.dockerignore Updates ignored build outputs; intends to ignore packaging artifacts.

Comment thread .dockerignore Outdated
Comment thread mie-opensource-landing/docs/developers/release-pipeline.md Outdated
Comment thread mie-opensource-landing/docs/developers/release-pipeline.md
Comment thread mie-opensource-landing/docs/developers/release-pipeline.md Outdated
Comment thread .github/workflows/build-images.yml
@runleveldev runleveldev marked this pull request as ready for review June 16, 2026 13:26
- container-creator-init: invoke node_modules/.bin/sequelize directly
  instead of 'npm run db:migrate' so npm is not a runtime dependency.
- container-creator: create /var/log/opensource-server on demand via
  systemd LogDirectory instead of shipping an empty directory in the
  package.
Self-contained Makefile with the standard deps/build/install/dev
contract (default goal: build), DESTDIR/PREFIX/VERSION parameters, and
deb/rpm/apk targets that stage the component and package it with nfpm.

- dev runs 'npm run dev' (server + client watch); dev-client runs only
  the client bundle watcher for the compose client service.
- install stages the app under PREFIX/create-a-container (cp -a to keep
  node_modules/.bin symlinks), the three systemd units, and the
  logrotate drop-in.
- nfpm.yaml builds the opensource-server package: depends on
  opensource-agent + opensource-docs (the manager nginx config
  references their files) plus nodejs/sudo/libc; postinstall enables
  the units, preremove disables them on real removal. Logrotate ships
  as a config file. Relocated from images/manager/.
Makefile with deps (uv sync) / build (zensical build, default) /
install (stage the prebuilt site under PREFIX) / dev (zensical serve)
and deb/rpm/apk targets. nfpm.yaml builds the content-only
opensource-docs package (arch all), suggesting nginx.
Makefile with no-op deps/build/dev (plain bash) and an install target
that stages the pull-config engine, instances, cron schedule, the
shared error pages and the nginx forward-auth cache dir. nfpm.yaml
builds the opensource-agent package, depending on nginx (with stream
and ModSecurity modules), dnsmasq, cron and curl; instances and cron
ship as config files (instances mode 0755).
The root Makefile now delegates the standard deps/build/install/dev/
deb/rpm/apk contract to the three component Makefiles and forwards
PREFIX/DESTDIR/VERSION. 'make deb' builds all three packages and
collects them into ./dist. Default goal is build.
Add images/builder, a Debian image that runs 'make deb' (Node + uv +
nfpm) to produce the three packages, exported as an artifact-only
stage. docs/agent/manager now install those packages via a builder
context instead of copying the repo and running make:

- agent: installs opensource-agent; keeps image-only conffile edits
  (ModSecurity, dnsmasq, acme.sh).
- docs: installs opensource-docs + nginx; keeps the vhost.
- manager: installs opensource-docs + opensource-server (agent already
  present); keeps PGDG postgres + the Proxmox snakeoil drop-in.

Each leaf image stages /etc/apt/sources.list.d/opensource-server.sources
(flat repo at releases/latest/download) so 'apt upgrade' tracks future
releases. The source is added last / removed-then-re-added in manager so
an 'apt update' during the build is never blocked by the release not
existing yet.

Also fix container-creator.service to use the correct systemd directive
LogsDirectory (not LogDirectory), so /var/log/opensource-server is
created on demand; the typo silently disabled it and the app crashed
opening access.log.
The node, client and zensical dev services now install make and invoke
the component Makefile targets instead of inlining npm/uv commands:
- node: 'make deps' (create-a-container)
- client: 'make dev-client' (client bundle watcher only; the server runs
  inside Proxmox)
- zensical: 'make dev' (docs live server), preserving VIRTUAL_ENV

Keeps the dev workflow in lockstep with the packaging build steps.
- release.yml: on a v* tag, build the three packages via the builder
  bake target, generate flat APT repo metadata (Packages, Packages.gz)
  with dpkg-scanpackages, and attach the debs + metadata to the GitHub
  release so releases/latest/download serves a working
  'deb [trusted=yes] ... ./' source.
- build-images.yml: expand the paths filters to the component
  directories, **/Makefile, **/nfpm.yaml and .dockerignore, since the
  images now build from the component packages.
Add a release trigger (published, released) and gate the :latest tag on
a non-prerelease release event instead of every push to main. Merges to
main still publish branch/sha tags; :latest now moves only when a real
(non-prerelease) GitHub release is published, keeping the :latest image
channel aligned with the releases/latest deb channel.
- Add developers/release-pipeline.md covering the component Makefile
  contract (deps/build/install/dev), nfpm packaging and the three
  package names, the builder image, the flat APT repo on GitHub
  Releases, the deb apt source, and the latest-on-non-prerelease rule.
- Wire it into the docs nav.
- docker-images.md: fix the stale lego reference (acme.sh), describe the
  package-based image composition and the builder target.
- pull-config.md: note the Makefile/package supersede install.sh.
- release.yml: also publish *_latest.deb stable-name aliases.
- nfpm.yaml no longer fights 'make install': /etc files are declared
  explicitly as config and the rest is packaged per top-level directory
  (/opt, /usr), so no file appears in both a tree and a config entry.
  'make package' no longer rm -rf's or mutates the staged build-root; it
  reuses the DESTDIR install (run 'make clean' first for a pristine
  build).
- container-creator-init.service is the manager image's concern, not the
  package's: it provisions a *local* PostgreSQL, which the package only
  suggests. Moved the unit to images/manager and made it
  Requires=postgresql.service. The package now ships only
  container-creator + job-runner; postinstall/preremove manage those two.
Apply the same nfpm tree-split as opensource-server: /etc files are
declared explicitly as config entries and the rest is packaged per
top-level directory, so no file appears in both a tree and a config
entry. 'make package' now reuses the DESTDIR install instead of
rm -rf'ing the staged tree and deleting conffiles from it (run
'make clean' first for a pristine package).
- Bind-mount the builder's /dist with RUN --mount=from=builder instead
  of COPY + RUN, removing the extra image layer per package install.
- Stage the release APT source once and leave it in place for the whole
  build (and the final image) instead of removing and re-adding it. A
  missing release is a non-fatal 'apt update' warning for our own
  install steps ('|| true'); the PGDG setup script does a strict update,
  so the source is moved aside and restored within that single layer.
- Install and enable container-creator-init.service in the manager image
  (it provisions local PostgreSQL, an image concern, not the package's).
Installing make in each slim dev image was ugly. The node, client and
zensical services emulate their component make targets (deps,
dev-client, dev) directly with npm/uv instead, matching the original
approach. Comments cross-reference the equivalent make target.
Reflect that container-creator-init lives in the manager image (not the
package), the nfpm tree-split that avoids the config/tree collision and
the no-rm-rf packaging, and the RUN --mount install with the apt source
left in place.
…ild-root

- The pull-config engine and instances are program code, not
  configuration (runtime config comes from /etc/environment, which is
  not packaged), so nothing is tagged as a config file.
- nfpm.yaml no longer hard-codes ./build-root: nfpm runs from the
  staging root, so content sources are relative (etc, opt, var) and work
  for any DESTDIR. Packaging stages into a dedicated .pkg-root (never a
  user-supplied DESTDIR); make clean removes only that staging dir.
nfpm now runs from a dedicated .pkg-root staging dir, so nfpm.yaml
content sources are relative (opt, usr, etc) and support any DESTDIR
without hard-coding build-root. Removed the install-buildroot helper
target. For opensource-server, maintainer scripts are staged under
.pkg-root/.nfpm/ (outside the packaged contents) so they resolve
relative to nfpm's working directory. make clean only removes the
internal staging dir, never a user-supplied DESTDIR.
Use nfpm's expand:true on content entries to interpolate ${DESTDIR} in
the source paths, so nfpm.yaml no longer hard-codes the staging path and
nfpm runs from the component directory (not the staging root). Rename the
dedicated packaging staging dir to .nfpm/buildroot, descriptive of the
tooling.
…rib/

Group the distro-integration files under contrib/ (the conventional
location): contrib/systemd/{container-creator,job-runner}.service,
contrib/{postinstall,preremove}.sh and contrib/opensource-server.logrotate.
Update the Makefile install paths and nfpm.yaml script references
accordingly. Also adopt expand:true for ${DESTDIR} interpolation and the
.nfpm/buildroot staging dir, and drop the '|| true' guards from the
maintainer scripts in favor of detecting systemctl availability and
whether systemd is running.
…ease

Drop the '|| true' guards and the manager's source move-aside dance. Now
that every release carries flat APT repository metadata (an empty
Packages index suffices for the bootstrap release), apt-get update
against the release source succeeds throughout the image build, so the
release source can stay in place and failures are surfaced rather than
ignored. Also drop the redundant '|| true' on systemctl enable, which
succeeds at build time by creating static symlinks.
Each component's clean target now also removes its built *.deb/*.rpm/*.apk
artifacts, and the top-level clean removes the dist/ collection directory
in addition to delegating to the components.
The CI image build failed with 'version number does not start with digit'
because a shallow checkout has no tags, so 'git describe --tags --always'
returned a bare commit SHA which is not a valid Debian version.

- VERSION now falls back to 0.0.0+g<sha> when no tag is reachable, and
  only uses the tag-derived form when 'git describe --tags' succeeds, so
  the version is always digit-leading and valid.
- build-images.yml checks out with fetch-depth: 0 so the builder image's
  git describe sees tags and produces the proper 2026.6.2+N.gSHA version
  (release.yml already did this).
The release workflow no longer creates or mutates the GitHub release.
It runs on 'release: published' (full or prerelease), checks out the
release tag, builds the packages, and uploads the debs + flat-repo
metadata to the triggering release via 'gh release upload --clobber'.
This removes the prerelease race entirely: create the release (choosing
full vs prerelease) in GitHub first, then the action just attaches
assets. workflow_dispatch still builds packages for a manual test but
skips the upload. Docs updated accordingly.
The previous version logic translated prerelease suffixes to deb's ~rc1
form, which is invalid for apk (which needs _rc1). Instead, VERSION now
produces a plain semver string (e.g. 2026.6.3-rc1, 2026.6.3-rc1+15.gSHA)
and nfpm's default semver schema renders the correct version for each
packager: ~rc1 for deb/rpm, _rc1 for apk, with snapshot metadata mapped
to each format's convention. Verified prerelease and snapshot builds
across deb, rpm and apk.
Tags are now unprefixed semver (e.g. 2026.6.3, 2026.6.3-rc1), so the
'^v' strip is removed from the VERSION sed in all three component
Makefiles. git describe must reach an unprefixed tag for a valid
version.
Now that releases are tagged, git describe always finds a tag, so the
VERSION sed collapses to a single describe|sed pipeline.
metadata-action's flavor latest=auto adds :latest for type=ref,event=tag
events independently of the explicit type=raw,value=latest rule, so
publishing the 2026.6.3 prerelease moved :latest even though the raw
rule was disabled for prereleases. Set flavor: latest=false on every
metadata step so :latest is controlled solely by the explicit
non-prerelease-gated raw rule.
Each Makefile now parses VERSION (leading v stripped, 0.0.0 fallback),
PRERELEASE, commit count, hash, and dirty state from
git describe --tags --long --dirty. scripts/nfpm-version.sh composes a
format-appropriate version string (deb: ~pre +meta; rpm: ~pre ^snap;
apk: _pre _gitN) and nfpm.yaml sets version_schema: none so nfpm uses it
verbatim instead of its own semver parsing.
Move all version parsing and per-format composition into a single
script at the repo root, ./package-version <deb|rpm|apk>, which derives
the version from git itself. The component Makefiles no longer parse git
or hold version parts; their package targets just call the script. The
script has no .sh suffix and no tool-specific name so the implementation
can change later. Drop the now-unused VERSION plumbing from the
top-level Makefile.
Replace the three nfpm.yaml files with fpm options files
(<package>.fpm) holding the static package metadata, and have each
Makefile's package target invoke fpm with the dynamic options on the
CLI (output type, version from ../package-version, arch, staging dir,
and the manager's version-pinned inter-package deps).

fpm's dir input packages the staged tree verbatim from -C <stage>,
preserving symlinks (e.g. node_modules/.bin/sequelize) and the
directory layout, which removes nfpm's awkward per-directory src/dst
'tree' entries and ${DESTDIR} interpolation. Config files are marked
explicitly with --config-files and --deb-no-default-config-files stops
the auto-marking of everything under /etc that nfpm/dpkg defaults to.

The packaging staging dir is renamed from .nfpm/buildroot to
.pkg/buildroot (a dir literally named .fpm is consumed by fpm as an rc
options file).
Rename the per-component fpm options files to .fpm so fpm auto-loads
them, dropping --fpm-options-file. Move --architecture into each .fpm.
Let fpm copy the whole staging root from -C instead of listing the
top-level dirs. Add opensource-agent/opensource-docs to the manager's
.fpm as plain (unversioned) depends, dropping the per-format
version-pinned --depends from the Makefile.
Replace the nfpm .deb install with ruby + fpm via gem.
Update release-pipeline.md to describe the fpm-based packaging: .fpm
options files, the package-version composer, fpm's dir input from the
staging root, and explicit config-file marking. Correct the note that
pull-config instances are program code, not config files.
Add a help target listing the available targets and variables to the
top-level and each component Makefile, and set it as .DEFAULT_GOAL so a
bare 'make' prints usage instead of building. Also drop the stale nfpm
references from the create-a-container header comment.
The Makefiles stage into .pkg/buildroot, not build-root, so the stale
**/build-root pattern let local packaging artifacts leak into the build
context.
Restrict the push trigger to main so feature-branch pushes don't build
images (their PR covers that), reducing CI/registry churn. No paths
filter is added, so doc-only changes still rebuild the images.
Correct the Makefile contract table (default goal is help, add the help
target, drop the VERSION override row), describe ./package-version as the
version source, and state consistently that a leading v on the tag is
optional.
@runleveldev runleveldev force-pushed the rgingras/feature/nfpm-packaging branch from ebda76f to 67b06c9 Compare June 18, 2026 16:12

@cmyers-mieweb cmyers-mieweb left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

@runleveldev runleveldev merged commit 5a34da2 into main Jun 19, 2026
7 of 8 checks passed
@runleveldev runleveldev deleted the rgingras/feature/nfpm-packaging branch June 19, 2026 15:41
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.

Tag images latest on release Package as deb for easier upgrades

3 participants