diff options
Diffstat (limited to 'src/content/en/tils/2020/11/12')
-rw-r--r-- | src/content/en/tils/2020/11/12/diy-nix-bash-ci.adoc | 63 | ||||
-rw-r--r-- | src/content/en/tils/2020/11/12/git-bisect-automation.adoc | 25 | ||||
-rw-r--r-- | src/content/en/tils/2020/11/12/useful-bashvars.adoc | 61 |
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. |