diff --git a/src/build/mod.rs b/src/build/mod.rs index af33a4d..c943c01 100644 --- a/src/build/mod.rs +++ b/src/build/mod.rs @@ -458,8 +458,10 @@ pub fn run_source_build( if let Some(u) = &ui { u.progress_message("Generating .buildinfo"); } - let mut checksums = FileChecksums::new(); - checksums.add_file_as(&ref_dsc_path, &ref_dsc_name)?; + // What the .buildinfo itself records: like dpkg-genbuildinfo, only the + // referenced .dsc — not the tarballs, and never the buildinfo itself. + let mut buildinfo_checksums = FileChecksums::new(); + buildinfo_checksums.add_file_as(&ref_dsc_path, &ref_dsc_name)?; let status_path = PathBuf::from("/var/lib/dpkg/status"); let bd_fields = [ctrl.source.get("Build-Depends").unwrap_or("")]; @@ -484,7 +486,7 @@ pub fn run_source_build( environment: environment.clone(), }) }; - buildinfo::save_buildinfo(&buildinfo_path, &render_buildinfo_doc(&checksums))?; + buildinfo::save_buildinfo(&buildinfo_path, &render_buildinfo_doc(&buildinfo_checksums))?; // Register the .buildinfo in debian/files (as dpkg-genbuildinfo does). let files_path = cwd.join("debian/files"); @@ -506,6 +508,10 @@ pub fn run_source_build( if let Some(u) = &ui { u.progress_message("Generating .changes"); } + // What the .changes distributes: the .dsc (with its recorded digests), + // the tarballs listed in it (below), and the .buildinfo (last, as + // dpkg-genchanges does when it consumes debian/files). + let mut checksums = buildinfo_checksums.clone(); // Pull the tarball checksums out of the referenced .dsc so they are // distributed through the .changes like dpkg-genchanges does, in the // order the .dsc itself lists them. @@ -682,18 +688,22 @@ pub fn run_source_build( log::info!("Signing {}", dsc_name); crate::utils::gpg::clearsign_file(&dsc_path, &keyid)?; - // The freshly built .dsc changed: refresh its checksums inside the - // .buildinfo. For binary-only builds the metadata references the + // The freshly built .dsc changed: refresh its digests in both + // checksum sets. For binary-only builds the metadata references the // *previous* .dsc (untouched by this build), so there is nothing to // refresh. if !entry.binary_only { + buildinfo_checksums.add_file_as(&dsc_path, &dsc_name)?; checksums.add_file_as(&dsc_path, &dsc_name)?; } - buildinfo::save_buildinfo(&buildinfo_path, &render_buildinfo_doc(&checksums))?; + // Re-render the .buildinfo from its own set (the .dsc only, like + // dpkg-genbuildinfo): it must not list the tarballs or itself. + buildinfo::save_buildinfo(&buildinfo_path, &render_buildinfo_doc(&buildinfo_checksums))?; log::info!("Signing {}", buildinfo_name); crate::utils::gpg::clearsign_file(&buildinfo_path, &keyid)?; - // Both .dsc and .buildinfo changed: refresh the .changes. + // Both .dsc and .buildinfo changed: refresh the .changes with the + // signed buildinfo's fresh digests. checksums.add_file_as(&buildinfo_path, &buildinfo_name)?; changes::save_changes(&changes_path, &render_changes_doc(&checksums))?;