summaryrefslogtreecommitdiff
path: root/src/content/en/tils/2020/11/12
diff options
context:
space:
mode:
Diffstat (limited to 'src/content/en/tils/2020/11/12')
-rw-r--r--src/content/en/tils/2020/11/12/diy-nix-bash-ci.adoc63
-rw-r--r--src/content/en/tils/2020/11/12/git-bisect-automation.adoc25
-rw-r--r--src/content/en/tils/2020/11/12/useful-bashvars.adoc61
3 files changed, 149 insertions, 0 deletions
diff --git a/src/content/en/tils/2020/11/12/diy-nix-bash-ci.adoc b/src/content/en/tils/2020/11/12/diy-nix-bash-ci.adoc
new file mode 100644
index 0000000..97ace30
--- /dev/null
+++ b/src/content/en/tils/2020/11/12/diy-nix-bash-ci.adoc
@@ -0,0 +1,63 @@
+= DIY bare bones CI server with Bash and Nix
+:categories: ci
+:sort: 2
+
+:post-receive: https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
+:example-project: https://euandreh.xyz/remembering/ci.html
+
+With a server with Nix installed (no need for NixOS), you can leverage its build
+isolation for running CI jobs by adding a {post-receive}[post-receive] Git hook
+to the server.
+
+In most of my project I like to keep a `test` attribute which runs the test with
+`nix-build -A test`. This way, a post-receive hook could look like:
+
+[source,sh]
+----
+#!/usr/bin/env bash
+set -Eeuo pipefail
+set -x
+
+LOGS_DIR="/data/static/ci-logs/libedn"
+mkdir -p "$LOGS_DIR"
+LOGFILE="${LOGS_DIR}/$(date -Is)-$(git rev-parse master).log"
+exec &> >(tee -a "${LOGFILE}")
+
+unset GIT_DIR
+CLONE="$(mktemp -d)"
+git clone . "$CLONE"
+pushd "$CLONE"
+
+finish() {
+ printf "\n\n>>> exit status was %s\n" "$?"
+}
+trap finish EXIT
+
+nix-build -A test
+----
+
+We initially (lines #5 to #8) create a log file, named after _when_ the run is
+running and for _which_ commit it is running for. The `exec` and `tee` combo
+allows the output of the script to go both to `stdout` _and_ the log file. This
+makes the logs output show up when you do a `git push`.
+
+Lines #10 to #13 create a fresh clone of the repository and line #20 runs the
+test command.
+
+After using a similar post-receive hook for a while, I now even generate a
+simple HTML file to make the logs available ({example-project}[example project])
+through the browser.
+
+== Upsides
+
+No vendor lock-in, as all you need is a server with Nix installed.
+
+And if you pin the Nixpkgs version you're using, this very simple setup yields
+extremely sandboxed runs on a very hermetic environment.
+
+== Downsides
+
+Besides the many missing shiny features of this very simplistic CI, `nix-build`
+can be very resource intensive. Specifically, it consumes too much memory. So
+if it has to download too many things, or the build closure gets too big, the
+server might very well run out of memory.
diff --git a/src/content/en/tils/2020/11/12/git-bisect-automation.adoc b/src/content/en/tils/2020/11/12/git-bisect-automation.adoc
new file mode 100644
index 0000000..dff8737
--- /dev/null
+++ b/src/content/en/tils/2020/11/12/git-bisect-automation.adoc
@@ -0,0 +1,25 @@
+= Git bisect automation
+:categories: git
+:sort: 1
+
+It is good to have an standardized way to run builds and tests on the repository
+of a project, so that you can find when a bug was introduced by using
+`git bisect run`.
+
+I've already been in the situation when a bug was introduced and I didn't know
+how it even was occurring, and running Git bisect over hundreds of commits to
+pinpoint the failing commit was very empowering:
+
+[source,sh]
+----
+$ GOOD_COMMIT_SHA=e1fd0a817d192c5a5df72dd7422e36558fa78e46
+$ git bisect start HEAD $GOOD_COMMIT_SHA
+$ git bisect run sn -c './build.sh && ./run-failing-case.sh'
+----
+
+Git will than do a binary search between the commits, and run the commands you
+provide it with to find the failing commit.
+
+Instead of being afraid of doing a bisect, you should instead leverage it, and
+make Git help you dig through the history of the repository to find the bad
+code.
diff --git a/src/content/en/tils/2020/11/12/useful-bashvars.adoc b/src/content/en/tils/2020/11/12/useful-bashvars.adoc
new file mode 100644
index 0000000..fb148fb
--- /dev/null
+++ b/src/content/en/tils/2020/11/12/useful-bashvars.adoc
@@ -0,0 +1,61 @@
+= Useful Bash variables
+:categories: shell
+
+:bash: https://www.gnu.org/software/bash/
+:bash-bang-bang: https://www.gnu.org/software/bash/manual/bash.html#Event-Designators
+:bash-dollar-underscore: https://www.gnu.org/software/bash/manual/bash.html#Special-Parameters
+
+{bash}[GNU Bash] has a few two letter variables that may be useful when typing
+on the terminal.
+
+== `!!`: the text of the last command
+
+The {bash-bang-bang}[`!!` variable] refers to the previous command, and I find
+useful when following chains for symlinks:
+
+[source,sh]
+----
+$ which git
+/run/current-system/sw/bin/git
+$ readlink $(!!)
+readlink $(which git)
+/nix/store/5bgr1xpm4m0r72h9049jbbhagxdyrnyb-git-2.28.0/bin/git
+----
+
+It is also useful when you forget to prefix `sudo` to a command that requires
+it:
+
+[source,sh]
+----
+$ requires-sudo.sh
+requires-sudo.sh: Permission denied
+$ sudo !!
+sudo ./requires-sudo.sh
+# all good
+----
+
+Bash prints the command expansion before executing it, so it is better for you
+to follow along what it is doing.
+
+== `$_`: most recent parameter
+
+The {bash-dollar-underscore}[`$_` variable] will give you the most recent
+parameter you provided to a previous argument, which can save you typing
+sometimes:
+
+[source,sh]
+----
+# instead of...
+$ mkdir -p a/b/c/d/
+$ cd a/b/c/d/
+
+# ...you can:
+$ mkdir -p a/b/c/d/
+$ cd $_
+----
+
+== Conclusion
+
+I wouldn't use those in a script, as it would make the script terser to read, I
+find those useful shortcut that are handy when writing at the interactive
+terminal.