feat: initial action implementation
This commit is contained in:
commit
a849295b46
4 changed files with 465 additions and 0 deletions
121
scripts/checkout.sh
Executable file
121
scripts/checkout.sh
Executable file
|
@ -0,0 +1,121 @@
|
|||
#!/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
|
Loading…
Add table
Add a link
Reference in a new issue