Created
July 3, 2021 20:26
-
-
Save kuvaldini/c40fb8c57bfbe2f3bd4fc288709c0974 to your computer and use it in GitHub Desktop.
Script to expand YAML anchors in GitHub Actions workflows
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -euo pipefail | |
--help(){ | |
cat<<'END' | |
make-workflows: | |
This script expands '*.src.yml' from $1 (default: script's directory) | |
to $2 (default:REPO_ROOT/.github/workflows) with corresponding name '*.yml' | |
Main goal is to dereference YAML anchors. | |
Deals only with Git cached/indexed files until --no-git-index passed. | |
DEBUG: use option -x | |
NOTE: spaces in filenames are not allowed to keep code simplicity | |
END | |
cat<<END | |
Usage: | |
make-workflows.sh [--no-git-index] [dirs_from... [dir_to]] | |
make-workflows.sh [--help] | |
Options: | |
--no-git-index|--worktree List files and get contents from working tree | |
instead of git index | |
-h, --help show this help | |
-x, --trace | |
+x, --no-trace enable/disable bash trace | |
END | |
exit | |
} | |
files_list(){ | |
git diff --cached --name-only --relative -- "$@" | |
} | |
file_contents(){ | |
git show $(printf ":%s " $@) | |
} | |
while [[ $# > 0 ]] ;do | |
case "$1" in | |
## List files and get contents from working tree instead of git index | |
--no-git-index|--worktree) | |
files_list(){ | |
ls $@ | |
} | |
file_contents(){ | |
cat $@ | |
} | |
;; | |
-x|--trace) set -x ;; | |
+x|--no-trace) set +x ;; | |
-h|--help|'-?') --help ;; | |
-*) | |
echo >&2 "make-workflows: ERROR: unxpected parameter" | |
--help >&2 | |
exit 2 | |
;; | |
## The last non-option argument is dir_to all previous are dirs_from | |
*) | |
if [[ "$1" = *' '* ]] ;then | |
echo >&2 "make-workflows: ERROR: spaces in arguments are not allowed: '$1'" | |
exit 1 | |
fi | |
if [[ "$(echo ${dirs_from:-})" = '' ]] ;then | |
dirs_from=$1 | |
else | |
dirs_from+=" "${dir_to:-} | |
dir_to=$1 | |
fi | |
;; | |
esac | |
shift | |
done | |
readonly script_dir=$(dirname $(realpath "$0")) | |
readonly dirs_from=${dirs_from:-${script_dir}} | |
readonly repo_root=$(git rev-parse --show-toplevel) | |
dir_to=${dir_to:-$repo_root/.github/workflows} | |
readonly dir_to=$(realpath $dir_to) | |
edited_files= | |
for dir_from in $dirs_from ;do | |
pushd $dir_from >/dev/null | |
for f in $(files_list '*.src.yml') ;do | |
out=$(echo $f | sed 's|.src.yml$|.yml|') | |
wout=$dir_to/$out | |
tempout=$(mktemp) | |
trap "rm -f $tempout" EXIT ## in case of error file will be removed before exit | |
echo >>$tempout "## DO NOT EDIT" | |
echo >>$tempout "## Generated from $f with $(basename $0)" | |
echo >>$tempout "" | |
## Take cached content from index | |
file_contents ./$f | yq eval 'explode(.)' - >>$tempout | |
if ! diff -q $wout $tempout &>/dev/null ;then | |
mv $tempout $wout | |
edited_files+="'$(realpath --relative-to=$OLDPWD $wout)' " | |
else | |
rm -f $tempout | |
fi | |
done | |
popd >/dev/null | |
done | |
if [[ -n "$edited_files" ]] | |
then echo "make-workflows: these files were edited: $edited_files" | |
else echo "make-workflows: everything is up to date" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment