#!/bin/sh
set -eu
usage() {
cat <<-'EOF'
Usage:
report [-C REPO] -o DIRECTORY
report -h
EOF
}
help() {
cat <<-'EOF'
Options:
-C REPO change to REPO when doing Git operations (default: $PWD)
-o DIRECTORY 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, the
expected output on the target directory "public" is:
$ tree public/
public/
index.html
data/
my-ci-run-2020-01-01-deadbeef.log
...
logs/
my-ci-run-2020-01-01-deadbeef.log
...
$ cat public/data/my-ci-run-2020-01-01-deadbeef.log
0 deadbeef my-ci-run-2020-01-01-deadbeef.log
$ cat public/logs/my-ci-run-2020-01-01-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 file.
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:
$ report -o www
EOF
}
for flag in "$@"; do
case "$flag" in
--)
break
;;
--help)
usage
help
exit
;;
*)
;;
esac
done
REPO="$PWD"
while getopts 'C:o:h' flag; do
case "$flag" in
C)
REPO="$OPTARG"
;;
o)
OUTDIR="$OPTARG"
;;
h)
usage
help
exit
;;
*)
exit 2
;;
esac
done
shift $((OPTIND - 1))
if [ -z "${OUTDIR:-}" ]; then
printf 'Missing -o OUTDIR.\n\n' >&2
usage >&2
exit 2
fi
if [ -r src/infrastructure/config/conf.env ]; then
CONF=src/infrastructure/config/conf.env
else
CONF=/etc/conf.env
fi
# shellcheck source=/dev/null
. "$CONF"
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 -C "$REPO" notes list | cut -d' ' -f2); do
git -C "$REPO" 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 -C "$REPO" notes --ref=refs/notes/ci-logs show "$c" > logs/"$FILENAME"
done
{
cat <<-EOF