mbox series

[v5,00/29] CI: run "make" in CI "steps", improve UX

Message ID cover-v5-00.29-00000000000-20220421T181526Z-avarab@gmail.com (mailing list archive)
Headers show
Series CI: run "make" in CI "steps", improve UX | expand

Message

Ævar Arnfjörð Bjarmason April 21, 2022, 6:22 p.m. UTC
This series changes CI "step" targets that are shellscripts that do N
things to instead be single command invocations at the "step" level,
driven by the CI recipe itself.

To do that we need to pass state that we previously re-setup for every
"step" via $GITHUB_ENV, whose state we then helpfully show (this is just
a standard GitHub CI feature) in a drop-down at the start of every
"step".

I.e. at the tip of this series you can reliably look at that
$GITHUB_ENV view to see what the full and relevant environment was for
that "make", "make test" or whatever.

Change since v4:

 * Minor UX improvements for 29/29, e.g. "error: " prefixes for error
   messages.
 * Addressed feedback from Phillip Wood at
   https://lore.kernel.org/git/1157a463-f6c6-1df5-59cd-419d73eed1df@gmail.com/:

   - That bash-specific ${../../} syntax is gone
   - The inverted "skip-test: no" is now a "skip-test: yes", as it should be.

   - The new "trace" output from ci/lib.sh now doesn't have "SKIP"
     lines, i.e. we just say what variables we do set, not what we
     don't set. E.g.:
     https://github.com/avar/git/runs/6093145633?check_suite_focus=true#step:4:13

   - I looked at the "a lot of churn" comment, there's e.g. "CI:
     export variables via a wrapper" where we first make a wrapper to
     "export" variables, then make further use of it, some of which
     involves touching the same lines again.

     Likewise first invoking ci/lib.sh, then splitting that up into
     ci/lib.sh --build and ci/lib.sh --test.

     I looked at squashing some of that together, but I think it
     really makes it harder to review & reason about to do N things at
     the same time, even if the net diff size is bigger.
 * Squashed together two commits that were adjusting bash syntax to be
   POSIX syntax.
 * For the pedantic job that skips tests the "ci/lib.sh --test" step
   of setting up variables for it is now also skipped. See:
   https://github.com/avar/git/runs/6093144782?check_suite_focus=true
 * Made ci/select-test-slice.sh do the same "are we in GitHub CI?"
   check as the rest of the scripts, it's now easier to run it
   stand-alone for testing.
 * Adjusted usage output, made it friendlier, moved those UX bits over
   to a test_commit-like getopts parsing.
 * Fixed a typo/commit message suggestion by Eric Sunshine.

 * This series contained a regression fix for an issue already on
   "master", which I've split out in
   https://lore.kernel.org/git/patch-v2-1.1-92acf9420a9-20220421T174733Z-avarab@gmail.com/

   When the two are merged there's a conflict that's resolved thusly,
   per a --remerge-diff (which I snipped away with [...]). I.e. gcc-8
   and gcc-9 need to be added to the linux-gcc and osx-gcc part of
   ci/lib.sh:
	
	diff --git a/ci/lib.sh b/ci/lib.sh
	remerge CONFLICT (content): Merge conflict in ci/lib.sh
	index 407e994edcd..a4e9d51ad6c 100755
	--- a/ci/lib.sh
	+++ b/ci/lib.sh
	@@ -30,126 +30,6 @@ usage() {
	 	then
	 		echo "$CI_TYPE_HELP" >&2
	 	fi
	-<<<<<<< ca24940186b (Merge branch 'avar/ci-have-osx-p4-install-fall-back-on-sha256-no-check' into build-master)
	-=======
	[...snipped ~100 lines ... ]
	->>>>>>> 92acf9420a9 (CI: select CC based on CC_PACKAGE (again))
	 	exit 1
	 }
	 
	@@ -373,7 +253,7 @@ vs-test)
	 	setenv --test MAKEFLAGS "$COMMON_MAKEFLAGS"
	 	;;
	 linux-gcc)
	-	CC=gcc
	+	CC=gcc-8
	 	setenv --test GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME main
	 	;;
	 linux-gcc-default)
	@@ -397,7 +277,7 @@ linux-TEST-vars)
	 	;;
	 osx-gcc)
	 	MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=$(which python3)"
	-	CC=gcc
	+	CC=gcc-9
	 	;;
	 osx-clang)
	 	MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=$(which python2)"

