Eric Bower
·
2026-05-11
1#!/usr/bin/env bash
2# post-receive hook — archives the pushed commit and uploads to pgs.sh,
3# then publishes a build event to pici via ssh pipe.
4#
5# Install: ./install-hooks.sh /path/to/bare-repos
6#
7# stdin format (per ref pushed): <old-sha> <new-sha> <ref-name>
8
9set -euo pipefail
10
11PIPE_HOST="${PIPE_HOST:-pipe.pico.sh}"
12PGS_HOST="${PGS_HOST:-pgs.sh}"
13PGS_PROJECT_BASE="${PGS_PROJECT_BASE:-public-ci}"
14
15log() {
16 echo "[post-receive] $*" >&2
17}
18
19while read -r old_sha new_sha ref; do
20 # Skip delete refs
21 if [ "$new_sha" = "0000000000000000000000000000000000000000" ]; then
22 log "skip delete ref: $ref"
23 continue
24 fi
25
26 # Extract branch name from ref (e.g. refs/heads/main → main)
27 branch="${ref#refs/heads/}"
28
29 # Repo name and short SHA from bare repo
30 repo="$(basename "$(pwd)" .git)"
31 pgs_project="${PGS_PROJECT_BASE}-${repo}"
32 short_sha="${new_sha:0:8}"
33
34 log "repo=$repo branch=$branch commit=$new_sha"
35
36 pgs_path="/${pgs_project}/${short_sha}/"
37 tar_path="${pgs_path}workspace.tar"
38 log "upload: git archive $new_sha → $PGS_HOST:$tar_path"
39
40 if ! git archive "$new_sha" | ssh -T "$PGS_HOST" "$tar_path"; then
41 log "ERROR: upload failed" >&2
42 continue
43 fi
44
45 # Workspace points to the tar on pgs.sh
46 workspace="${PGS_HOST}:${tar_path}"
47
48 # Detect force push: old SHA is not an ancestor of new SHA
49 is_force_push=false
50 if [ "$old_sha" != "0000000000000000000000000000000000000000" ]; then
51 if ! git merge-base --is-ancestor "$old_sha" "$new_sha" 2>/dev/null; then
52 is_force_push=true
53 fi
54 fi
55
56 event=$(printf '{"type":"git.push","name":"%s","workspace":"%s","branch":"%s","commit":"%s","artifact_dest":"%s:%s","force_push":%s}' \
57 "$repo" "$workspace" "$branch" "$new_sha" "$PGS_HOST" "$pgs_path" "$is_force_push")
58
59 log "publish: $event"
60 echo "$event" | ssh -T "$PIPE_HOST" pub -b=false build.event
61 log "done"
62done