diff options
-rwxr-xr-x | aux/assert-nixfmt.sh | 11 | ||||
-rwxr-xr-x | aux/assert-shellcheck.sh | 6 | ||||
-rwxr-xr-x | aux/ci/ci-build.sh | 53 | ||||
-rwxr-xr-x | aux/ci/git-post-receive.sh | 14 | ||||
-rwxr-xr-x | aux/ci/git-pre-push.sh | 19 | ||||
-rw-r--r-- | aux/guix/manifest.scm | 16 | ||||
-rw-r--r-- | aux/guix/pinned-channels.scm | 11 | ||||
-rwxr-xr-x | aux/guix/with-container.sh | 14 | ||||
-rwxr-xr-x | aux/workflow/README.sh | 30 | ||||
-rwxr-xr-x | aux/workflow/TODOs.sh | 23 | ||||
-rwxr-xr-x | aux/workflow/assert-todos.sh | 57 | ||||
-rw-r--r-- | aux/workflow/preamble.md | 16 | ||||
-rw-r--r-- | aux/workflow/style.css | 38 |
13 files changed, 308 insertions, 0 deletions
diff --git a/aux/assert-nixfmt.sh b/aux/assert-nixfmt.sh new file mode 100755 index 0000000..19bd0a2 --- /dev/null +++ b/aux/assert-nixfmt.sh @@ -0,0 +1,11 @@ +#!/bin/sh +set -eux + +# shellcheck disable=2016 +find . -type f -name '*.nix' -print0 | xargs -0 -I{} sh -c ' + nixfmt < "$1" | diff - "$1" || { + echo "The file \"$1\" is unformatted. To fix it, run:" + echo " nixfmt $1" + exit 1 + } +' _ {} \; diff --git a/aux/assert-shellcheck.sh b/aux/assert-shellcheck.sh new file mode 100755 index 0000000..334a875 --- /dev/null +++ b/aux/assert-shellcheck.sh @@ -0,0 +1,6 @@ +#!/bin/sh +set -eux + +git ls-files -z | \ + xargs -0 awk 'FNR==1 && /^#!\/bin\/sh$/ { print FILENAME }' | \ + xargs shellcheck diff --git a/aux/ci/ci-build.sh b/aux/ci/ci-build.sh new file mode 100755 index 0000000..81ee1fd --- /dev/null +++ b/aux/ci/ci-build.sh @@ -0,0 +1,53 @@ +#!/bin/sh +set -eux + +PACKAGE="$1" +LOGS_DIR="$2" +read -r _ SHA _ # oldrev newrev refname +FILENAME="$(date -Is)-$SHA.log" +LOGFILE="$LOGS_DIR/$FILENAME" + +{ + echo "Starting CI job at: $(date -Is)" + + finish() { + STATUS="$?" + printf "\n\n>>> exit status was %s\n" "$STATUS" + echo "Finishing CI job at: $(date -Is)" + cd - + NOTE=$(cat <<EOF +See CI logs with: + git notes --ref=refs/notes/ci-logs show $SHA + git notes --ref=refs/notes/ci-data show $SHA +EOF + ) + git notes --ref=refs/notes/ci-data add -f -m "$STATUS $FILENAME" + git notes --ref=refs/notes/ci-logs add -f -F "$LOGFILE" + git notes append -m "$NOTE" + printf "\n>>>\n>>> CI logs added as Git note.\n>>>\n>>> Run status was %s" "$STATUS" + } + trap finish EXIT + + unset GIT_DIR + CLONE="$(mktemp -d)" + git clone . "$CLONE" + cd "$CLONE" + git config --global user.email git@euandre.org + git config --global user.name 'EuAndreh CI' + + if [ -f aux/guix/with-container.sh ]; then + RUNNER='./aux/guix/with-container.sh' + else + RUNNER='sh -c' + fi + + if [ -f ./configure ]; then + COMMAND='./configure && make clean check public' + else + COMMAND='make CC=cc clean check public' + fi + + $RUNNER "$COMMAND" + + rsync -avzzP public/ "/srv/http/$PACKAGE/" --delete +} | tee "$LOGFILE" 2>&1 diff --git a/aux/ci/git-post-receive.sh b/aux/ci/git-post-receive.sh new file mode 100755 index 0000000..b169489 --- /dev/null +++ b/aux/ci/git-post-receive.sh @@ -0,0 +1,14 @@ +#!/bin/sh +set -eu + +for n in $(seq 0 $((GIT_PUSH_OPTION_COUNT - 1))); do + opt="$(eval "echo \$GIT_PUSH_OPTION_$n")" + if [ "$opt" = skip-ci ] || [ "$opt" = ci-skip ]; then + printf "\n'%s' option detected, not running ci-build.sh\n\n" "$opt" + exit 0 + fi +done + +PACKAGE="$(basename "$PWD" | cut -d. -f1)" # remove .git suffix +LOGS_DIR="/srv/ci/$PACKAGE/logs" +"/srv/ci/$PACKAGE/ci-build.sh" "$PACKAGE" "$LOGS_DIR" diff --git a/aux/ci/git-pre-push.sh b/aux/ci/git-pre-push.sh new file mode 100755 index 0000000..d90a4b4 --- /dev/null +++ b/aux/ci/git-pre-push.sh @@ -0,0 +1,19 @@ +#!/bin/sh +set -eux + +PACKAGE="$(basename "$PWD")" +LOGS_DIR="/srv/ci/$PACKAGE/logs" +REMOTE_GIT_DIR="/srv/git/$PACKAGE.git" + +DESCRIPTION="$(mktemp)" +if [ -f description ] +then + cp description "$DESCRIPTION" +else + git config euandreh.description > "$DESCRIPTION" +fi + +scp "$DESCRIPTION" "git.euandreh.xyz:$REMOTE_GIT_DIR/description" +ssh git.euandreh.xyz mkdir -p "$LOGS_DIR" +scp aux/ci/ci-build.sh "git.euandreh.xyz:$(dirname "$LOGS_DIR")/ci-build.sh" +scp aux/ci/git-post-receive.sh "git.euandreh.xyz:$REMOTE_GIT_DIR/hooks/post-receive" diff --git a/aux/guix/manifest.scm b/aux/guix/manifest.scm new file mode 100644 index 0000000..7164e5c --- /dev/null +++ b/aux/guix/manifest.scm @@ -0,0 +1,16 @@ +(specifications->manifest + (map symbol->string + '(bash + coreutils + findutils + diffutils + grep + sed + git + tar + gzip + gawk + make + perl + shellcheck + pandoc))) diff --git a/aux/guix/pinned-channels.scm b/aux/guix/pinned-channels.scm new file mode 100644 index 0000000..67b5a51 --- /dev/null +++ b/aux/guix/pinned-channels.scm @@ -0,0 +1,11 @@ +(list + (channel + (name 'guix) + (url "https://git.savannah.gnu.org/git/guix.git") + (commit + "d265809b782293eb42dd663b4611ca19dd2bf1b3") + (introduction + (make-channel-introduction + "9edb3f66fd807b096b48283debdcddccfea34bad" + (openpgp-fingerprint + "BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA"))))) diff --git a/aux/guix/with-container.sh b/aux/guix/with-container.sh new file mode 100755 index 0000000..3e6a590 --- /dev/null +++ b/aux/guix/with-container.sh @@ -0,0 +1,14 @@ +#!/bin/sh +set -eux + +if [ -z "${1:-}" ]; then + guix time-machine -C aux/guix/pinned-channels.scm -- \ + environment --pure -C -m aux/guix/manifest.scm +elif [ "$1" = '-i' ]; then + guix time-machine -C aux/guix/pinned-channels.scm -- \ + environment -m aux/guix/manifest.scm +else + guix time-machine -C aux/guix/pinned-channels.scm -- \ + environment --pure -C -m aux/guix/manifest.scm -- \ + sh -c "$@" +fi diff --git a/aux/workflow/README.sh b/aux/workflow/README.sh new file mode 100755 index 0000000..b9fa38e --- /dev/null +++ b/aux/workflow/README.sh @@ -0,0 +1,30 @@ +#!/bin/sh +set -eu + +mkdir -p public + +PROJECT_UC="$1" +PROJECT="$2" +README="${3:-README.md}" + +RELEASES_LIST="$(mktemp)" +for version in $(git tag); do + echo "- version [$version](https://git.euandreh.xyz/$PROJECT/snapshot/$PROJECT-$version.tar.gz), released in $(git log -1 --format=%cd --date=short "$version")" >> "$RELEASES_LIST" +done + +RELEASES="$(mktemp)" +if [ -s "$RELEASES_LIST" ]; then + printf '\n# Releases\n\n' >> "$RELEASES" + cat "$RELEASES_LIST" >> "$RELEASES" +fi + +cat "$README" "$RELEASES" | \ + pandoc --toc \ + --highlight-style pygments \ + --toc-depth=2 \ + -s \ + --metadata title="$PROJECT_UC - README" \ + --metadata lang=en \ + -r commonmark \ + -w html \ + > public/index.html diff --git a/aux/workflow/TODOs.sh b/aux/workflow/TODOs.sh new file mode 100755 index 0000000..5dbc761 --- /dev/null +++ b/aux/workflow/TODOs.sh @@ -0,0 +1,23 @@ +#!/bin/sh +set -eu + +mkdir -p public + +export PROJECT_UC="$1" +export PROJECT="$2" +export MAILING_LIST="$3" + +REGEX='s/^## (TODO|DOING|WAITING|MEETING|INACTIVE|NEXT|CANCELLED|DONE) (.*) \{#(.*?)\}$/## <a href="#\3"><span class="\1">\1<\/span> \2<\/a>\n<span class="header-anchor" id="\3">#\3<\/span>\n/' + +envsubst < aux/workflow/preamble.md | \ + printf '%s\n\n%s' "$(cat -)" "$(perl -pe "$REGEX" TODOs.md)" | \ + pandoc --toc \ + --highlight-style pygments \ + --toc-depth=2 \ + -s \ + --metadata title="$PROJECT_UC - TODOs" \ + --metadata lang=en \ + -r commonmark \ + -w html \ + -H aux/workflow/style.css \ + > public/TODOs.html diff --git a/aux/workflow/assert-todos.sh b/aux/workflow/assert-todos.sh new file mode 100755 index 0000000..203d465 --- /dev/null +++ b/aux/workflow/assert-todos.sh @@ -0,0 +1,57 @@ +#!/bin/sh +set -eu + +if git grep FIXME | grep -v '^TODOs.md' | grep -v '^aux/workflow/assert-todos.sh' | grep -v '^aux/docbook-xsl/'; then + echo "Found dangling FIXME markers on the project." + echo "You should write them down properly on TODOs.md." + exit 1 +fi + +awk -F'{#' ' +BEGIN { + exitstatus = 0 + h2flag = 0 + h2status = "" + prevline = "" + idx = 0 + delete ids[0] +} +h2flag == 1 { + split($0, l, " ") + timelinestatus = l[2] + if (h2status != timelinestatus) { + print "h2/timeline status mismatch for line " NR-1 + print prevline + print $0 + exitstatus = 1 + } + h2status = "" + h2flag = 0 +} + +/^## (TODO|DOING|WAITING|MEETING|INACTIVE|NEXT|CANCELLED|DONE)/ { + if (match($0, / \{#.*?\}$/) == 0) { + print "Missing ID for line " NR ":\n" $0 + exitstatus = 1 + } + id_with_prefix = substr($2, 0, length($2) - 1) + match(id_with_prefix, /^\w+-/) + id = substr(id_with_prefix, RLENGTH + 1) + if (id in arr) { + print "Duplicate ID: " id + exitstatus = 1 + } else { + arr[id] = 1 + } + + split($0, l, " ") + h2status = l[2] + h2flag = 1 + prevline = $0 +} + + +/^# Scratch$/ { + exit exitstatus +} +' TODOs.md diff --git a/aux/workflow/preamble.md b/aux/workflow/preamble.md new file mode 100644 index 0000000..c6ae56e --- /dev/null +++ b/aux/workflow/preamble.md @@ -0,0 +1,16 @@ +# About + +TODOs for $PROJECT_UC. + +See also [$PROJECT.euandreh.xyz](https://$PROJECT.euandreh.xyz/). + +Register a new one at +[~euandreh/$MAILING_LIST@lists.sr.ht](mailto:~euandreh/$MAILING_LIST@lists.sr.ht?subject=%5B$PROJECT%5D%20BUG%20or%20TASK%3A%20%3Cdescription%3E) +and see [existing discussions](https://lists.sr.ht/~euandreh/$MAILING_LIST?search=%5B$PROJECT%5D). + +*Você também pode escrever em português*. + +*Vous pouvez aussi écrire en français*. + +*Vi povas ankaŭ skribi esperante*. + diff --git a/aux/workflow/style.css b/aux/workflow/style.css new file mode 100644 index 0000000..ac0144c --- /dev/null +++ b/aux/workflow/style.css @@ -0,0 +1,38 @@ +<style> + hr { + background-color: #ccc; + } + + span.header-anchor { + opacity: 0.5; + } + + /* + Replicate colors from: + https://git.euandreh.xyz/dotfiles/tree/spacemacs.el?id=fcd9f9c4ef399d45d54927382dc1cdde251ebb0a#n866 + */ + + .TODO { + color: brown; + } + + .DOING { + color: yellowgreen; + } + + .WAITING, .MEETING { + color: gray; + } + + .INACTIVE { + color: orange; + } + + .NEXT { + color: red; + } + + .CANCELLED, .DONE { + color: green; + } +</style> |