Ævar Arnfjörð Bjarmason (29):
  CI: run "set -ex" early in ci/lib.sh
  CI: make "$jobname" explicit, remove fallback
  CI: remove more dead Travis CI support
  CI: remove dead "tree skipping" code
  CI: remove unused Azure ci/* code
  CI/lib.sh: stop adding leading whitespace to $MAKEFLAGS
  CI: don't have "git grep" invoke a pager in tree content check
  CI: have "static-analysis" run a "make ci-static-analysis" target
  CI: have "static-analysis" run "check-builtins", not "documentation"
  CI: move p4 and git-lfs variables to ci/install-dependencies.sh
  CI: consistently use "export" in ci/lib.sh
  CI: export variables via a wrapper
  CI: remove "run-build-and-tests.sh", run "make [test]" directly
  CI: make ci/{lib,install-dependencies}.sh POSIX-compatible
  CI: check ignored unignored build artifacts in "win[+VS] build" too
  CI: invoke "make artifacts-tar" directly in windows-build
  CI: split up and reduce "ci/test-documentation.sh"
  CI: combine ci/install{,-docker}-dependencies.sh
  CI: move "env" definitions into ci/lib.sh
  ci/run-test-slice.sh: replace shelling out with "echo"
  CI: pre-select test slice in Windows & VS tests
  CI: only invoke ci/lib.sh as "steps" in main.yml
  CI: narrow down variable definitions in --build and --test
  CI: add more variables to MAKEFLAGS, except under vs-build
  CI: set CC in MAKEFLAGS directly, don't add it to the environment
  CI: set SANITIZE=leak in MAKEFLAGS directly
  CI: set PYTHON_PATH setting for osx-{clang,gcc} into "$jobname" case
  CI: don't use "set -x" in "ci/lib.sh" output
  CI: make it easy to use ci/*.sh outside of CI

 .github/workflows/main.yml            | 101 +++---
 Makefile                              |  31 +-
 ci/check-directional-formatting.bash  |   2 +-
 ci/check-unignored-build-artifacts.sh |  20 ++
 ci/install-dependencies.sh            |  82 +++--
 ci/install-docker-dependencies.sh     |  22 --
 ci/lib-ci-type.sh                     |   6 +
 ci/lib-online_cpus.sh                 |  26 ++
 ci/lib-tput.sh                        |   5 +
 ci/lib.sh                             | 424 ++++++++++++++++----------
 ci/make-test-artifacts.sh             |  12 -
 ci/mount-fileshare.sh                 |  25 --
 ci/print-test-failures.sh             |  53 +---
 ci/run-build-and-tests.sh             |  54 ----
 ci/run-docker-build.sh                |  66 ----
 ci/run-docker.sh                      |  47 ---
 ci/run-static-analysis.sh             |  32 --
 ci/run-test-slice.sh                  |  17 --
 ci/select-test-slice.sh               |  13 +
 ci/test-documentation.sh              |  37 +--
 ci/util/extract-trash-dirs.sh         |  50 ---
 shared.mak                            |   1 +
 22 files changed, 508 insertions(+), 618 deletions(-)
 create mode 100755 ci/check-unignored-build-artifacts.sh
 delete mode 100755 ci/install-docker-dependencies.sh
 create mode 100644 ci/lib-ci-type.sh
 create mode 100644 ci/lib-online_cpus.sh
 create mode 100644 ci/lib-tput.sh
 delete mode 100755 ci/make-test-artifacts.sh
 delete mode 100755 ci/mount-fileshare.sh
 delete mode 100755 ci/run-build-and-tests.sh
 delete mode 100755 ci/run-docker-build.sh
 delete mode 100755 ci/run-docker.sh
 delete mode 100755 ci/run-static-analysis.sh
 delete mode 100755 ci/run-test-slice.sh
 create mode 100755 ci/select-test-slice.sh
 delete mode 100755 ci/util/extract-trash-dirs.sh

Range-diff against v4:
 1:  ed27ca0b7e7 =  1:  84d8098e365 CI: run "set -ex" early in ci/lib.sh
 2:  737fe1e2c4c !  2:  3f5c071b0f6 CI: make "$jobname" explicit, remove fallback
    @@ ci/lib.sh
     +# Starting assertions
     +if test -z "$jobname"
     +then
    -+	echo "must set a CI jobname in the environment" >&2
    ++	echo "error: must set a CI jobname in the environment" >&2
     +	exit 1
     +fi
     +
 3:  d875069fc28 =  3:  c64845a4efb CI: remove more dead Travis CI support
 4:  2590459db33 =  4:  45856e67d5d CI: remove dead "tree skipping" code
 5:  e311ea8b9b3 =  5:  d4671148eb7 CI: remove unused Azure ci/* code
 6:  151f28e3818 =  6:  45ea80d0495 CI/lib.sh: stop adding leading whitespace to $MAKEFLAGS
 7:  6c2a8ee9c4e =  7:  a264b40ba0d CI: don't have "git grep" invoke a pager in tree content check
 8:  64a0a1fc8ce =  8:  4a58f7be8d4 CI: have "static-analysis" run a "make ci-static-analysis" target
 9:  0f780bf9e3c =  9:  78c0c81af43 CI: have "static-analysis" run "check-builtins", not "documentation"
10:  3cdeae9c141 = 10:  07e36035a1e CI: move p4 and git-lfs variables to ci/install-dependencies.sh
11:  1d3d357dcef = 11:  272bd590a95 CI: consistently use "export" in ci/lib.sh
12:  5ef0756d095 = 12:  ea35327e24c CI: export variables via a wrapper
13:  e0ce614eb6d ! 13:  f6ff81f48ab CI: remove "run-build-and-tests.sh", run "make [test]" directly
    @@ .github/workflows/main.yml: jobs:
                image: daald/ubuntu32:xenial
              - jobname: pedantic
                image: fedora
    -+          skip-tests: no
    ++          skip-tests: yes
          env:
            jobname: ${{matrix.vector.jobname}}
          runs-on: ubuntu-latest
    @@ .github/workflows/main.yml: jobs:
     +    - run: ci/lib.sh
     +    - run: make
     +    - run: make test
    -+      if: success() && matrix.vector.skip-tests != 'no'
    ++      if: success() && matrix.vector.skip-tests != 'yes'
          - run: ci/print-test-failures.sh
     -      if: failure()
    -+      if: failure() && matrix.vector.skip-tests != 'no'
    ++      if: failure() && matrix.vector.skip-tests != 'yes'
          - name: Upload failed tests' directories
            if: failure() && env.FAILED_TEST_ARTIFACTS != ''
            uses: actions/upload-artifact@v1
14:  a8e70124929 <  -:  ----------- ci/lib.sh: use "test" instead of "["
18:  eec7a11376e ! 14:  533dbc50c4f CI: make ci/install-dependencies.sh POSIX-compatible
    @@ Metadata
     Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## Commit message ##
    -    CI: make ci/install-dependencies.sh POSIX-compatible
    +    CI: make ci/{lib,install-dependencies}.sh POSIX-compatible
     
         Change the unportable constructs in the "ci/install-dependencies.sh"
         scripts to use POSIX replacements, and have it run under "/bin/sh"
    @@ Commit message
         "ci/install-docker-dependencies.sh", which doesn't have access to
         "bash".
     
    +    While we're at it change "if [" to "if test" in ci/lib.sh. This isn't
    +    strictly speaking a case of POSIX-incompatibility, but that syntax was
    +    being used there because this code was using idiomatic bash
    +    constructs. Let's have it use our usual style of "if test" instead.
    +
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## ci/install-dependencies.sh ##
    @@ ci/install-dependencies.sh: ubuntu-latest)
      	# Uncomment this if you want to run perf tests:
      	# brew install gnu-time
      	brew link --force gettext
    +@@ ci/install-dependencies.sh: macos-latest)
    + 
    + 	if test -n "$CC_PACKAGE"
    + 	then
    +-		BREW_PACKAGE=${CC_PACKAGE/-/@}
    ++		BREW_PACKAGE=$(echo $CC_PACKAGE | tr '-' '@')
    + 		brew install "$BREW_PACKAGE"
    + 		brew link "$BREW_PACKAGE"
    + 	fi
    +
    + ## ci/lib.sh ##
    +@@ ci/lib.sh: ubuntu-latest)
    + 		break
    + 	fi
    + 
    +-	if [ "$jobname" = linux-gcc ]
    ++	if test "$jobname" = linux-gcc
    + 	then
    + 		MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=/usr/bin/python3"
    + 	else
    +@@ ci/lib.sh: ubuntu-latest)
    + 	setenv --test GIT_TEST_HTTPD true
    + 	;;
    + macos-latest)
    +-	if [ "$jobname" = osx-gcc ]
    ++	if test "$jobname" = osx-gcc
    + 	then
    + 		MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=$(which python3)"
    + 	else
15:  bb335d1c0ca = 15:  6044c2b383f CI: check ignored unignored build artifacts in "win[+VS] build" too
16:  5458e6dab0b = 16:  4d1a9f88c32 CI: invoke "make artifacts-tar" directly in windows-build
17:  5e5a5b71700 = 17:  5c8f464a60f CI: split up and reduce "ci/test-documentation.sh"
19:  a9c98582de1 = 18:  a218be76819 CI: combine ci/install{,-docker}-dependencies.sh
20:  96e7eb68906 = 19:  83e21b4f501 CI: move "env" definitions into ci/lib.sh
21:  fdbe8554f5d = 20:  fd0e1610577 ci/run-test-slice.sh: replace shelling out with "echo"
22:  f257ab59971 ! 21:  0c7cd9d64ba CI: pre-select test slice in Windows & VS tests
    @@ ci/run-test-slice.sh => ci/select-test-slice.sh
      tests=$(echo $(cd t && ./helper/test-tool path-utils slice-tests "$1" "$2" \
      	t[0-9]*.sh))
     -make --quiet -C t T="$tests"
    -+echo T="$tests" >>$GITHUB_ENV
    ++if test -n "$GITHUB_ENV"
    ++then
    ++	echo T="$tests" >>$GITHUB_ENV
    ++fi
23:  1d95088da29 = 22:  1b077665352 CI: only invoke ci/lib.sh as "steps" in main.yml
24:  a7434b215db ! 23:  1867da7eddb CI: narrow down variable definitions in --build and --test
    @@ Commit message
         fewer, which makes diagnosing anything going on there easier, as we
         won't have to look at a deluge of e.g. GIT_TEST_* variables.
     
    +    For the "pedantic" job (which has no test phase) we won't run the
    +    "ci/lib.sh --test" step, which will be clearly visible as a skipped
    +    step in the UX.
    +
         Since we'll now always run "--build" for "make" and "--test" for "make
         test" we can stop setting the "fat" MAKEFLAGS entirely on the "test"
         steps, i.e. the one with PYTHON_PATH, CC etc. These will all be
    @@ .github/workflows/main.yml: jobs:
     +    - run: ci/lib.sh --build
          - run: make
     +    - run: ci/lib.sh --test
    ++      if: success() && matrix.vector.skip-tests != 'yes'
          - run: make test
    -       if: success() && matrix.vector.skip-tests != 'no'
    +       if: success() && matrix.vector.skip-tests != 'yes'
          - run: ci/print-test-failures.sh
     @@ .github/workflows/main.yml: jobs:
          steps:
    @@ .github/workflows/main.yml: jobs:
     
      ## ci/lib.sh ##
     @@ ci/lib.sh: set -ex
    + # Helper libraries
      . ${0%/*}/lib-ci-type.sh
      
    ++# Parse options
    ++mode_build=
    ++mode_test=
    ++while test $# != 0
    ++do
    ++	case "$1" in
    ++	--build)
    ++		mode_build=t
    ++		;;
    ++	--test)
    ++		mode_test=t
    ++		;;
    ++	-*)
    ++		echo "error: invalid option: $1" >&2
    ++		exit 1
    ++		;;
    ++	*)
    ++		echo "error: invalid argument: $1" >&2
    ++		exit 1
    ++		;;
    ++	esac
    ++	shift
    ++done
    ++
      # Starting assertions
    -+mode=$1
    -+if test -z "$mode"
    + if test -z "$jobname"
    + then
    +@@ ci/lib.sh: then
    + 	exit 1
    + fi
    + 
    ++if test "$mode_test$mode_build" != "t"
     +then
    -+	echo "need a $0 mode, e.g. --build or --test" >&2
    ++	echo "error: need one mode, e.g. --build or --test" >&2
     +	exit 1
     +fi
     +
    - if test -z "$jobname"
    - then
    - 	echo "must set a CI jobname in the environment" >&2
    -@@ ci/lib.sh: setenv () {
    + # Helper functions
    + setenv () {
      	while test $# != 0
      	do
      		case "$1" in
    --		--build)
    --			;;
    --		--test)
    + 		--build)
    ++			if test -z "$mode_build"
    ++			then
    ++				return 0
    ++			fi
    + 			;;
    + 		--test)
     -			;;
     -		--all)
    -+		--build | --test)
    -+			if test "$1" != "$mode"
    ++			if test -z "$mode_test"
     +			then
     +				return 0
     +			fi
    -+
      			;;
      		-*)
      			echo "BUG: bad setenv() option '$1'" >&2
25:  78f4609a9c1 = 24:  a4e3a9d2c28 CI: add more variables to MAKEFLAGS, except under vs-build
26:  26a34f1d4b9 ! 25:  48d99cee809 CI: set CC in MAKEFLAGS directly, don't add it to the environment
    @@ Commit message
         "$jobname" to select packages & config, 2021-11-23), i.e. we're now
         aiming to only set those variables specific jobs need.
     
    +    Since we don't need to make this generic enough to handle "gcc-9"
    +    turning into "gcc@9" for "brew install" let's remove what was
    +    originally a bash-specific replacement in 707d2f2fe86 (CI: use
    +    "$runs_on_pool", not "$jobname" to select packages & config,
    +    2021-11-23), and which a preceding commit changed to a "tr"
    +    invocation.
    +
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## .github/workflows/main.yml ##
    @@ ci/install-dependencies.sh: UBUNTU_COMMON_PKGS="make libssl-dev libcurl4-openssl
       libemail-valid-perl libio-socket-ssl-perl libnet-smtp-ssl-perl"
      
     +CC_PACKAGE=
    ++BREW_CC_PACKAGE=
     +case "$jobname" in
     +linux-gcc | linux-TEST-vars)
     +	CC_PACKAGE=gcc-8
     +	;;
     +osx-gcc)
    -+	CC_PACKAGE=gcc-9
    ++	BREW_CC_PACKAGE=gcc@9
     +	;;
     +esac
     +
      case "$runs_on_pool" in
      ubuntu-latest)
      	# The Linux build installs the defined dependency versions below.
    +@@ ci/install-dependencies.sh: macos-latest)
    + 	} ||
    + 	brew install homebrew/cask/perforce
    + 
    +-	if test -n "$CC_PACKAGE"
    ++	if test -n "$BREW_CC_PACKAGE"
    + 	then
    +-		BREW_PACKAGE=$(echo $CC_PACKAGE | tr '-' '@')
    +-		brew install "$BREW_PACKAGE"
    +-		brew link "$BREW_PACKAGE"
    ++		brew install "$BREW_CC_PACKAGE"
    ++		brew link "$BREW_CC_PACKAGE"
    + 	fi
    + 	;;
    + esac
     
      ## ci/lib.sh ##
     @@ ci/lib.sh: setenv () {
27:  514de8d16b0 = 26:  07a6c087297 CI: set SANITIZE=leak in MAKEFLAGS directly
28:  6501059c594 = 27:  50f21ffdffe CI: set PYTHON_PATH setting for osx-{clang,gcc} into "$jobname" case
29:  1bdcf1399d9 ! 28:  e35dff2bef3 CI: don't use "set -x" in "ci/lib.sh" output
    @@ Commit message
         script doesn't "set -x" and will act differently depending on the
         $CI_TYPE.
     
    +    It's useful when developing this script to see what variables
    +    it *doesn't* set, but such output isn't useful to users, so let's hide
    +    the "SKIP" output behind a --debug option.
    +
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
     
      ## ci/lib.sh ##
    @@ ci/lib.sh
      
      # Helper libraries
      . ${0%/*}/lib-ci-type.sh
    +@@ ci/lib.sh: set -ex
    + # Parse options
    + mode_build=
    + mode_test=
    ++mode_debug=
    + while test $# != 0
    + do
    + 	case "$1" in
    + 	--build)
    ++		echo "MODE: $1" >&2
    + 		mode_build=t
    + 		;;
    + 	--test)
    ++		echo "MODE: $1" >&2
    + 		mode_test=t
    + 		;;
    ++	--debug)
    ++		echo "DEBUG: $1" >&2
    ++		mode_debug=t
    ++		;;
    + 	-*)
    + 		echo "error: invalid option: $1" >&2
    + 		exit 1
     @@ ci/lib.sh: then
      	exit 1
      fi
    @@ ci/lib.sh: then
     +echo "CONFIG: CI_TYPE=$CI_TYPE" >&2
     +echo "CONFIG: jobname=$jobname" >&2
     +echo "CONFIG: runs_on_pool=$runs_on_pool" >&2
    -+echo "CONFIG: GITHUB_ENV=$GITHUB_ENV" >&2
     +if test -n "$GITHUB_ENV"
     +then
     +	echo "CONFIG: GITHUB_ENV=$GITHUB_ENV" >&2
     +fi
    ++echo >&2
     +
      # Helper functions
      setenv () {
    -+	local skip=
    ++	skip=
      	while test $# != 0
      	do
      		case "$1" in
    - 		--build | --test)
    - 			if test "$1" != "$mode"
    + 		--build)
    + 			if test -z "$mode_build"
    + 			then
    +-				return 0
    ++				skip=t
    + 			fi
    + 			;;
    + 		--test)
    + 			if test -z "$mode_test"
      			then
     -				return 0
     +				skip=t
      			fi
    - 
      			;;
    + 		-*)
     @@ ci/lib.sh: setenv () {
      	val=$2
      	shift 2
      
     +	if test -n "$skip"
     +	then
    -+		echo "SKIP '$key=$val'" >&2
    ++		if test -n "$mode_debug"
    ++		then
    ++			echo "SKIP: '$key=$val'" >&2
    ++		fi
     +		return 0
     +	fi
     +
30:  94abb826627 <  -:  ----------- CI: have osx-gcc use gcc, not clang
31:  4fc67e668da ! 29:  13d8c6997c3 CI: make it easy to use ci/*.sh outside of CI
    @@ Commit message
         Using "ci/lib.sh" as a stand-alone script is much more useful if it
         doesn't hardcode NPROC=10, let's provide a poor shellscript
         replacement for the online_cpus() we have in thread-utils.c to cover
    -    the most common OS's. It was suggested to use "2>&1" to invoke
    -    "command -v", but per my reading of [2] and my own testing that
    -    doesn't seem to be needed. Perhaps it's only needed for "which(1)"?
    -
    -    1. https://lore.kernel.org/git/214f8670-91d5-f4b6-efa1-76966c3ab1ee@sunshineco.com/
    -    2. https://pubs.opengroup.org/onlinepubs/009604499/utilities/command.html
    +    the most common OS's.
     
         Helped-by: Eric Sunshine <sunshine@sunshineco.com>
         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
    @@ ci/lib-online_cpus.sh (new)
     +#!/bin/sh
     +
     +# TODO: Ideally we'd compile t/helper/test-online-cpus.c early, but
    -+# that presents a chicken & egg problem. But if we move it to a
    -+# stand-oline command...
    ++# that currently presents a chicken & egg problem. We need this before
    ++# we build (much of) anything.
     +online_cpus() {
     +	NPROC=
     +
    @@ ci/lib.sh
      #!/bin/sh
      set -e
      
    -+#  Usage
    ++# Usage
     +CI_TYPE_HELP_COMMANDS='
     +	# run "make all test" like the "linux-leaks" job
     +	(eval $(jobname=linux-leaks ci/lib.sh --all) && make test)
    @@ ci/lib.sh
     +'
     +
     +CI_TYPE_HELP="
    -+running $0 outside of CI? You can use ci/lib.sh to set up your
    ++Running $0 outside of CI? You can use ci/lib.sh to set up your
     +environment like a given CI job. E.g.:
     +$CI_TYPE_HELP_COMMANDS
    -+
    -+note that some of these (e.g. the linux-musl one) may not work as
    ++Note that some of these (e.g. the linux-musl one) may not work as
     +expected due to the CI job configuring a platform that may not match
     +yours."
     +
    - # Helper libraries
    - . ${0%/*}/lib-ci-type.sh
    - 
    -@@ ci/lib.sh: mode=$1
    - if test -z "$mode"
    - then
    - 	echo "need a $0 mode, e.g. --build or --test" >&2
    ++usage() {
    ++	echo "usage: jobname=<job-name> [runs_on_pool=<pool-name>] $0 (--build | --test)" >&2
     +	if test -z "$CI_TYPE"
     +	then
     +		echo "$CI_TYPE_HELP" >&2
     +	fi
    - 	exit 1
    ++	exit 1
    ++}
    ++
    + # Helper libraries
    + . ${0%/*}/lib-ci-type.sh
    + 
    + # Parse options
    ++mode_all=
    + mode_build=
    + mode_test=
    + mode_debug=
    + while test $# != 0
    + do
    + 	case "$1" in
    ++	--all)
    ++		echo "MODE: $1" >&2
    ++		mode_all=t
    ++		mode_build=t
    ++		mode_test=t
    ++		;;
    + 	--build)
    + 		echo "MODE: $1" >&2
    + 		mode_build=t
    +@@ ci/lib.sh: do
    + 		;;
    + 	-*)
    + 		echo "error: invalid option: $1" >&2
    +-		exit 1
    ++		usage
    + 		;;
    + 	*)
    + 		echo "error: invalid argument: $1" >&2
    +-		exit 1
    ++		usage
    + 		;;
    + 	esac
    + 	shift
    +@@ ci/lib.sh: done
    + if test -z "$jobname"
    + then
    + 	echo "error: must set a CI jobname in the environment" >&2
    +-	exit 1
    ++	usage
      fi
      
    +-if test "$mode_test$mode_build" != "t"
    ++if test "$mode_test$mode_build" != "t" && test -z "$mode_all"
    + then
    + 	echo "error: need one mode, e.g. --build or --test" >&2
    +-	exit 1
    ++	usage
    + fi
    + 
    + # Show our configuration
     @@ ci/lib.sh: setenv () {
      	do
      		case "$1" in
    - 		--build | --test)
    --			if test "$1" != "$mode"
    -+			if test "$1" != "$mode" && test "$mode" != "--all"
    + 		--build)
    +-			if test -z "$mode_build"
    ++			if test -z "$mode_build$mode_all"
    + 			then
    + 				skip=t
    + 			fi
    + 			;;
    + 		--test)
    +-			if test -z "$mode_test"
    ++			if test -z "$mode_test$mode_all"
      			then
      				skip=t
      			fi