Skip to content

enhancements for build, upstream, changelog - #35

Open
TheJJ wants to merge 48 commits into
SFTtech:mainfrom
TheJJ:build-upstream-enhance
Open

TheJJ wants to merge 48 commits into
SFTtech:mainfrom
TheJJ:build-upstream-enhance

Conversation

@TheJJ

@TheJJ TheJJ commented Oct 24, 2026

Copy link
Copy Markdown
Member
  • adding new changelog entries (just a version copy to start this feature)
  • upstream fetch to get an orig tarball without switching to it
  • more watch file options support
  • notification for build finish (and no sign for binary builds by default)
  • allow taking selective packages from -proposed or experimental
  • output artifacts to $packageroot/build-area/ by default (fallback build-debmagic/)
  • use distro-info-data for release names
  • debmagic env exec for direct in-env command execution

mikonse and others added 30 commits October 24, 2026 02:29
Adds an explicit environment (env) subcommand which allows users
to list and interact with existing build / test environments.

Additionally contains extensive internal refactoring to make the
environment tracking and cleanup more robust.
SourcePackage parses each lazily once and caches it. The .dsc/.changes checksum helpers move from debian::control to checksums.
Source builds fail with "fakeroot not found" on dpkg before 1.22.13, which checks for the gain-root command at startup even for -S. Both source and binary builds now install fakeroot unless Rules-Requires-Root is no.
`debmagic build source` fails with "no upstream tarball found" after
`debmagic upstream switch`: switch writes the orig tarball to the
output dir (`build/`), but the source build only looked in the data
dir and `../`. The source build now uses the output dir too.
--test, --clean, --incremental, --proposed, --debug-symbols and --sign-notify now take yes/no and on/off besides true/false.
`debmagic upstream fetch [VERSION]` puts the orig tarball into the
output dir, keeping an existing one unless `--force`. `upstream switch`
fetches the same way, then replaces the tree.

- `--from auto|upstream|launchpad|ubuntu|debian|custom` picks the source
- `--repack[=no]` (`upstream.repack`) strips `Files-Excluded` from
  upstream and custom tarballs; without it the tarball stays pristine
  and every excluded file it contains is listed as a warning
- `--signature-check[=no]` replaces `--no-signature-check`, and the
  `upstream.verify_signatures` config key is now `upstream.signature_check`
- upstream tarballs without excluded files are no longer re-created
`upstream fetch --from upstream` fails for watch files like valkey's:
- the `.zip` GitHub lists first won the version dedup; a tarball
  dpkg-source can use as-is is now preferred
- `@ARCHIVE_EXT@` and the version macros are now expanded in mangle
  rules too, like uscan does, so `filenamemangle` matches
