-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathrun_git_publish.sh
executable file
·112 lines (96 loc) · 4.27 KB
/
run_git_publish.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/env bash
# Inspired by https://gist.github.com/joncardasis/e6494afd538a400722545163eb2e1fa5
set -euo pipefail
IFS=$'\n\t'
[[ -f "/.dockerenv" ]] || { printf "Error: must be executed inside Docker container\n" 1>&2; exit 1; }
readonly envGitEmail="${ENV_GIT_EMAIL:?}"
readonly envGitName="${ENV_GIT_NAME:?}"
readonly envGitPublishBranch="${ENV_GIT_PUBLISH_BRANCH:?}"
readonly envGitPublishIncludePatterns="${ENV_GIT_PUBLISH_INCLUDE_PATTERNS:?}"
readonly envGitRepoURL="${ENV_GIT_REPO_URL:?}"
# readonly envGitToken="${ENV_GIT_TOKEN:?}"
# readonly envGitUsername="${ENV_GIT_USERNAME:?}"
readonly envPublishDir="${ENV_PUBLISH_DIR:?}"
readonly envTmpDir="${ENV_TMP_DIR:?}"
# Gets the name of the repo from envGitRepoURL
# Ex: https://github.com/flemay/3musketeers.git -> 3musketeers
getRepoName() {
printf "function: getRepoName\n"
declare -n _retRepoName="${1}"
_retRepoName="${envGitRepoURL##*/}"
_retRepoName="${_retRepoName%.git}"
}
getRepoTmpDir() {
printf "function: getRepoTmpDir\n"
declare -n _retRepoTmpDir="${1}"
local _repoName=""
getRepoName _repoName
_retRepoTmpDir="${envTmpDir}/${_repoName}"
}
# https://git-scm.com/docs/gitfaq#Documentation/gitfaq.txt-HowdoIreadapasswordortokenfromanenvironmentvariable
# https://stackoverflow.com/questions/72577367/git-push-provide-credentials-without-any-prompts
# Notes
# - The helper line could've been written like `-c credential.helper="!f() { echo \"username=${envGitUsername}\"; echo \"password=${envGitToken}\"; };f" \` but decided to leave git to evaluate the value when Git runs the command.
# - Possible leak: Be sure the helper code is correct. For instance, if we put `password${ENV_GIT_TOKEN}` (omiting the `=`), the command will leak the token with the following message: "warning: invalid credential line: passwordgithub_pat[REDACTED]".
gitAuth() {
printf "function: gitAuth\n"
# shellcheck disable=SC2016
git -c credential.helper= \
-c credential.helper='!f() { echo "username=${ENV_GIT_USERNAME:?}"; echo "password=${ENV_GIT_TOKEN:?}"; };f' \
"$@"
# -c credential.helper="!f() { echo \"username=${envGitUsername}\"; echo \"password=${envGitToken}\"; };f" \
}
cloneAndSetPublishBranch() {
# Clone the repository to a tmp dir so that the current code is not messed up
# The use of option `--single-branch` is to make sure only the default branch is downloaded. This can save some bandwith
printf "function: cloneAndSetPublishBranch\n"
local _repoTmpDir=""
getRepoTmpDir _repoTmpDir
rm -fr "${_repoTmpDir:?}"
gitAuth clone --single-branch "${envGitRepoURL}" "${_repoTmpDir}"
cd "${_repoTmpDir}"
local _currentBranch=""
_currentBranch=$(git rev-parse --abbrev-ref HEAD)
if [[ "${envGitPublishBranch}" == "${_currentBranch}" ]]; then
printf "Error: ENV_GIT_PUBLISH_BRANCH cannot be '%s'\n" "${_currentBranch}"
exit 1
fi
# Create a new orphan branch (which has no history and tracked files)
# According to Git (https://git-scm.com/docs/git-switch/2.23.0):
# --orphan <new-branch>
# Create a new orphan branch, named <new-branch>. All tracked files are removed.
git branch -D "${envGitPublishBranch}" &> /dev/null || true
git switch --orphan "${envGitPublishBranch}"
# create a new .gitignore specifically for publish branch
printf "*\n" > .gitignore
IFS=',' read -ra _includePatterns <<< "${envGitPublishIncludePatterns}"
for pattern in "${_includePatterns[@]}"; do
printf "!%s\n" "${pattern}" >> .gitignore
done
cp -r "${envPublishDir}"/* .
}
configureGitConfig() {
printf "function: configureGitConfig\n"
git config user.email "${envGitEmail}"
git config user.name "${envGitName}"
git remote remove originForPublishing &> /dev/null || true
git remote add originForPublishing "${envGitRepoURL}"
}
commitAndPush() {
printf "function: commitAndPush\n"
git add .
git commit -m "Publish"
# shellcheck disable=SC2310
gitAuth push originForPublishing -d "${envGitPublishBranch}" &> /dev/null || true
gitAuth push originForPublishing "${envGitPublishBranch}"
}
cleanup() {
printf "function: cleanup\n"
local _repoTmpDir=""
getRepoTmpDir _repoTmpDir
rm -fr "${_repoTmpDir}"
}
cloneAndSetPublishBranch
configureGitConfig
commitAndPush
cleanup