Mercurial: GPG Sign Tags

I recently needed to write a pretxnchangegroup hook that would check if any new tags had been pushed, and if so, if they were GPG signed. I had the requirement that the changeset with the tag be signed, not the changeset that added the tag. I’m not a python coder, so I opted to go for a simple bash script to accomplish the task. The only option the script has is whether or not the hook can fail if a changeset does not have a valid signature. If the option is disabled, it will only throw an error, but the hook will still pass.

[code lang=”shell”]#!/bin/bash
# Script to check that tagged revisions are GPG signed.

# Set to true to cause this hook to fail if a tag is not signed
require_gpg=false
failed=

tags_modified=`hg log -r "$HG_NODE:tip" –template ‘{files}\n’ |grep ^\.hgtags$`;

if [ -z "$tags_modified" ]; then
exit 0;
fi

# set $IFS to end-of-line
ORIGIFS=$IFS;
IFS=`echo -en "\n\b"`;

regex=’^\+([^\+]{12}).* (.*)$';

for line in $(hg diff -r "parents($HG_NODE):tip" .hgtags); do
if [[ $line =~ $regex ]]; then
valid_gpg=`hg sigcheck ${BASH_REMATCH[1]} | grep "is signed by"`;
if [ -z "$valid_gpg" ]; then
echo "Tag ${BASH_REMATCH[2]} does not have a valid GPG signature.";
failed=true;
fi
fi
done

# set $IFS back
IFS=$ORIGIFS;

if [[ $require_gpg == true && $failed == true ]]; then
exit 1;
fi

exit 0;[/code]