GPG verifying git tags in a deployment script
We would like our deployment process to pull directly from our git
repository, but only activate new changes if they are signed (via git
tag -s
) with a GPG signature. I've found very few examples out there
of workflows that use GPG verification of git tags, so I'm not sure if
there's a "best practice" for this sort of thing.
What we have so far looks like this:
# discard erroneous local changes
git reset --hard HEAD
# get changes
git fetch
start=$(git rev-parse FETCH_HEAD)
# get new tags
git fetch --tags
# find most recent release tag
tag=$(git describe --abbrev=0 --match "release-*" $start)
if git tag -v $tag; then
git checkout $tag
...do stuff...
fi
Does this make sense? In particular, in order to avoid erroneous
local changes from hosing the deployment process, is git reset --hard
HEAD
the right thing to do? Also, remembering FETCH_HEAD
seems to
be necessary, other wise tags subsequent to HEAD
don't show up in
the output of git describe
. Is there another way to do this?
Alternatively, if you have a documented deployment workflow that uses signed tags for verification I would be interested in a link to that.
The title of the question is about signed tags in a deployment workflow, but what you are asking has very little to do with the signed tags. And in reality the only step that would be different is the verification of the tags, and you are already doing that.
git reset --hard HEAD
is not going to clean out any untracked local files, which may very well ruin your build process. After git reset --hard
you may want to also run git clean -d -x -f
.
git fetch
may fetch multiple branches, or it may not fetch what you would expect it to fetch. All the fetched branches would be added to .git/FETCH_HEAD
so to avoid any surprises when using the FETCH_HEAD
ref, I would recommend fetching your release branch explicitly. Something like git fetch $remote $branch
.
You are asking if there is a "better" way of doing this, but personally I think this is good enough. If your goal is to avoid unnecessary fetching, then you could play with the output of git ls-remote
but it is really not worth the effort.
Personally, for reproducible builds I would simply start the build in a clean directory every time. dir=$(mktemp -d); cd $dir; git init; git remote add ...
and so on. This way you can also easily move this script to a different machine. To speed up the initial fetch you can tell the temporary directory to find git objects from the permanent local directory with a echo $permanent_git_directory/.git/objects > .git/objects/info/alternates
(man gitrepository-layout
for more info).