aboutsummaryrefslogtreecommitdiff
path: root/v2/aux/ci/git-post-receive.sh
blob: 76adccf6b13939a3b5b87f09c56b022c945feaad (about) (plain) (blame)
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#!/bin/sh
# shellcheck source=/dev/null disable=2317
. /etc/rc
set -eu


# shellcheck disable=2034
read -r _oldrev SHA REFNAME

if [ "$SHA" = '0000000000000000000000000000000000000000' ]; then
	exit
fi


SKIP_DEPLOY=false
for n in $(seq 0 $((GIT_PUSH_OPTION_COUNT - 1))); do
	opt="$(eval "printf '%s' \"\$GIT_PUSH_OPTION_$n\"")"
	case "$opt" in
		ci.skip)
			cat <<-EOF

				"$opt" option detected, not running CI.

			EOF
			exit
			;;
		deploy.skip)
			SKIP_DEPLOY=true
			;;
		*)
			;;
	esac
done


epoch() {
	awk 'BEGIN { srand(); print(srand()); }'
}

now() {
	date '+%Y-%m-%dT%H:%M:%S%:z'
}

NAME="$(basename "$PWD" .git)"
LOGS_DIR=/var/log/ci/"$NAME"/
HTML_OUTDIR="/srv/www/s/$NAME"
TIMESTAMP="$(now)"
FILENAME="$TIMESTAMP-$SHA.log"
LOGFILE="$LOGS_DIR/$FILENAME"
mkdir -p "$LOGS_DIR"


END_MARKER='\033[0m'
LIGHT_BLUE_B='\033[1;36m'
YELLOW='\033[1;33m'

blue() {
	printf "${LIGHT_BLUE_B}%s${END_MARKER}" "$1"
}

yellow() {
	printf "${YELLOW}%s${END_MARKER}" "$1"
}

info() {
	sed "s|^\(.\)|$(blue 'CI'): \1|"
}


uuid() {
	od -xN20 /dev/urandom |
		head -n1 |
		awk '{OFS="-"; print $2$3,$4,$5,$6,$7$8$9}'
}

tmpname() {
	printf '%s/uuid-tmpname with spaces.%s' "${TMPDIR:-/tmp}" "$(uuid)"
}

mkdtemp() {
	name="$(tmpname)"
	mkdir -- "$name"
	printf '%s' "$name"
}


{
	cat <<-EOF | info
		Starting CI job at: $(now)
	EOF
	START="$(epoch)"

	duration() {
		if [ "$RUN_DURATION" -gt 60 ]; then
			cat <<-EOF
				$(yellow 'WARNING'): run took more than 1 minute! ($RUN_DURATION seconds)
			EOF
		else
			cat <<-EOF
				Run took $RUN_DURATION seconds.
			EOF
		fi
	}

	finish() {
		STATUS="$?"
		END="$(epoch)"
		RUN_DURATION=$((END - START))
		cat <<-EOF | info
			Finishing CI job at: $(now)
			Exit status was $STATUS
			Re-run with:
			  \$ $CMD
			$(duration)
		EOF

		NOTE="$(
			cat <<-EOF
				See CI logs with:
				  git notes --ref=refs/notes/ci-logs show $SHA
				  git notes --ref=refs/notes/ci-data show $SHA

				Exit status: $STATUS
				Duration: $RUN_DURATION
			EOF
		)"
		git notes --ref=refs/notes/ci-data add -f -m "$(
			cat <<-EOF
				status $STATUS
				sha $SHA
				filename $FILENAME
				duration $RUN_DURATION
				timestamp $TIMESTAMP
				to-prod $TO_PROD
				refname $REFNAME
			EOF
		)" "$SHA"
		git notes --ref=refs/notes/ci-logs add -f -F "$LOGFILE" "$SHA"
		git notes add -f -m "$NOTE" "$SHA"

		{
			printf 'Git CI HTML report for %s (%s) started.\n' "$NAME" "$SHA" >&2
			DIR="$(mkdtemp)"
			REMOTE="$PWD"
			cd "$DIR"
			{
				git clone "$REMOTE" .
				git fetch origin 'refs/notes/*:refs/notes/*'
			} 1>/dev/null 2>&1
			sh aux/ci/report.sh -n "$NAME" -o public-ci
			sudo -u deployer mkdir -p "$HTML_OUTDIR"/ci/
			sudo -u deployer rsync \
				--chmod=D775,F664         \
				--chown=deployer:deployer \
				--delete                  \
				-a                        \
				public-ci/ "$HTML_OUTDIR"/ci/
			rm -rf "$DIR"
			printf 'Git CI HTML report for %s (%s) finished.\n' "$NAME" "$SHA" >&2
		} 2>&1 | logger -i -p local0.warn -t git-ci 1>/dev/null 2>&1 &
	}
	trap finish EXIT

	unset GIT_DIR

	if [ "$REFNAME" = 'refs/heads/main' ] && [ "$SKIP_DEPLOY" = false ]; then
		cat <<-EOF | info
			In branch "main", running deploy for $SHA.
		EOF
		TO_PROD=true
		CMD="sudo cicd $NAME $SHA"
	else
		if [ "$SKIP_DEPLOY" = true ]; then
			cat <<-EOF | info
				"deploy.skip" option detected, skipping deploy for $SHA.
			EOF
		else
			cat <<-EOF | info
				Not on branch "main", skipping deploy for $SHA.
			EOF
		fi
		TO_PROD=false
		CMD="sudo cicd -n $NAME $SHA"
	fi
	$CMD
} 2>&1 | ts -s '%.s' | tee "$LOGFILE"