121 lines
3.5 KiB
Bash
121 lines
3.5 KiB
Bash
|
#!/usr/bin/env bash
|
||
|
shopt -s extglob
|
||
|
|
||
|
ACTION_INPUT_TOKEN="${ACTION_INPUT_TOKEN:?}"
|
||
|
ACTION_INPUT_REPOSITORY="${ACTION_INPUT_REPOSITORY:?}"
|
||
|
ACTION_INPUT_PATH="${ACTION_INPUT_PATH:?}"
|
||
|
ACTION_INPUT_REF="${ACTION_INPUT_REF:?}"
|
||
|
|
||
|
error() {
|
||
|
echo "$*" 1>&2 ; exit 1;
|
||
|
}
|
||
|
|
||
|
# ensure we are in the right place
|
||
|
[[ -z "${GITHUB_WORKSPACE:-}" ]] || { cd "${GITHUB_WORKSPACE}" || error ; }
|
||
|
|
||
|
git config --global --add protocol.version 2
|
||
|
|
||
|
git init -q "${ACTION_INPUT_PATH}" && { cd "${ACTION_INPUT_PATH}" || error ; }
|
||
|
|
||
|
git config --local gc.auto 0
|
||
|
|
||
|
# the server url and uri are important for determining the default checkout url
|
||
|
GITHUB_SERVER_URL="${GITHUB_SERVER_URL:?}"
|
||
|
GITHUB_SERVER_URI="${GITHUB_SERVER_URL//http?(s):\/\//}"
|
||
|
|
||
|
# use https instead of everything else
|
||
|
git config --add url."${GITHUB_SERVER_URL}/".insteadOf "git@${GITHUB_SERVER_URI}:"
|
||
|
git config --add url."${GITHUB_SERVER_URL}/".insteadOf "ssh://git@${GITHUB_SERVER_URI}/"
|
||
|
git config --add url."${GITHUB_SERVER_URL}/".insteadOf "git://${GITHUB_SERVER_URI}/"
|
||
|
|
||
|
# prepare git config extra header for https auth
|
||
|
BASE64="base64 --wrap 0"
|
||
|
echo "" | ${BASE64} >/dev/null 2>&1 || BASE64="base64"
|
||
|
echo "" | ${BASE64} >/dev/null 2>&1 || BASE64="openssl base64 -A"
|
||
|
echo "" | ${BASE64} >/dev/null 2>&1
|
||
|
|
||
|
GIT_HTTP_EXTRAHEADER="AUTHORIZATION: basic $(echo -n "x-access-token:${ACTION_INPUT_TOKEN}" | ${BASE64})"
|
||
|
git config --local --add http."${GITHUB_SERVER_URL}".extraheader "${GIT_HTTP_EXTRAHEADER}"
|
||
|
|
||
|
# add the repository as remote
|
||
|
git remote add origin "${ACTION_INPUT_REPOSITORY}"
|
||
|
|
||
|
git_default_refspec() {
|
||
|
git ls-remote --symref origin HEAD | { read -r _ ref name ; echo "${ref}" ; }
|
||
|
}
|
||
|
|
||
|
git_resolve_refspec() {
|
||
|
# shellcheck disable=SC2068
|
||
|
git ls-remote origin $@ | { read -r sha ref _ ; echo "${sha} ${ref}" ; }
|
||
|
}
|
||
|
|
||
|
fetch() {
|
||
|
# shellcheck disable=SC2068
|
||
|
git fetch --no-tags --prune --no-recurse-submodules --depth=1 origin $@
|
||
|
}
|
||
|
|
||
|
checkout() {
|
||
|
# shellcheck disable=SC2068
|
||
|
git checkout --force $@
|
||
|
}
|
||
|
|
||
|
# the checkout is based on a commit hash
|
||
|
if [[ ${ACTION_INPUT_REF:-} =~ ^[0-9a-f]{5,40}$ ]]
|
||
|
then
|
||
|
fetch "${ACTION_INPUT_REF}" && checkout "${ACTION_INPUT_REF}"
|
||
|
exit
|
||
|
fi
|
||
|
|
||
|
# update selected ref when no input is given to remote default branch
|
||
|
: "${ACTION_INPUT_REF:=$( git_default_refspec )}"
|
||
|
|
||
|
# TODO: check if repo is workflow repo, if so, use commit sha from env
|
||
|
# like GITHUB_REF and GITHUB_SHA
|
||
|
|
||
|
read -r GIT_SHA GIT_REF _ <<< "$( git_resolve_refspec "${ACTION_INPUT_REF}" )"
|
||
|
: "${GIT_SHA:?}" "${GIT_REF:?}"
|
||
|
|
||
|
# we always use the refspec with the commit sha as source to prevent
|
||
|
# race conditions when running on a frequently used branch
|
||
|
|
||
|
checkout_head() {
|
||
|
local name="${GIT_REF#refs\/heads\/}"
|
||
|
local remote="refs/remotes/origin/${name}"
|
||
|
|
||
|
fetch "+${GIT_SHA}:${remote}"
|
||
|
|
||
|
checkout -B "${name}" "${remote}"
|
||
|
}
|
||
|
|
||
|
checkout_pull() {
|
||
|
local name="${GIT_REF#refs\/pull\/}"
|
||
|
local remote="refs/remotes/pull/${name}"
|
||
|
|
||
|
fetch "+${GIT_SHA}:${remote}"
|
||
|
|
||
|
# pull requests have a special treatment for the branch name. The name
|
||
|
# is determined by the branch the pull request is targeting.
|
||
|
|
||
|
local branch="${GITHUB_BASE_REF:-$( git_default_refspec )}"
|
||
|
checkout -B "${branch#refs\/heads\/}" "${remote}"
|
||
|
}
|
||
|
|
||
|
checkout_tag() {
|
||
|
local name="${GIT_REF#refs\/tags\/}"
|
||
|
local remote="refs/tags/${name}"
|
||
|
|
||
|
fetch "+${GIT_SHA}:${remote}"
|
||
|
|
||
|
checkout "${remote}"
|
||
|
}
|
||
|
|
||
|
case "${GIT_REF}" in
|
||
|
# heads and pull are a branch based checkout
|
||
|
refs/heads/*) checkout_head ;;
|
||
|
refs/pull/* ) checkout_pull ;;
|
||
|
|
||
|
# tags are a detached head checkout
|
||
|
refs/tags/* ) checkout_tag ;;
|
||
|
|
||
|
*) error "ref type '${GIT_REF}' is unknown" ;;
|
||
|
esac
|