Description
Description
I am using GitPython
to sign tags as such:
repo.git.tag(
"-s",
"v{}".format(str(new_version)),
"-m Version {}".format(str(new_version)),
)
This fails with the following error/exception:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/jgalar/.cache/pypoetry/virtualenvs/reml-06EzQDmo-py3.9/lib/python3.9/site-packages/click/core.py", line 829, in __call__
return self.main(*args, **kwargs)
File "/home/jgalar/.cache/pypoetry/virtualenvs/reml-06EzQDmo-py3.9/lib/python3.9/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/home/jgalar/.cache/pypoetry/virtualenvs/reml-06EzQDmo-py3.9/lib/python3.9/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/jgalar/.cache/pypoetry/virtualenvs/reml-06EzQDmo-py3.9/lib/python3.9/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/home/jgalar/EfficiOS/src/reml/reml/cli.py", line 93, in main
release = project.release(
File "/home/jgalar/EfficiOS/src/reml/reml/project.py", line 443, in release
self._commit_and_tag(new_version)
File "/home/jgalar/EfficiOS/src/reml/reml/lttngtools.py", line 41, in _commit_and_tag
self._repo.git.tag(
File "/home/jgalar/.cache/pypoetry/virtualenvs/reml-06EzQDmo-py3.9/lib/python3.9/site-packages/git/cmd.py", line 545, in <lambda>
return lambda *args, **kwargs: self._call_process(name, *args, **kwargs)
File "/home/jgalar/.cache/pypoetry/virtualenvs/reml-06EzQDmo-py3.9/lib/python3.9/site-packages/git/cmd.py", line 1011, in _call_process
return self.execute(call, **exec_kwargs)
File "/home/jgalar/.cache/pypoetry/virtualenvs/reml-06EzQDmo-py3.9/lib/python3.9/site-packages/git/cmd.py", line 828, in execute
raise GitCommandError(command, status, stderr_value, stdout_value)
git.exc.GitCommandError: Cmd('git') failed due to: exit code(128)
cmdline: git tag -s v2.12.4 -m Version 2.12.4
stderr: 'error: gpg failed to sign the data
error: unable to sign the tag'
Debugging the problem
I was initially confused since I can sign tags correctly from the command line using the git tag -s ...
command directly.
Digging a bit, I saw that git
invokes gpg
with the following arguments both when I tag using the git
client directly or when using GitPython
.
argv[0] = /usr/bin/gpg2
argv[1] = --status-fd=2
argv[2] = -bsau
argv[3] = Jérémie Galarneau <jeremie.galarneau@efficios.com>
This seemed to point to something more subtle, possibly related to the process's environment.
I couldn't find a way for git
to provide the stderr
of gpg
to get a better error report. Thus, I modified GnuPG 2.2.27
and rebuilt it to output the errors to a log file. This yielded the following error:
[GNUPG:] INV_SGNR 9 Jérémie Galarneau <jeremie.galarneau@efficios.com>
[GNUPG:] FAILURE sign 17
gpg: signing failed: No secret key
If you look at the first line, you will see that the é
characters in my name were changed to é
.
This typically happens when my name is converted from UTF-8 to ISO/IEC 8859-1.
This clued me in that something funny related to locales was happening.
I dumped and compared the environment of the gpg
process in the two scenarios (CLI use and GitPython) and saw that the only meaningful difference was that the LANGUAGE
and LC_ALL
environment variables were set to C
when GitPython
was involved.
Indeed, invoking git
with LC_ALL="C" LANGUAGE="C" git tag -s [...]
reproduced the problem.
Cause
Looking at the GitPython
code, I found that git is invoked with those environment variables set:
https://github.com/gitpython-developers/GitPython/blame/b3778ec/git/cmd.py#L694
I am unsure what "parsing code" the comments are referring to so I can't comment on the reasons why this is done. However, forcing a C
locale will cause these kinds of erroneous encoding conversions for people who, like me, have non-ASCII names.
For what it's worth, my locale is LANG=en_CA.utf8
.
I would guess that forcing the locale to any UTF-8 English locale would work around most issues and still provide GitPython
with an English output.
My workaround
I found out that setting the signingKey
property to my KEYID
in my .gitconfig
causes git
to invoke gpg
with the KEYID
instead of the name
property.
[user]
name = Jérémie Galarneau
email = jeremie.galarneau@efficios.com
signingKey = MY_KEY_ID_HERE
This works around the problem since no accented letters are used in the gpg
invocation.