threads / patch / 47038

patchtag: add tag.gpgSign config option to force all tags be GPG-signed

Subject: [PATCH] tag: add tag.gpgSign config option to force all tags be GPG-signed

## tl;dr

7 messages between Oct 26, 2017 and Oct 28, 2017. Diffs are folded; open one to read it.

replies: 6people: 4as markdown or json

Tigran Mkrtchyan· Oct 26, 2017, 19:55 UTC · lore

In some workflows we have no control on how git command is executed, however a signed tags are required.

The new config-file option tag.gpgSign enforces signed tags. Additional command line option --no-gpg-sign is added to disable such behavior if needed. E.g.:

    $ git tag -m "commit message"
will generate a GPG signed tag if tag.gpgSign option is true, while
    $ git tag --no-gpg-sign -m "commit message"
will skip the signing step.
Signed-off-by: Tigran Mkrtchyan <tigran.mkrtchyan@desy.de>
---
 Documentation/config.txt               |  4 ++++
 Documentation/git-tag.txt              |  4 ++++
 builtin/tag.c                          | 18 +++++++++++++++---
 contrib/completion/git-completion.bash |  1 +
 t/t7004-tag.sh                         | 21 +++++++++++++++++++++
 5 files changed, 45 insertions(+), 3 deletions(-)
Show changes to 5 files +45 −3

Documentation/config.txt, Documentation/git-tag.txt, builtin/tag.c, contrib/completion/git-completion.bash, t/t7004-tag.sh

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 1ac0ae6ad..fa6694bec 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -3161,6 +3161,10 @@ tag.forceSignAnnotated::
 	If `--annotate` is specified on the command line, it takes
 	precedence over this option.
 
+tag.gpgSign::
+
+	A boolean to specify whether all tags should be GPG signed.
+
 tag.sort::
 	This variable controls the sort ordering of tags when displayed by
 	linkgit:git-tag[1]. Without the "--sort=<value>" option provided, the
diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index 956fc019f..1dd43f18b 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -181,6 +181,10 @@ This option is only applicable when listing tags without annotation lines.
 	`--create-reflog`, but currently does not negate the setting of
 	`core.logAllRefUpdates`.
 
+--no-gpg-sign::
+	Countermand `tag.gpgSign` configuration variable that is
+	set to force each and every tag to be signed.
+
 <tagname>::
 	The name of the tag to create, delete, or describe.
 	The new tag name must pass all checks defined by
diff --git a/builtin/tag.c b/builtin/tag.c
index b38329b59..d9060a404 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -31,6 +31,7 @@ static const char * const git_tag_usage[] = {
 
 static unsigned int colopts;
 static int force_sign_annotate;
+static int sign_tag;
 
 static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting,
 		     struct ref_format *format)
@@ -141,6 +142,11 @@ static int git_tag_config(const char *var, const char *value, void *cb)
 	int status;
 	struct ref_sorting **sorting_tail = (struct ref_sorting **)cb;
 
