main pici / hooks / post-receive
Eric Bower  ·  2026-07-22
 1#!/usr/bin/env bash
 2# post-receive hook — archives the pushed commit, uploads to the configured
 3# pici.upload destination, and publishes a build event via ssh pipe.
 4#
 5# Install: ./install-hooks.sh /path/to/bare-repos
 6# Opt-in:  git -C /path/to/repo.git config pici.upload pgs.sh:/private-ci/myrepo
 7#
 8# stdin format (per ref pushed): <old-sha> <new-sha> <ref-name>
 9
10set -euo pipefail
11
12PIPE_HOST="${PIPE_HOST:-pipe.pico.sh}"
13
14log() {
15  echo "[post-receive] $*" >&2
16}
17
18repo="$(basename "$(pwd)" .git)"
19
20# Read upload base from git config — noop if unset
21upload_base="$(git config --get pici.upload 2>/dev/null)" || true
22if [ -z "$upload_base" ]; then
23  log "pici.upload not set, skipping $repo"
24  exit 0
25fi
26
27while read -r old_sha new_sha ref; do
28  # Skip delete refs
29  if [ "$new_sha" = "0000000000000000000000000000000000000000" ]; then
30    log "skip delete ref: $ref"
31    continue
32  fi
33
34  short_sha="${new_sha:0:8}"
35
36  case "$ref" in
37    refs/heads/*)
38      event_type="git.push"
39      ref_name="${ref#refs/heads/}"
40      ;;
41    refs/tags/*)
42      event_type="git.tag"
43      ref_name="${ref#refs/tags/}"
44      ;;
45    *)
46      log "unknown ref: $ref"
47      continue
48      ;;
49  esac
50
51  log "repo=$repo type=$event_type name=$ref_name commit=$new_sha"
52
53  # upload_base is "host:path", e.g. pgs.sh:/private-ci/myrepo
54  upload_host="${upload_base%%:*}"
55  upload_dir="${upload_base#*:}/${short_sha}/"
56  tar_path="${upload_dir}workspace.tar"
57  log "upload: git archive $new_sha$upload_host:$tar_path"
58
59  if ! git archive "$new_sha" | ssh -T "$upload_host" "$tar_path"; then
60    log "ERROR: upload failed" >&2
61    continue
62  fi
63
64  workspace="${upload_host}:${tar_path}"
65  artifact_dest="${upload_host}:${upload_dir}"
66  job_id="$short_sha"
67
68  if [ "$event_type" = "git.tag" ]; then
69    event=$(printf '{"type":"%s","name":"%s","job_id":"%s","tag":"%s","commit":"%s","workspace":"%s","artifact_dest":"%s"}' \
70      "$event_type" "$repo" "$job_id" "$ref_name" "$new_sha" "$workspace" "$artifact_dest")
71  else
72    event=$(printf '{"type":"%s","name":"%s","job_id":"%s","branch":"%s","commit":"%s","workspace":"%s","artifact_dest":"%s"}' \
73      "$event_type" "$repo" "$job_id" "$ref_name" "$new_sha" "$workspace" "$artifact_dest")
74  fi
75
76  log "publish: $event"
77  echo "$event" | ssh -T "$PIPE_HOST" pub -b=false pici
78  log "done"
79done