- a mangled filename is always reduced to its last path component
The orig tarball version is the upstream version with `oversionmangle` (`Oversion-Mangle` in v5) applied, e.g. dovecot's `s/(.*)/$1+dfsg1/`.
A `Files-Excluded` entry naming a directory (dovecot's `doc/rfc`) never matched the files under it: `--repack=no` printed no warning, and repacking was skipped as if nothing were excluded.
gpg's `--keyring` only reads binary keyrings, so every `debian/upstream/signing-key.asc` failed with "invalid packet (ctb=2d)". The key is now dearmored first, like uscan does.
The GitHub API answers requests without one with 403 Forbidden, breaking watch files on api.github.com (e.g. mdevctl).
- `component=` in `opts`
- version field `same`, and `ignore`: a component without a release for the main version falls back to its newest one (also v5 `Version-Schema`)
- update script `uupdate` is accepted, as `upstream switch` does its job (also v5 `Update-Script`)
`upstream switch` left stale content behind:
- a dir present in both the old and the new tree was merged, keeping files the new version dropped
- a component's `debian/` was kept from the old tree, while dpkg-source only replaces the main orig's `debian/`

The old tree is now removed entirely before the new one moves in, except `.git`, kept paths and the main tree's `debian/`.
A changelog targeting `<release>-security`, `-updates`, `-proposed` or `-backports` fails the build with an unknown distro codename. Such suites now resolve to their release.
`--notify[=no]` (config `notify`) sends a desktop notification via notify-send and rings the terminal bell when `debmagic build` succeeds or fails, so a long build in a background window isn't forgotten.
Fresh container environments only ran `apt-get update`, so a cached Docker image or a long-lived Environment built against outdated packages.
They now also run `apt-get dist-upgrade`, and `--apt-update-age` (config `driver.apt_update_age`) decides when a reused Environment upgrades again.
The time of the last upgrade is kept in the Environment registry instead of a stamp file inside the container.
A source build in a container environment fails with `cannot fstat file ./<name>.orig.tar.*` when the output dir is on another filesystem than the environments dir: the symlink fallback pointed at a host path the container doesn't have. The tarball is now copied instead.
A source build of a package with debian/watch components (like mdevctl's vendor/) fails with dpkg-source 'unrepresentable changes to source', since only the main orig tarball was staged. Component origs are now fetched and staged next to it.
The top-level `notify` now defaults the new `build.notify`, `test.notify`
and the now optional `sign.notify`; one `--notify[=no]` overrides all
steps of a command and replaces `--sign-notify`.

- `debmagic test` notifies when the run finishes
- a build that signs notifies once, when signing starts
You can still sign them with `--sign` or `build.sign_binary`.
`upstream switch` and `build source` fail with "No such file or directory" when the orig tarball in `..` is a relative symlink (e.g. into the git-ubuntu cache).
Fix by resolving the symlink and replacing whatever is at the destination, dangling links included.
`--force` also removes dangling links.
debmagic tags its output dir and the orig download cache with a `CACHEDIR.TAG`, so backup tools skip them.
An untagged `build/` holding more than artifacts belongs to upstream: every command then uses `output_dir_fallback` (`build-debmagic` by default), or stops with `output_dir_clash = "fail"`.
`upstream switch` moves the output dir to the fallback when the new version starts shipping its name, instead of merging upstream's files into it.

Builds no longer treat the output dir's contents as source:
- it is never staged, in any `--source-sync` mode
- the untracked-files warning of `--source-sync tracked` skips it
TheJJ added 17 commits October 24, 2026 17:00
`build source` fails with "invalid deb822: expected key" when a
continuation field contains a `#` comment line (e.g. openldap's
Build-Depends). deb822-lossless >= 0.5 parses these like dpkg does;
raise it and debian-control >= 0.3, which depends on it.
A second `build source` empties the orig tarball (and the file it is
hardlinked to, e.g. in the git-ubuntu cache): the work dir already holds
a hardlink of it, and copying `..`'s symlink onto it truncates the shared
inode. Stage the tarballs from `..` and the test artifacts by replacing
the destination instead.
Before, `config set` changed the user-global config when debian/debmagic.toml was missing
Orig tarball naming, `is_source_changes` and `is_artifact_filename` need no `.changes` file, so they move to `debmagic_common::artifact`; `changes` keeps the `.changes` entry handling.
A fresh container ran apt-get update up to three times and four separate
dpkg transactions before building.

- container creation runs no apt (LXD) or bakes the refresh into the cached
  image (Docker); `--apt-update-age` then also applies to fresh Docker
  containers, measured from the image creation
- tooling and build dependencies install in one `apt-get satisfy`
  (`install` + `build-dep` before Debian 11 and Ubuntu 20.04)
- `--test=no` also sets the `nocheck` build profile, skipping test-only
  build dependencies
- build containers skip recommends, translations, index diffs, fsync,
  man-db rebuilds and service starts
- debmagic writes the `--apt-mirror`/`--proposed` sources itself, so
  containers no longer need python3
New releases and moving aliases needed a debmagic update. debmagic now
reads /usr/share/distro-info, or fetches the data into
~/.cache/debmagic/distro-info/ when that is missing or predates the
latest release, and derives `stable`, `oldstable`, `testing` and `devel`
from the release dates.

- `testing` is accepted as a suite alias
- the Debian package depends on distro-info-data
…sed`

`--proposed` now uses the suite the release's updates come from and takes
everything newer there, like Launchpad builds for -proposed:

- Ubuntu: `<release>-proposed`, pinned to the release's priority, since
  apt otherwise only upgrades installed packages from it
- Debian testing: unstable, instead of its proposed-updates, which only
  carries freeze exceptions
- Debian unstable: nothing, instead of an error

A build for experimental always gets unstable and experimental sources;
its install is retried preferring experimental when unstable alone
can't satisfy the build dependencies.
`--proposed=libfoo1,src:bar` takes only those packages from the proposed
suite, everything else stays with the release. `--experimental[=<packages>]`
adds experimental to unstable and testing builds; other releases reject it.
Both work for `debmagic test` too, to run a test suite against them.

In the config, `driver.proposed` and the new `driver.experimental` take a
bool or a list of packages.
The snap reads the release table from the distro-info-data it ships, or
from its base snap, and can fetch a newer one.
`debmagic test --proposed=libfoo1` (or `src:foo`, or `--experimental=...`)
runs the source tree's tests against that suite's build of the package
instead of a local one, so no prior `debmagic build` is needed. All its
binaries come from that suite, so their versions match.
`driver.apt_mirror`, `driver.apt_update_age`, `driver.proposed` and
`driver.experimental` are now `apt.mirror`, `apt.update_age`,
`apt.proposed` and `apt.experimental`. The old keys are rejected with
their new name. The CLI flags stay the same.
…--package`

`--package <package>[=<version>][/<archive>]` uses apt-get's syntax;
the archive is `release`, `proposed` or `experimental`. A version is
installed even if older. Naming the tested package makes `debmagic test`
test that build, e.g. `--package src:foo/release` for what the release
ships.

The config takes the same as `[apt.packages]`, e.g.
`"src:foo" = { from = "proposed" }`. `apt.proposed` and
`apt.experimental` are now bools; `--proposed=<packages>` stays a
shorthand for `--package <package>/proposed`.
`--archive [<name>=]ppa:<owner>/<name>[@<suite>]` adds a Launchpad PPA
to the environment, also as `[apt.archives]` in the config. Without
packages picked from it with `--package <package>/<name>`, apt takes all
newer ones from it. `--package libfoo1/ppa:me/stuff` adds the PPA itself.

Its signing key is looked up on Launchpad, fetched from
keyserver.ubuntu.com and checked against the fingerprint before anything
is built. Debian targets need the `@<suite>`.
Options pass through to apt, e.g. trusted=yes; a signed-by key file is read on the host and copied into the environment. Packages picked from such an archive are pinned by its host.
Add `debmagic env shell` and `debmagic env exec -- <command>...`, resolving container users and shells inside the Environment. Direct commands preserve terminal input and exit codes; both commands support `--user`/`-u` and default to root in containers.
@TheJJ
TheJJ requested a review from mikonse October 24, 2026 18:12

This branch has not been deployed

No deployments
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.

2 participants