#!/bin/sh
set -eu
usage() {
cat <<-'EOF'
Usage:
aux/ci/report.sh -o OUTDIR
aux/ci/report.sh -h
EOF
}
help() {
cat <<-'EOF'
Options:
-o OUTDIR the directory where to place the generated files
-h, --help show this message
Gather data from Git Notes, and generate an HTML report on CI runs.
Two refs with notes are expected:
1. refs/notes/ci-data: contains metadata abount the CI runs,
with timestamps, filenames and exit status;
2. refs/notes/ci-logs: contains the content of the log.
When reconstructing the CI run, the $FILENAME present in
the refs/notes/ci-data ref names the file, and its content comes
from refs/notes/ci-logs.
On a CI run that generated the numbers from 1 to 10, for a file named
'my-ci-run-2020-01-01-deadbeef.log' that exited successfully, ran for
15 seconds and was deployed to production, the expected output on the
target directory "public" is:
$ tree public/
public/
index.html
data/
2020-01-01T01:00:00-deadbeef.log
...
logs/
2020-01-01T01:00:00-deadbeef.log
...
$ cat public/data/2020-01-01T01:00:00-deadbeef.log
status 0
sha deadbeef
filename deadbeef 2020-01-01T01:00:00-deadbeef.log
duration 15
timestamp 2020-01-01T01:00:00
to-prod true
refname refs/heads/main
$ cat public/logs/2020-01-01T01:00:00-deadbeef.log
1
2
3
4
5
6
7
8
9
10
The generated 'index.html' is a webpage with the list of all known
CI runs, their status, a link to the commit and a link to the
log and data files.
To enable fetching these refs by default, do so in the git config:
$ git config --add remote.origin.fetch '+refs/notes/*:refs/notes/*'
Examples:
Generate the report on the 'www' directory:
$ sh aux/ci/report.sh -o www
EOF
}
for flag in "$@"; do
case "$flag" in
--)
break
;;
--help)
usage
help
exit
;;
*)
;;
esac
done
while getopts 'o:h' flag; do
case "$flag" in
o)
OUTDIR="$OPTARG"
;;
h)
usage
help
exit
;;
*)
exit 2
;;
esac
done
shift $((OPTIND - 1))
. aux/lib.sh
eval "$(assert_arg "${OUTDIR:-}" '-o OUTDIR')"
esc() {
sed \
-e 's|&|\&|g' \
-e 's|<|\<|g' \
-e 's|>|\>|g' \
-e 's|"|\"|g' \
-e "s|'|\'|g"
}
mkdir -p "$OUTDIR"
cd "$OUTDIR"
mkdir -p logs data
for c in $(git notes list | cut -d' ' -f2); do
git notes --ref=refs/notes/ci-data show "$c" > data/FILENAME-tmp
FILENAME="$(grep '^filename ' data/FILENAME-tmp | cut -d' ' -f2-)"
mv data/FILENAME-tmp data/"$FILENAME"
git notes --ref=refs/notes/ci-logs show "$c" > logs/"$FILENAME"
done
{
cat <<-EOF