build: stop redistributing the previous source on binNMU uploads
dpkg-genchanges/genbuildinfo handle a binary-only upload by referencing the previous source version textually (Source: pkg (prev), Binary-Only: yes, Binary-Only-Changes) while distributing no source files at all: pkh instead pulled the previous .dsc and its tarballs into both documents whenever they sat next to the artifacts, re-uploading the whole source on every binNMU. Drop that redistribution (and include_dsc_artifacts with it), and emit the missing Binary-Only: yes field, which the new differential test against real dpkg-buildpackage -b caught. The binNMU case shares its runner with the regular binary metadata differential; a unit test pins the exclusion even with the previous artifacts present.
This commit is contained in:
+75
-16
@@ -638,6 +638,7 @@ pub fn run_source_build(
|
||||
date: entry.date_raw.clone(),
|
||||
source: source_display.clone(),
|
||||
binaries: Vec::new(), // source-only upload
|
||||
binary_only: entry.binary_only,
|
||||
built_for_profiles: profiles.clone(),
|
||||
architecture: "source".to_string(),
|
||||
version: entry.version.full(),
|
||||
@@ -1863,23 +1864,50 @@ Provides: virtual-thing (= 2.0), plain-virtual
|
||||
#[test]
|
||||
fn diff_binary_build_metadata() {
|
||||
const NAME: &str = "pkh-diff-m";
|
||||
let control = format!(
|
||||
"Source: {NAME}\nSection: utils\nPriority: optional\nMaintainer: {MAINTAINER}\nBuild-Depends: libc6\n\n\
|
||||
Package: {NAME}\nArchitecture: any\nDescription: test package main\n long description\n\n\
|
||||
Package: {NAME}-u\nPackage-Type: udeb\nArchitecture: all\nDescription: test udeb\n short\n"
|
||||
);
|
||||
let changelog = format!(
|
||||
"{NAME} (1.0-1) unstable; urgency=medium\n\n * Binary build test.\n\n -- {MAINTAINER} {DATE}\n"
|
||||
);
|
||||
let rules = format!(
|
||||
"#!/usr/bin/make -f\nV = $(shell dpkg-parsechangelog -S Version)\nA = $(shell dpkg-architecture -qDEB_HOST_ARCH)\n\nbuild:\n\tmkdir -p debian/tmp/usr/bin\n\tprintf '#!/bin/sh\\necho hi\\n' > debian/tmp/usr/bin/hello\n\tchmod 755 debian/tmp/usr/bin/hello\n\ttouch $@\n\nbinary: build\n\trm -rf debian/{NAME} debian/{NAME}-u\n\tmkdir -p debian/{NAME}/usr/bin debian/{NAME}/DEBIAN\n\tcp -r debian/tmp/. debian/{NAME}/\n\tdpkg-gencontrol -p{NAME} -Pdebian/{NAME}\n\tdpkg-deb --build debian/{NAME} ..\n\tmkdir -p debian/{NAME}-u/usr/share debian/{NAME}-u/DEBIAN\n\techo data > debian/{NAME}-u/usr/share/data.txt\n\tdpkg-gencontrol -p{NAME}-u -Pdebian/{NAME}-u\n\tdpkg-deb --build debian/{NAME}-u ..\n\tmv ../{NAME}-u_$(V)_all.deb ../{NAME}-u_$(V)_all.udeb\n\nclean:\n\trm -rf debian/tmp debian/{NAME} debian/{NAME}-u build-stamp debian/files debian/*.substvars\n\n.PHONY: build binary clean\n"
|
||||
);
|
||||
diff_binary_metadata_case(NAME, &changelog, "1.0-1", false);
|
||||
}
|
||||
|
||||
/// debian/control shared by the binary-metadata differential cases: one
|
||||
/// arch:any deb and one arch:all udeb.
|
||||
fn binary_test_control(name: &str) -> String {
|
||||
format!(
|
||||
"Source: {name}\nSection: utils\nPriority: optional\nMaintainer: {MAINTAINER}\nBuild-Depends: libc6\n\n\
|
||||
Package: {name}\nArchitecture: any\nDescription: test package main\n long description\n\n\
|
||||
Package: {name}-u\nPackage-Type: udeb\nArchitecture: all\nDescription: test udeb\n short\n"
|
||||
)
|
||||
}
|
||||
|
||||
/// debian/rules driving dpkg-gencontrol/dpkg-deb directly (no debhelper).
|
||||
fn binary_test_rules(name: &str) -> String {
|
||||
format!(
|
||||
"#!/usr/bin/make -f\nV = $(shell dpkg-parsechangelog -S Version)\nA = $(shell dpkg-architecture -qDEB_HOST_ARCH)\n\nbuild:\n\tmkdir -p debian/tmp/usr/bin\n\tprintf '#!/bin/sh\\necho hi\\n' > debian/tmp/usr/bin/hello\n\tchmod 755 debian/tmp/usr/bin/hello\n\ttouch $@\n\nbinary: build\n\trm -rf debian/{name} debian/{name}-u\n\tmkdir -p debian/{name}/usr/bin debian/{name}/DEBIAN\n\tcp -r debian/tmp/. debian/{name}/\n\tdpkg-gencontrol -p{name} -Pdebian/{name}\n\tdpkg-deb --build debian/{name} ..\n\tmkdir -p debian/{name}-u/usr/share debian/{name}-u/DEBIAN\n\techo data > debian/{name}-u/usr/share/data.txt\n\tdpkg-gencontrol -p{name}-u -Pdebian/{name}-u\n\tdpkg-deb --build debian/{name}-u ..\n\tmv ../{name}-u_$(V)_all.deb ../{name}-u_$(V)_all.udeb\n\nclean:\n\trm -rf debian/tmp debian/{name} debian/{name}-u build-stamp debian/files debian/*.substvars\n\n.PHONY: build binary clean\n"
|
||||
)
|
||||
}
|
||||
|
||||
/// Both-sides binary metadata comparison for one changelog: golden
|
||||
/// `dpkg-buildpackage -b` against the pkh deb flow (rules targets with a
|
||||
/// dpkg-buildpackage-like environment) plus native metadata generation.
|
||||
/// `artifact_version` is the full version the artifacts are named after;
|
||||
/// `with_prev_source` additionally places the previous version's `.dsc`
|
||||
/// and tarball next to the tree on both sides (the binNMU trap: they must
|
||||
/// not be redistributed).
|
||||
fn diff_binary_metadata_case(
|
||||
name: &str,
|
||||
changelog: &str,
|
||||
artifact_version: &str,
|
||||
with_prev_source: bool,
|
||||
) {
|
||||
let control = binary_test_control(name);
|
||||
let rules = binary_test_rules(name);
|
||||
|
||||
let write_tree = |root: &Path| {
|
||||
fs::create_dir_all(root.join(format!("{NAME}/debian/source"))).expect("mkdir tree");
|
||||
let tree = root.join(NAME);
|
||||
fs::create_dir_all(root.join(format!("{name}/debian/source"))).expect("mkdir tree");
|
||||
let tree = root.join(name);
|
||||
fs::write(tree.join("debian/control"), &control).expect("write control");
|
||||
fs::write(tree.join("debian/changelog"), &changelog).expect("write changelog");
|
||||
fs::write(tree.join("debian/changelog"), changelog).expect("write changelog");
|
||||
fs::write(tree.join("debian/source/format"), "3.0 (native)\n").expect("write format");
|
||||
fs::write(tree.join("debian/rules"), &rules).expect("write rules");
|
||||
#[cfg(unix)]
|
||||
@@ -1900,6 +1928,20 @@ Provides: virtual-thing (= 2.0), plain-virtual
|
||||
let golden_tree = write_tree(&golden_root);
|
||||
let ours_tree = write_tree(&ours_root);
|
||||
|
||||
if with_prev_source {
|
||||
for root in [&golden_root, &ours_root] {
|
||||
let dsc = format!(
|
||||
"Format: 3.0 (native)\nSource: {name}\nBinary: {name}\nArchitecture: all\n\
|
||||
Version: 1.0-1\nMaintainer: {MAINTAINER}\nChecksums-Sha1:\n aaa111 12 \
|
||||
{name}_1.0.tar.xz\nChecksums-Sha256:\n bbb222 12 {name}_1.0.tar.xz\nFiles:\n \
|
||||
ddd333 12 utils optional {name}_1.0.tar.xz\n"
|
||||
);
|
||||
fs::write(root.join(format!("{name}_1.0-1.dsc")), dsc).expect("write previous dsc");
|
||||
fs::write(root.join(format!("{name}_1.0.tar.xz")), "tarball byte")
|
||||
.expect("write previous tarball");
|
||||
}
|
||||
}
|
||||
|
||||
// Golden side: real dpkg-buildpackage binary build.
|
||||
let status = crate::test_support::run_logged(
|
||||
Command::new("dpkg-buildpackage")
|
||||
@@ -1915,7 +1957,7 @@ Provides: virtual-thing (= 2.0), plain-virtual
|
||||
// rules targets directly by default (missing Rules-Requires-Root is
|
||||
// treated as 'no'), so no fakeroot wrapper here either.
|
||||
let entry =
|
||||
crate::debian::parse_changelog_entry_from_str(&changelog).expect("parse changelog");
|
||||
crate::debian::parse_changelog_entry_from_str(changelog).expect("parse changelog");
|
||||
let vendor = env::current_vendor();
|
||||
let profiles = env::resolve_build_profiles(&[], &vendor);
|
||||
let parallel = env::num_parallel();
|
||||
@@ -1959,15 +2001,32 @@ Provides: virtual-thing (= 2.0), plain-virtual
|
||||
|
||||
// Compare artifacts.
|
||||
assert_changes_equivalent(
|
||||
&golden_root.join(format!("{NAME}_1.0-1_amd64.changes")),
|
||||
&ours_root.join(format!("{NAME}_1.0-1_amd64.changes")),
|
||||
&golden_root.join(format!("{name}_{artifact_version}_amd64.changes")),
|
||||
&ours_root.join(format!("{name}_{artifact_version}_amd64.changes")),
|
||||
);
|
||||
assert_buildinfo_equivalent(
|
||||
&golden_root.join(format!("{NAME}_1.0-1_amd64.buildinfo")),
|
||||
&ours_root.join(format!("{NAME}_1.0-1_amd64.buildinfo")),
|
||||
&golden_root.join(format!("{name}_{artifact_version}_amd64.buildinfo")),
|
||||
&ours_root.join(format!("{name}_{artifact_version}_amd64.buildinfo")),
|
||||
);
|
||||
}
|
||||
|
||||
/// Differential check of the binary-only (binNMU) metadata against real
|
||||
/// `dpkg-buildpackage -b`: with the previous source artifacts sitting
|
||||
/// next to the tree (as after a source build), the `.changes` must
|
||||
/// distribute only the binaries and the `.buildinfo`, both documents
|
||||
/// referencing the previous version textually only. Regression guard for
|
||||
/// the previous-source redistribution pkh used to emit.
|
||||
#[test]
|
||||
fn diff_binmu_binary_metadata() {
|
||||
const NAME: &str = "pkh-diff-r";
|
||||
let changelog = format!(
|
||||
"{NAME} (1.0-1+b1) unstable; urgency=medium, binary-only=yes\n\n * Binary-only \
|
||||
rebuild.\n\n -- {MAINTAINER} {DATE}\n\n{NAME} (1.0-1) unstable; urgency=medium\n\n \
|
||||
* Initial release.\n\n -- {MAINTAINER} {DATE}\n"
|
||||
);
|
||||
diff_binary_metadata_case(NAME, &changelog, "1.0-1+b1", true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn diff_native_minimal() {
|
||||
differential_case(&FixtureSpec::new("pkh-diff-a", "1.0-1", "unstable"));
|
||||
|
||||
Reference in New Issue
Block a user