Hi!
Here's an initial draft of the pristine-tar support. More than something
intended to be merged in, this is just a way to get some feedback,
trying to understand if I'm on the right track.
I did two things:
1. Added a new pristine-tar=commit_id metadata field to the signed tag
generated by git-debpush
2. If a pristine-tar commitid is present, the git repo is hard-reset to
it, then the tarball name is obtained from the tree, and
`pristine-tar checkout` is invoked to generate the tarball.
I believe this is safe security-wise because the commit id represented
the expected status of the pristine-tar branch on the developer's
machine is signed at the time of the upload. If for some reason the
branch gets in-between the upload, and the expected commit is lost,
things will just fail instead of generating a "wrong" tarball. Do you
see flaws in this reasoning?
Note: I did not test that my implementation is actually correct and
working. I did not add any new test either. I believe there are no
regressions in old tests but I'm testing this on a plane and didn't look
too much into the log output.
Let me know that you think! Bye :)
---
git-debpush | 12 +++++++++++-
infra/dgit-repos-server | 5 ++++-
tag2upload-obtain-origs | 23 ++++++++++++++++++++++-
3 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/git-debpush b/git-debpush
index e3a4ba39..1782513e 100755
--- a/git-debpush
+++ b/git-debpush
@@ -457,6 +457,16 @@ if $upstream; then
to_push+=("$upstream_tag")
fi
+# TODO: pristine-tar
+# I obtain the commit ID at the time of the upload, so that I can be sure that
+# the tag2upload service generates the tarball with the expected pristine-tar
+# branch state
+pristine_tar_info=''
+if pristine_tar_commit=$(git rev-parse --verify --quiet
'refs/heads/pristine-tar'); then
+ pristine_tar_info=" pristine-tar=$pristine_tar_commit"
+fi
+
+
#**** Useful sanity checks ****
#---- UNRELEASED suite
@@ -837,7 +847,7 @@ fi
tagmessage="$source release $version for $target
[dgit distro=$distro split$quilt_mode_text]
-[dgit please-upload source=$source version=$version$upstream_info]
+[dgit please-upload source=$source
version=$version$upstream_info$pristine_tar_info]
"
git_tag_main_opts_args=(-m "$tagmessage" "$debian_tag" "$branch_commit")
diff --git a/infra/dgit-repos-server b/infra/dgit-repos-server
index f6a3716c..e797123b 100755
--- a/infra/dgit-repos-server
+++ b/infra/dgit-repos-server
@@ -1304,7 +1304,7 @@ our ($t2u_email_noreply, $t2u_email_noreply_addr,
$t2u_email_reply_to,
@t2u_email_copies, $t2u_jid, $t2u_url, $t2u_putative_package);
our ($t2u_tagger, $t2u_tagger_addr, $t2u_timeout);
our ($t2u_signing_keyid);
-our ($t2u_upstreamc, $t2u_upstreamt, $t2u_quilt);
+our ($t2u_upstreamc, $t2u_upstreamt, $t2u_quilt, $t2u_pristinetar);
sub t2u_dgit_cmd () {
(
@@ -1840,6 +1840,8 @@ sub tag2upload_parsetag ($) {
$package = $1;
} elsif (s/^version=(\S+) //) {
$tagversion = $1;
+ } elsif (s/^pristine-tar=(\w+) //) {
+ $t2u_pristinetar = $1;
} else {
return 0;
}
@@ -2030,6 +2032,7 @@ END
"v=$version",
"s=$suite",
"u=$t2u_upstreamc",
+ "pristinetar=$t2u_pristinetar",
);
flush EMAIL_REPORT or confess $!;
open STDOUT, ">& EMAIL_REPORT" or confess $!;
diff --git a/tag2upload-obtain-origs b/tag2upload-obtain-origs
index 016fa655..0453c2de 100755
--- a/tag2upload-obtain-origs
+++ b/tag2upload-obtain-origs
@@ -16,6 +16,7 @@
# optional settings:
#
# bpd defaults to ../bpd
+# pristinetar=PRISTINE-TAR-COMMITID
set -eu -o pipefail
shopt -s inherit_errexit # #514862, wtf
@@ -96,7 +97,27 @@ case "$rc" in
;;
esac
-x git deborig "$s_u"
+if [ -n "$s_pristinetar" ]; then
+ old_head=$(git rev-parse --verify HEAD)
+ git reset --hard -- "$s_pristinetar"
+
+ # Only get the first tarball file matching the current package version.
+ # pristine-tar does not disallow having two tarballs for the same package
+ # version using different compression algorithms, so this will just pick a
+ # random one. It might make sense to error out instead in such cases.
+ tarball=$(git ls-tree --name-only | while IFS= read -r file; do
+ case "$file" in
+ "${s_p}_${fversion}.orig.*.id") printf '%s\n' "${file%.id}"
+ break ;;
+ esac
+ done)
+
+ x pristine-tar checkout "$tarball"
+ git reset --hard -- "$old_head"
+else
+ x git deborig "$s_u"
+fi
+
report 'created orig'
--
2.47.2