deb: retrieve only the artifacts produced by the build, not globbed files
CI / build (push) Failing after 53s
CI / test (push) Skipped
CI / snap (push) Skipped

build_binary_package_impl copied the whole parent directory into the
build root (ensure_available) and then retrieved every *.deb / *.changes
/ *.buildinfo it found there. That surfaced stale files already sitting
next to the package tree in the "Built in Ns:" summary.

Now local::build returns the exact set of artifacts produced by this
build — the binary packages registered in debian/files plus the
generated .buildinfo/.changes from generate_binary_metadata — and
build_binary_package_impl retrieves that list instead of globbing the
build root. Only files genuinely produced by the current build are
printed.
This commit is contained in:
2026-09-10 15:30:06 +02:00
parent 182a06ffbe
commit c7af3bc9b1
2 changed files with 71 additions and 37 deletions
+52 -14
View File
@@ -7,7 +7,7 @@ use crate::ui::logfmt::QuiltClassifier;
use log::warn;
use std::collections::HashMap;
use std::error::Error;
use std::path::Path;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use crate::apt;
@@ -38,7 +38,7 @@ pub async fn build(
ctx: Arc<Context>,
ui: Option<Arc<DebUi>>,
jobs: Option<usize>,
) -> Result<(), Box<dyn Error>> {
) -> Result<Vec<PathBuf>, Box<dyn Error>> {
let sink: Option<Arc<dyn LineSink>> = ui.as_ref().map(|u| u.sink());
// Environment
@@ -334,15 +334,60 @@ pub async fn build(
);
}
// Collect the exact set of artifacts produced by this build so the caller
// retrieves only those: the binary packages registered in debian/files
// (the contract between dh_builddeb/dpkg-gencontrol and the artifact
// generators) plus the .buildinfo/.changes generated below. This avoids
// globbing the build root, which would also surface stale files copied
// alongside the package tree.
let mut artifacts = collect_binary_artifacts(&ctx, package_dir_str, build_root)?;
// Generate the upload metadata (.buildinfo + .changes) natively, the
// equivalent of dpkg-genbuildinfo -b + dpkg-genchanges -b, consuming
// debian/files produced by the build. Failures are logged but do not
// discard the produced binaries.
if let Err(e) = generate_upload_metadata(package_dir_str, build_root, arch, cross, &env, &ctx) {
warn!("failed to generate .buildinfo/.changes: {}", e);
match generate_upload_metadata(package_dir_str, build_root, arch, cross, &env, &ctx) {
Ok((buildinfo, changes)) => {
log::info!(
"generated upload metadata: {} and {}",
buildinfo.display(),
changes.display()
);
artifacts.push(buildinfo);
artifacts.push(changes);
}
Err(e) => {
warn!("failed to generate .buildinfo/.changes: {}", e);
}
}
Ok(())
Ok(artifacts)
}
/// Collect the binary artifacts (.deb/.udeb) registered by the build in
/// `debian/files`, returning their paths inside the build context
/// (`<build_root>/<filename>`). `debian/files` is the canonical record of
/// which binary packages `debian/rules binary` produced, so we retrieve
/// exactly those instead of globbing the build root (which would also pick
/// up stale files copied alongside the package tree).
fn collect_binary_artifacts(
ctx: &Arc<Context>,
package_dir: &str,
build_root: &str,
) -> Result<Vec<PathBuf>, Box<dyn Error>> {
let files_content = ctx
.read_file(&Path::new(package_dir).join("debian/files"))
.unwrap_or_default();
let files_list = crate::debian::FilesList::parse(&files_content)
.map_err(|e| format!("invalid debian/files in {package_dir}: {e}"))?;
let upload_dir = Path::new(build_root);
let mut artifacts = Vec::new();
for entry in files_list.iter() {
if matches!(entry.package_type.as_deref(), Some("deb") | Some("udeb")) {
artifacts.push(upload_dir.join(&entry.filename));
}
}
Ok(artifacts)
}
/// Generate `.buildinfo` and `.changes` for the finished binary build,
@@ -354,9 +399,7 @@ fn generate_upload_metadata(
cross: bool,
env: &HashMap<String, String>,
ctx: &Arc<Context>,
) -> Result<(), Box<dyn Error>> {
use std::path::Path;
) -> Result<(PathBuf, PathBuf), Box<dyn Error>> {
let changelog_path = Path::new(package_dir).join("debian/changelog");
let changelog_content = ctx.read_file(&changelog_path)?;
let entry = crate::debian::parse_changelog_entry_from_str(&changelog_content)?;
@@ -414,12 +457,7 @@ fn generate_upload_metadata(
Path::new(build_root),
&opts,
)?;
log::info!(
"generated upload metadata: {} and {}",
buildinfo.display(),
changes.display()
);
Ok(())
Ok((buildinfo, changes))
}
/// Apply quilt patches before building, if the package provides a