+	if (!strcmp(var, "tag.gpgsign")) {
+		sign_tag = git_config_bool(var, value);
+		return 0;
+	}
+
 	if (!strcmp(var, "tag.sort")) {
 		if (!value)
 			return config_error_nonbool(var);
@@ -372,6 +378,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 	static struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;
 	struct ref_format format = REF_FORMAT_INIT;
 	int icase = 0;
+	int no_gpg_sign = 0;
 	struct option options[] = {
 		OPT_CMDMODE('l', "list", &cmdmode, N_("list tag names"), 'l'),
 		{ OPTION_INTEGER, 'n', NULL, &filter.lines, N_("n"),
@@ -393,6 +400,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 					N_("use another key to sign the tag")),
 		OPT__FORCE(&force, N_("replace the tag if exists")),
 		OPT_BOOL(0, "create-reflog", &create_reflog, N_("create a reflog")),
+		OPT_BOOL(0, "no-gpg-sign", &no_gpg_sign, N_("do not GPG-sign tag")),
 
 		OPT_GROUP(N_("Tag listing options")),
 		OPT_COLUMN(0, "column", &colopts, N_("show tag list in columns")),
@@ -426,6 +434,10 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 
 	argc = parse_options(argc, argv, prefix, options, git_tag_usage, 0);
 
+	if (no_gpg_sign) {
+		sign_tag = 0;
+	}
+
 	if (keyid) {
 		opt.sign = 1;
 		set_signing_key(keyid);
@@ -444,7 +456,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 	if (cmdmode == 'l')
 		setup_auto_pager("tag", 1);
 
-	if ((create_tag_object || force) && (cmdmode != 0))
+	if ((create_tag_object || force || no_gpg_sign) && (cmdmode != 0))
 		usage_with_options(git_tag_usage, options);
 
 	finalize_colopts(&colopts, -1);
@@ -536,8 +548,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 
 	create_reflog_msg(&object, &reflog_msg);
 
-	if (create_tag_object) {
-		if (force_sign_annotate && !annotate)
+	if (create_tag_object || sign_tag) {
+		if (sign_tag || (force_sign_annotate && !annotate))
 			opt.sign = 1;
 		create_tag(&object, tag, &buf, &opt, &prev, &object);
 	}
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 0e16f017a..0dbe689a2 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2648,6 +2648,7 @@ _git_config ()
 		status.showUntrackedFiles
 		status.submodulesummary
 		submodule.
+		tag.gpgSign
 		tar.umask
 		transfer.unpackLimit
 		url.
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index a9af2de99..ccff37733 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -904,6 +904,27 @@ test_expect_success GPG \
 	test_cmp expect actual
 '
 
+get_tag_header gpgsign-enabled $commit commit $time >expect
+echo "A message" >>expect
+echo '-----BEGIN PGP SIGNATURE-----' >>expect
+test_expect_success GPG \
+	'git tag configured tag.gpgsign enables GPG sign' \
+	'test_config tag.gpgsign true &&
+	git tag -m "A message" gpgsign-enabled &&
+	get_tag_msg gpgsign-enabled>actual &&
+	test_cmp expect actual
+'
+
+get_tag_header no-gpg-sign $commit commit $time >expect
+echo "A message" >>expect
+test_expect_success GPG \
+	'git tag --no-gpg-sign configured tag.gpgsign skip GPG sign' \
+	'test_config tag.gpgsign true &&
+	git tag -a --no-gpg-sign -m "A message" no-gpg-sign &&
+	get_tag_msg no-gpg-sign>actual &&
+	test_cmp expect actual
+'
+
 test_expect_success GPG \
 	'trying to create a signed tag with non-existing -F file should fail' '
 	! test -f nonexistingfile &&
-- 
2.13.6
Jonathan Nieder· Oct 26, 2017, 20:55 UTC · re: Tigran Mkrtchyan · lore

Re: [PATCH] tag: add tag.gpgSign config option to force all tags be GPG-signed

Hi,
Tigran Mkrtchyan wrote:
> In some workflows we have no control on how git command is executed,
> however a signed tags are required.

Don't leave me hanging: this leaves me super curious. Can you tell me more about these workflows?

Thanks and hope that helps, Jonathan

Mkrtchyan, Tigran· Oct 26, 2017, 21:01 UTC · re: Jonathan Nieder · lore

Re: [PATCH] tag: add tag.gpgSign config option to force all tags be GPG-signed

Well, this is a build/release process where we can't pass additional command line options to git. TO be hones, is case of annotated tags there is already option tag.forceSignAnnotated. However, non annotated tags are not forced to be signed.

Additionally, the proposed option is symmetric with commit.gpgSign.
Tigran.
----- Original Message -----
Show 5 quoted lines
> From: "Jonathan Nieder" <jrnieder@gmail.com>
> To: "Tigran Mkrtchyan" <tigran.mkrtchyan@desy.de>
> Cc: git@vger.kernel.org
> Sent: Thursday, October 26, 2017 10:55:09 PM
> Subject: Re: [PATCH] tag: add tag.gpgSign config option to force all tags be GPG-signed
Show 12 quoted lines
> Hi,
> 
> Tigran Mkrtchyan wrote:
> 
>> In some workflows we have no control on how git command is executed,
>> however a signed tags are required.
> 
> Don't leave me hanging: this leaves me super curious.  Can you tell me
> more about these workflows?
> 
> Thanks and hope that helps,
> Jonathan
Jonathan Nieder· Oct 26, 2017, 21:33 UTC · re: Mkrtchyan, Tigran · lore

Re: [PATCH] tag: add tag.gpgSign config option to force all tags be GPG-signed

Hi again,
Mkrtchyan, Tigran wrote:
> Jonathan Nieder wrote:
>> Tigran Mkrtchyan wrote:
Show 12 quoted lines
>>> In some workflows we have no control on how git command is executed,
>>> however a signed tags are required.
>>
>> Don't leave me hanging: this leaves me super curious.  Can you tell me
>> more about these workflows?
>
> Well, this is a build/release process where we can't pass additional
> command line options to git. TO be hones, is case of annotated tags
> there is already option tag.forceSignAnnotated. However, non annotated
> tags are not forced to be signed.
>
> Additionally, the proposed option is symmetric with commit.gpgSign.
Now I'm even more curious.

I don't think we have the full picture to understand whether this change is needed. When adding a configuration item, we need to be able to explain to users what the configuration item is for, and so far the only answer I am hearing is "because we do not want to patch our build/release script, though we could in principle". That doesn't sound like a compelling reason.

On the other hand, perhaps the answer is "our build/release script does not have a --sign option for the following reason, and this is a better interface for configuring it".

Or perhaps there is an answer that does not involve the build/release script.

But with no answer at all, it is hard to see why we should move forward on this patch.

To be clear, I am not saying that writing the patch is wasted effort. E.g. you can continue to use it internally, and it means that once we have a clear reason to add this configuration, the patch is there and ready to use to do so.

Thanks again, Jonathan

Stefan Beller· Oct 26, 2017, 21:45 UTC · re: Jonathan Nieder · lore

Re: [PATCH] tag: add tag.gpgSign config option to force all tags be GPG-signed

On Thu, Oct 26, 2017 at 2:33 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:
Show 20 quoted lines
> Hi again,
>
> Mkrtchyan, Tigran wrote:
>> Jonathan Nieder wrote:
>>> Tigran Mkrtchyan wrote:
>
>>>> In some workflows we have no control on how git command is executed,
>>>> however a signed tags are required.
>>>
>>> Don't leave me hanging: this leaves me super curious.  Can you tell me
>>> more about these workflows?
>>
>> Well, this is a build/release process where we can't pass additional
>> command line options to git. TO be hones, is case of annotated tags
>> there is already option tag.forceSignAnnotated. However, non annotated
>> tags are not forced to be signed.
>>
>> Additionally, the proposed option is symmetric with commit.gpgSign.
>
> Now I'm even more curious.

I started digging and found https://public-inbox.org/git/20131105112840.GZ4589@mars-attacks.org/ which is an answer to "Why do we have commit.gpgSign?" which is a very similar question to begin with.

Maybe the answer is also similar (bonus points if the answer also touches when to prefer one over the other)?

Mkrtchyan, Tigran· Oct 27, 2017, 07:41 UTC · re: Jonathan Nieder · lore

Re: [PATCH] tag: add tag.gpgSign config option to force all tags be GPG-signed

Hi Jonathan,

I can't disagree with you - the right solution is to fix the build/release process to support signed tagging. It's just too many of them to fix: jenkins, maven, IDE, etc. My naive assumption was that if a tool (git) has a switch to enable some functionality, why not have a possibility to make it default.

You can put this change on hold and re-consider it if more people will need such functionality.
Thanks,
   Tigran.
----- Original Message -----
Show 5 quoted lines
> From: "Jonathan Nieder" <jrnieder@gmail.com>
> To: "Tigran Mkrtchyan" <tigran.mkrtchyan@desy.de>
> Cc: "git" <git@vger.kernel.org>
> Sent: Thursday, October 26, 2017 11:33:37 PM
> Subject: Re: [PATCH] tag: add tag.gpgSign config option to force all tags be GPG-signed
Show 45 quoted lines
> Hi again,
> 
> Mkrtchyan, Tigran wrote:
>> Jonathan Nieder wrote:
>>> Tigran Mkrtchyan wrote:
> 
>>>> In some workflows we have no control on how git command is executed,
>>>> however a signed tags are required.
>>>
>>> Don't leave me hanging: this leaves me super curious.  Can you tell me
>>> more about these workflows?
>>
>> Well, this is a build/release process where we can't pass additional
>> command line options to git. TO be hones, is case of annotated tags
>> there is already option tag.forceSignAnnotated. However, non annotated
>> tags are not forced to be signed.
>>
>> Additionally, the proposed option is symmetric with commit.gpgSign.
> 
> Now I'm even more curious.
> 
> I don't think we have the full picture to understand whether this
> change is needed.  When adding a configuration item, we need to be
> able to explain to users what the configuration item is for, and so
> far the only answer I am hearing is "because we do not want to patch
> our build/release script, though we could in principle".  That doesn't
> sound like a compelling reason.
> 
> On the other hand, perhaps the answer is "our build/release script
> does not have a --sign option for the following reason, and this is a
> better interface for configuring it".
> 
> Or perhaps there is an answer that does not involve the build/release
> script.
> 
> But with no answer at all, it is hard to see why we should move
> forward on this patch.
> 
> To be clear, I am not saying that writing the patch is wasted effort.
> E.g. you can continue to use it internally, and it means that once we
> have a clear reason to add this configuration, the patch is there and
> ready to use to do so.
> 
> Thanks again,
> Jonathan
brian m. carlson· Oct 28, 2017, 17:17 UTC · re: Jonathan Nieder · lore

Re: [PATCH] tag: add tag.gpgSign config option to force all tags be GPG-signed

On Thu, Oct 26, 2017 at 02:33:37PM -0700, Jonathan Nieder wrote:
Show 15 quoted lines
> Now I'm even more curious.
> 
> I don't think we have the full picture to understand whether this
> change is needed.  When adding a configuration item, we need to be
> able to explain to users what the configuration item is for, and so
> far the only answer I am hearing is "because we do not want to patch
> our build/release script, though we could in principle".  That doesn't
> sound like a compelling reason.
> 
> On the other hand, perhaps the answer is "our build/release script
> does not have a --sign option for the following reason, and this is a
> better interface for configuring it".
> 
> Or perhaps there is an answer that does not involve the build/release
> script.

I think this option is potentially quite useful. Say we have a policy which requires signed tags for auditability reasons. Shipping a standard system-wide gitconfig to all systems with this option can be very useful and is easier than relying on individuals remembering the required options. Otherwise, somebody might create a lightweight tag (or an unsigned tag) and push it by accident, which would be hard to undo (because tags aren't overwritten).

In my open-source projects, I always want to create a signed tag, so I would find this option useful. The only time I want a lightweight tag is in creating ephemeral repositories, and I can script that into my alias.

-- 
brian m. carlson / brian with sandals: Houston, Texas, US
https://www.crustytoothpaste.net/~bmc | My opinion only
OpenPGP: https://keybase.io/bk2204

← back to recent threads