-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathgit.ts
More file actions
122 lines (105 loc) · 4.43 KB
/
git.ts
File metadata and controls
122 lines (105 loc) · 4.43 KB
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
113
114
115
116
117
118
119
120
121
122
import type { TemplateConfig } from "../domain.js"
const renderEntrypointAuthEnvBridge = (config: TemplateConfig): string =>
String.raw`# 2) Ensure GitHub auth vars are available for SSH sessions if provided
if [[ -n "$GH_TOKEN" || -n "$GITHUB_TOKEN" ]]; then
EFFECTIVE_GITHUB_TOKEN="$GITHUB_TOKEN"
if [[ -z "$EFFECTIVE_GITHUB_TOKEN" ]]; then
EFFECTIVE_GITHUB_TOKEN="$GH_TOKEN"
fi
EFFECTIVE_GH_TOKEN="$GH_TOKEN"
if [[ -z "$EFFECTIVE_GH_TOKEN" ]]; then
EFFECTIVE_GH_TOKEN="$EFFECTIVE_GITHUB_TOKEN"
fi
printf "export GH_TOKEN=%q\n" "$EFFECTIVE_GH_TOKEN" > /etc/profile.d/gh-token.sh
printf "export GITHUB_TOKEN=%q\n" "$EFFECTIVE_GITHUB_TOKEN" >> /etc/profile.d/gh-token.sh
chmod 0644 /etc/profile.d/gh-token.sh
SSH_ENV_PATH="/home/${config.sshUser}/.ssh/environment"
printf "%s\n" "GH_TOKEN=$EFFECTIVE_GH_TOKEN" > "$SSH_ENV_PATH"
printf "%s\n" "GITHUB_TOKEN=$EFFECTIVE_GITHUB_TOKEN" >> "$SSH_ENV_PATH"
chmod 600 "$SSH_ENV_PATH"
chown 1000:1000 "$SSH_ENV_PATH" || true
SAFE_GH_TOKEN="$(printf "%q" "$GH_TOKEN")"
# Keep git+https auth in sync with gh auth so push/pull works without manual setup.
su - ${config.sshUser} -c "GH_TOKEN=$SAFE_GH_TOKEN gh auth setup-git --hostname github.com --force" || true
GH_LOGIN="$(su - ${config.sshUser} -c "GH_TOKEN=$SAFE_GH_TOKEN gh api user --jq .login" 2>/dev/null || true)"
GH_ID="$(su - ${config.sshUser} -c "GH_TOKEN=$SAFE_GH_TOKEN gh api user --jq .id" 2>/dev/null || true)"
GH_LOGIN="$(printf "%s" "$GH_LOGIN" | tr -d '\r\n')"
GH_ID="$(printf "%s" "$GH_ID" | tr -d '\r\n')"
if [[ -z "$GIT_USER_NAME" && -n "$GH_LOGIN" ]]; then
GIT_USER_NAME="$GH_LOGIN"
fi
if [[ -z "$GIT_USER_EMAIL" && -n "$GH_LOGIN" && -n "$GH_ID" ]]; then
GIT_USER_EMAIL="${"${"}GH_ID}+${"${"}GH_LOGIN}@users.noreply.github.com"
fi
fi`
const renderEntrypointGitCredentialHelper = (config: TemplateConfig): string =>
String.raw`# 3) Configure git credential helper for HTTPS remotes
GIT_CREDENTIAL_HELPER_PATH="/usr/local/bin/docker-git-credential-helper"
cat <<'EOF' > "$GIT_CREDENTIAL_HELPER_PATH"
#!/usr/bin/env bash
set -euo pipefail
if [[ "$#" -lt 1 || "$1" != "get" ]]; then
exit 0
fi
token="$GITHUB_TOKEN"
if [[ -z "$token" ]]; then
token="$GH_TOKEN"
fi
if [[ -z "$token" ]]; then
exit 0
fi
printf "%s\n" "username=x-access-token"
printf "%s\n" "password=$token"
EOF
chmod 0755 "$GIT_CREDENTIAL_HELPER_PATH"
su - ${config.sshUser} -c "git config --global credential.helper '$GIT_CREDENTIAL_HELPER_PATH'"`
const renderEntrypointGitIdentity = (config: TemplateConfig): string =>
String.raw`# 4) Configure git identity for the dev user if provided
if [[ -n "$GIT_USER_NAME" ]]; then
SAFE_GIT_USER_NAME="$(printf "%q" "$GIT_USER_NAME")"
su - ${config.sshUser} -c "git config --global user.name $SAFE_GIT_USER_NAME"
fi
if [[ -n "$GIT_USER_EMAIL" ]]; then
SAFE_GIT_USER_EMAIL="$(printf "%q" "$GIT_USER_EMAIL")"
su - ${config.sshUser} -c "git config --global user.email $SAFE_GIT_USER_EMAIL"
fi`
export const renderEntrypointGitConfig = (config: TemplateConfig): string =>
[
renderEntrypointAuthEnvBridge(config),
renderEntrypointGitCredentialHelper(config),
renderEntrypointGitIdentity(config)
].join("\n\n")
export const renderEntrypointGitHooks = (): string =>
String.raw`# 3) Install global git hooks to protect main/master
HOOKS_DIR="/opt/docker-git/hooks"
PRE_PUSH_HOOK="$HOOKS_DIR/pre-push"
mkdir -p "$HOOKS_DIR"
if [[ ! -f "$PRE_PUSH_HOOK" ]]; then
cat <<'EOF' > "$PRE_PUSH_HOOK"
#!/usr/bin/env bash
set -euo pipefail
protected_branches=("refs/heads/main" "refs/heads/master")
allow_delete="${"${"}DOCKER_GIT_ALLOW_DELETE:-}"
while read -r local_ref local_sha remote_ref remote_sha; do
if [[ -z "$remote_ref" ]]; then
continue
fi
for protected in "${"${"}protected_branches[@]}"; do
if [[ "$remote_ref" == "$protected" || "$local_ref" == "$protected" ]]; then
echo "docker-git: push to protected branch '${"${"}protected##*/}' is disabled."
echo "docker-git: create a new branch: git checkout -b <name>"
exit 1
fi
done
if [[ "$local_sha" == "0000000000000000000000000000000000000000" && "$remote_ref" == refs/heads/* ]]; then
if [[ "$allow_delete" != "1" ]]; then
echo "docker-git: deleting remote branches is disabled (set DOCKER_GIT_ALLOW_DELETE=1 to override)."
exit 1
fi
fi
done
EOF
chmod 0755 "$PRE_PUSH_HOOK"
fi
git config --system core.hooksPath "$HOOKS_DIR" || true
git config --global core.hooksPath "$HOOKS_DIR" || true`