Re-vendor the shared files from sneak/prompts at dd4027b (closes #113)
check / check (push) Waiting to run
check / check (push) Waiting to run
The shared files are the sneak/prompts copies at dd4027b, with this repository's own entries after them. make lint and make test each build one Dockerfile phase without the cache, both covering the frontend through a node stage; the builder stage waits on both and takes its version from git describe unless VERSION is given. golangci-lint moves to v2.14.0 with the new .golangci.yml; one test spells X-Request-ID as canonicalheader asks. prettier formats only JavaScript, CSS, HTML and Markdown, so .golangci.yml stays as fetched. script/fmt and script/fmt-check put ~/.local/bin on PATH, which the shared workflow no longer does. script/bootstrap keeps a Go only if it is exactly GO_VERSION, and re-checks the go on PATH after installing. Model: opus-5-5
This commit is contained in:
+30
-15
@@ -6,17 +6,16 @@
|
||||
# used directly if it is at least NODE_MIN_VERSION; otherwise it is
|
||||
# installed at a pinned version via nvm (installing nvm itself first,
|
||||
# from a hash-verified release archive, never curl | sh). Go, with its
|
||||
# gofmt, is used directly if it is at least the version backend/go.mod
|
||||
# asks for; otherwise the pinned Go release is installed from its
|
||||
# hash-verified archive.
|
||||
# gofmt, is used directly only if it is exactly GO_VERSION; otherwise
|
||||
# that release is installed from its hash-verified archive.
|
||||
#
|
||||
# What this script installs outside the system package manager lives
|
||||
# under $HOME and is linked into ~/.local/bin, where make and the git
|
||||
# hook find it once that directory is on PATH. Nothing in ~/.local/bin
|
||||
# that this script did not create is ever replaced.
|
||||
#
|
||||
# golangci-lint is not installed: make lint runs it in Docker, which
|
||||
# this script does not install either.
|
||||
# golangci-lint is not installed: make lint runs it in Docker, as make
|
||||
# test runs the tests, and this script does not install Docker either.
|
||||
#
|
||||
# Unlike the org model: Go and gcc for backend/, a newer node for eslint.
|
||||
set -eu
|
||||
@@ -186,20 +185,29 @@ ensure_yarn() {
|
||||
}
|
||||
|
||||
# go_ok: the go on PATH has its gofmt beside it (a Go release ships the
|
||||
# two together) and is at least the version backend/go.mod asks for.
|
||||
# GOTOOLCHAIN=local makes an older go fail here instead of fetching a
|
||||
# newer toolchain for itself.
|
||||
# two together) and go version reports exactly GO_VERSION, compared over
|
||||
# the whole version, not a prefix of it. A go that fails or prints
|
||||
# anything else does not pass. GOTOOLCHAIN=local makes go report itself
|
||||
# rather than a toolchain it would fetch.
|
||||
go_ok() {
|
||||
if missing go; then return 1; fi
|
||||
[ -x "$(dirname "$(command -v go)")/gofmt" ] || return 1
|
||||
(cd "$ROOT/backend" && GOTOOLCHAIN=local go list -m >/dev/null 2>&1)
|
||||
case "$(GOTOOLCHAIN=local go version 2>/dev/null)" in
|
||||
"go version go$GO_VERSION "*) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# ensure_go: unless go_ok, install GO_VERSION and link its go and gofmt.
|
||||
# They are linked on every run that needs them, so a deleted link is put
|
||||
# back, and the archive is unpacked again if either binary is missing.
|
||||
# Afterwards go is looked up through PATH again and must pass go_ok, so
|
||||
# another go that hides the link stops bootstrap.
|
||||
ensure_go() {
|
||||
if go_ok; then return 0; fi
|
||||
if go_ok; then
|
||||
echo "bootstrap: using $(GOTOOLCHAIN=local go version)"
|
||||
return 0
|
||||
fi
|
||||
go_dir="$TOOLCHAIN/go-$GO_VERSION"
|
||||
if [ ! -x "$go_dir/bin/go" ] || [ ! -x "$go_dir/bin/gofmt" ]; then
|
||||
# sha256 of each archive, from https://go.dev/dl/?mode=json
|
||||
@@ -240,6 +248,13 @@ ensure_go() {
|
||||
fi
|
||||
link_bin "$go_dir/bin/go" go
|
||||
link_bin "$go_dir/bin/gofmt" gofmt
|
||||
hash -r
|
||||
if ! go_ok; then
|
||||
echo "bootstrap: after installing go $GO_VERSION in $go_dir," >&2
|
||||
echo " the go on PATH, $(command -v go), is not it or has no gofmt" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "bootstrap: installed $(GOTOOLCHAIN=local go version)"
|
||||
}
|
||||
|
||||
main() {
|
||||
@@ -256,9 +271,9 @@ main() {
|
||||
|
||||
if missing make; then pkg_install gnumake make make make; fi
|
||||
if missing git; then pkg_install git git git git; fi
|
||||
# The race detector in make test needs cgo, which Go turns on only
|
||||
# when it finds its C compiler, gcc on Linux. apt and apk ship the C
|
||||
# library headers apart from gcc.
|
||||
# The race detector in backend/'s make test needs cgo, which Go turns
|
||||
# on only when it finds its C compiler, gcc on Linux. apt and apk
|
||||
# ship the C library headers apart from gcc.
|
||||
if missing gcc; then
|
||||
pkg_install gcc "gcc libc6-dev" gcc "gcc musl-dev"
|
||||
fi
|
||||
@@ -271,8 +286,8 @@ main() {
|
||||
(cd "$ROOT/backend" && go mod download)
|
||||
|
||||
if missing docker; then
|
||||
echo "bootstrap: docker not found; make lint, and so make check" >&2
|
||||
echo " and the pre-commit hook, need it to run the linters" >&2
|
||||
echo "bootstrap: docker not found; make test and make lint, and so" >&2
|
||||
echo " make check and the pre-commit hook, need it" >&2
|
||||
fi
|
||||
if [ -n "$path_hint" ] && [ -d "$BIN_DIR" ]; then
|
||||
echo "bootstrap: add $BIN_DIR to the front of your PATH, e.g." >&2
|
||||
|
||||
+3
-1
@@ -1,6 +1,8 @@
|
||||
#!/bin/sh
|
||||
# script/check: run all checks (test, lint, fmt-check). Our own
|
||||
# extension to scripts-to-rule-them-all. Must not modify any files.
|
||||
# extension to scripts-to-rule-them-all. test and lint are Docker
|
||||
# phases; fmt-check is native, because a formatter writes the working
|
||||
# tree. Must not modify any files.
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
|
||||
+5
-2
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
# script/fmt: format the whole repo (writes): prettier over everything
|
||||
# it understands, then gofmt over the Go backend.
|
||||
# script/fmt: format the whole repo (writes): prettier over the
|
||||
# JavaScript, CSS, HTML and Markdown, then gofmt over the Go backend.
|
||||
# The org model formats only markdown; this repo also has JS and Go.
|
||||
set -eu
|
||||
|
||||
@@ -8,6 +8,9 @@ ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
# script/bootstrap links the node, yarn and gofmt it installs into
|
||||
# ~/.local/bin, which the shell that called it may not have on PATH.
|
||||
PATH="$HOME/.local/bin:$PATH"
|
||||
"$ROOT/script/frontend-fmt"
|
||||
"$ROOT/backend/script/fmt"
|
||||
}
|
||||
|
||||
@@ -8,6 +8,9 @@ ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
# script/bootstrap links the node, yarn and gofmt it installs into
|
||||
# ~/.local/bin, which the shell that called it may not have on PATH.
|
||||
PATH="$HOME/.local/bin:$PATH"
|
||||
"$ROOT/script/frontend-fmt-check"
|
||||
"$ROOT/backend/script/fmt-check"
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/bin/sh
|
||||
# script/frontend-check: run the frontend tests and format check only.
|
||||
# This exists for the frontend stage of Dockerfile, a node image with
|
||||
# neither Go nor Docker; the Dockerfile's frontend-lint stage runs the
|
||||
# frontend linter, and its lint and builder stages gate the backend.
|
||||
# Everywhere else, use script/check, which covers the whole repo. Must
|
||||
# not modify any files.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
"$ROOT/script/frontend-test"
|
||||
"$ROOT/script/frontend-fmt-check"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
+5
-3
@@ -1,6 +1,8 @@
|
||||
#!/bin/sh
|
||||
# script/frontend-fmt: format the frontend and every other file prettier
|
||||
# understands, repo-wide (writes), the markdown in backend/ included.
|
||||
# script/frontend-fmt: format the JavaScript, CSS, HTML and Markdown,
|
||||
# repo-wide (writes), the markdown in backend/ included. Those are the
|
||||
# languages REPO_POLICIES.md gives prettier; the YAML is left alone, as
|
||||
# backend/.golangci.yml must stay the org standard byte for byte.
|
||||
# Prettier does not read Go; backend/script/fmt formats the Go sources.
|
||||
set -eu
|
||||
|
||||
@@ -8,7 +10,7 @@ ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
yarn prettier --write .
|
||||
yarn prettier --write '**/*.{js,css,html,md}'
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -7,7 +7,7 @@ ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
yarn prettier --check .
|
||||
yarn prettier --check '**/*.{js,css,html,md}'
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
#!/bin/sh
|
||||
# script/frontend-lint: run eslint over the frontend. This runs inside
|
||||
# the frontend-lint stage of Dockerfile, the digest-pinned node image
|
||||
# with the packages from yarn.lock. From a checkout, run `make lint`,
|
||||
# which builds that stage.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
yarn eslint .
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -1,7 +1,8 @@
|
||||
#!/bin/sh
|
||||
# script/frontend-test: run the frontend test suite: the unit tests in
|
||||
# test/unit/, through the test script in package.json, then the
|
||||
# production build, which fails on broken code. The tests print a dot
|
||||
# script/frontend-test: run the frontend test suite on the host: the
|
||||
# unit tests in test/unit/, through the test script in package.json,
|
||||
# then the production build, which fails on broken code. make test runs
|
||||
# the same in the frontend stage of Dockerfile. The tests print a dot
|
||||
# each; if any fails, they run again with every test listed, and the
|
||||
# script fails even if that run passes. NODE_OPTIONS chooses the
|
||||
# reporter because yarn adds its arguments after the test files, where
|
||||
@@ -12,9 +13,9 @@ ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
NODE_OPTIONS=--test-reporter=dot timeout 30 yarn --silent run test || {
|
||||
NODE_OPTIONS=--test-reporter=dot timeout 90 yarn --silent run test || {
|
||||
echo "--- Rerunning with every test listed for details ---"
|
||||
NODE_OPTIONS=--test-reporter=spec timeout 30 yarn --silent run test
|
||||
NODE_OPTIONS=--test-reporter=spec timeout 90 yarn --silent run test
|
||||
exit 1
|
||||
}
|
||||
timeout 30 yarn build
|
||||
|
||||
+13
-13
@@ -1,23 +1,23 @@
|
||||
#!/bin/sh
|
||||
# script/lint: lint the whole repo: eslint over the frontend, then the Go
|
||||
# linter over backend/.
|
||||
# script/lint: run the linter. Linting is a phase of the Dockerfile and
|
||||
# this builds that phase alone; the linter is never installed or run on
|
||||
# a developer host, where a shared result cache and a host-global lock
|
||||
# make its answer untrustworthy.
|
||||
#
|
||||
# No linter runs on the host: this builds the frontend-lint and lint
|
||||
# stages of Dockerfile, the digest-pinned node and golangci-lint images.
|
||||
# The first runs eslint; the second runs the backend's fmt-check and
|
||||
# lint targets. --no-cache makes each linter really run every time
|
||||
# rather than reuse an earlier result, and each stage is built for its
|
||||
# checks alone, so no image is kept.
|
||||
# The phase is not the last stage in the file, so it is built only when
|
||||
# --target names it. --no-cache because a cached lint layer is a lint
|
||||
# that did not run. The tag makes each build replace the previous image
|
||||
# instead of leaving a dangling one behind.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
timeout 300 docker build --no-cache --target frontend-lint \
|
||||
--output type=cacheonly .
|
||||
timeout 300 docker build --no-cache --target lint \
|
||||
--output type=cacheonly .
|
||||
docker build --no-cache \
|
||||
--target lint \
|
||||
-t "$("$SCRIPT_DIR/projectname")-lint" .
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
+10
-8
@@ -1,17 +1,19 @@
|
||||
#!/bin/sh
|
||||
# script/test: run the test suite for the whole repo: the frontend at
|
||||
# the repo root, then the Go backend in backend/. Each half has its own
|
||||
# 30-second limit, and there is none around both: from a cold Go build
|
||||
# cache, compiling the backend's tests with the race detector can take
|
||||
# 30 seconds on its own, and Go's -timeout leaves the compile out.
|
||||
# script/test: run the test suite. Testing is a phase of the Dockerfile
|
||||
# and this builds that phase alone, on the same terms as script/lint:
|
||||
# --target because a phase that is not the last stage is built only when
|
||||
# named, --no-cache because a cached test layer is a test that did not
|
||||
# run, and a tag so each build replaces the previous image.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
script/frontend-test
|
||||
backend/script/test
|
||||
docker build --no-cache \
|
||||
--target test \
|
||||
-t "$("$SCRIPT_DIR/projectname")-test" .
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
Reference in New Issue
Block a user