Elliot bb3766ad6a
Add atomic push
Since time elapses between the checkout the github workflow performs and the eventual push this action invokes the remote HEAD may have changed. If this is the case the HEAD update will be rejected but any tag (and their commits) will be pushed.

In general I think this operation should be atomic, either we push everything or we push nothing.

Force pushes still work the way you would expect (i.e. if we force the HEAD update with --atomic everything is still pushed)

This also protects from the situation where someone else has seized your tag name in the meantime but not updated your HEAD.

See git docs for more information - https://git-scm.com/docs/git-push#Documentation/git-push.txt---no-atomic
2022-09-02 10:53:40 +01:00

51 lines
1.2 KiB
Bash
Executable File

#!/bin/sh
set -e
INPUT_FORCE=${INPUT_FORCE:-false}
INPUT_FORCE_WITH_LEASE=${INPUT_FORCE_WITH_LEASE:-false}
INPUT_SSH=${INPUT_SSH:-false}
INPUT_TAGS=${INPUT_TAGS:-false}
INPUT_DIRECTORY=${INPUT_DIRECTORY:-'.'}
_FORCE_OPTION=''
REPOSITORY=${INPUT_REPOSITORY:-$GITHUB_REPOSITORY}
echo "Push to branch $INPUT_BRANCH";
[ -z "${INPUT_GITHUB_TOKEN}" ] && {
echo 'Missing input "github_token: ${{ secrets.GITHUB_TOKEN }}".';
exit 1;
};
if ${INPUT_FORCE} && ${INPUT_FORCE_WITH_LEASE}; then
echo 'Please, specify only force or force_with_lease and not both.';
exit 1;
fi
if ${INPUT_FORCE}; then
_FORCE_OPTION='--force'
fi
if ${INPUT_FORCE_WITH_LEASE}; then
_FORCE_OPTION='--force-with-lease'
fi
if ${INPUT_TAGS}; then
_TAGS='--tags'
fi
cd ${INPUT_DIRECTORY}
if ${INPUT_SSH}; then
remote_repo="git@${INPUT_GITHUB_URL}:${REPOSITORY}.git"
else
remote_repo="${INPUT_GITHUB_URL_PROTOCOL}//${GITHUB_ACTOR}:${INPUT_GITHUB_TOKEN}@${INPUT_GITHUB_URL}/${REPOSITORY}.git"
fi
git config --local --add safe.directory ${INPUT_DIRECTORY}
if ${INPUT_FORCE_WITH_LEASE}; then
git push --atomic --follow-tags $_FORCE_OPTION $_TAGS;
else
git push "${remote_repo}" HEAD:${INPUT_BRANCH} --atomic --verbose --follow-tags $_FORCE_OPTION $_TAGS;
fi