Repository navigation
Expand file tree
/
Copy pathTaskfile.yml
More file actions
176 lines (151 loc) · 7.09 KB
/
Copy pathTaskfile.yml
File metadata and controls
176 lines (151 loc) · 7.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
version: "3"
# Everything in this repository is driven by `task`. `task` lists what there is;
# `task verify` is the whole gate, and CI runs the same tasks.
vars:
IMAGE: '{{.IMAGE | default "ghcr.io/configbutler/krm-foyer"}}'
# The krm-stream browser bundle the hello example vendors, and npm's integrity for
# its package. Bump both together, then `task vendor-krm-stream`.
KRM_STREAM_VERSION: 0.10.0
KRM_STREAM_INTEGRITY: sha512-Wjl0sq6he959ximL+0wHU1on+mfVfT+MyrJucp+sfd7idepOdBFjwWSv43L34oVRsY/1+QFZcheaoiubPlmEFQ==
VERSION:
sh: git describe --tags --always --dirty 2>/dev/null || echo dev
tasks:
default:
desc: "List the available tasks."
cmds:
- task --list
silent: true
verify:
desc: "The whole gate, in the order CI runs it. If this passes, CI passes."
cmds:
# Sequential on purpose: the first failure is the one you want to read.
- task: tidy-check
- task: vendor-check
- task: lint
- task: test
- task: image-smoke
- task: test-e2e
test:
desc: "Go tests with the race detector, a short fuzz run, and the browser helper's tests."
cmds:
# -race stays on: a proxy that fans streams out to many browsers is where a
# data race turns into one user seeing another's data.
- go test -race ./...
# Short runs of the path, response, CSRF, forged-cookie and return-path properties on top of their seeds, which
# the line above already runs. -fuzz takes one package and one target at a time.
- go test -run '^$' -fuzz '^FuzzCheckPath$' -fuzztime 10s ./internal/proxy/
- go test -run '^$' -fuzz '^FuzzCheckResponse$' -fuzztime 10s ./internal/proxy/
- go test -run '^$' -fuzz '^FuzzCheckMutation$' -fuzztime 10s ./internal/session/
- go test -run '^$' -fuzz '^FuzzForgedCookie$' -fuzztime 10s ./internal/session/
- go test -run '^$' -fuzz '^FuzzLocalPath$' -fuzztime 10s ./internal/auth/
- go test -run '^$' -fuzz '^FuzzDecisionsAreTransparent$' -fuzztime 10s ./internal/stream/
# The browser helper, /_foyer/foyer.js, with Node's own test runner: no npm, no build.
- node --test 'internal/pages/*.test.js'
vendor-krm-stream:
desc: "Vendor krm-stream's browser bundle into the hello example, from npm, checked against npm's integrity."
cmds:
- test/vendor-krm-stream.sh {{.KRM_STREAM_VERSION}} {{.KRM_STREAM_INTEGRITY}} examples/hello/web/krm-stream.js
vendor-check:
desc: "Check that the hello example's krm-stream bundle is the published one, byte for byte."
cmds:
- |
tmp="$(mktemp -d)"; trap 'rm -rf "$tmp"' EXIT
test/vendor-krm-stream.sh {{.KRM_STREAM_VERSION}} {{.KRM_STREAM_INTEGRITY}} "$tmp/krm-stream.js"
cmp "$tmp/krm-stream.js" examples/hello/web/krm-stream.js
test-e2e:
desc: "End-to-end suite against a real API server, a real Dex and krm-foyer in the cluster. Brings the fixture up if needed."
cmds:
- task: e2e-up
- task: e2e-deploy
# The suite is behind a build tag so `task test` stays fast. Pending specs are the
# krm-foyer claims not implemented yet; they are listed, not failed.
- go test -tags e2e -count=1 -timeout 15m ./test/e2e/ {{.CLI_ARGS}}
e2e-up:
desc: "Start (or reuse) the e2e fixture: k3d, Dex, an API server that trusts it, and Traefik as the Gateway."
cmds:
- test/e2e/cluster/start-cluster.sh
- test/e2e/cluster/install-traefik.sh
e2e-deploy:
desc: "Build the image, deploy krm-foyer into the e2e fixture (as cluster-admin bait), put the hello example in front of it, and Room Pass's QR login beside it."
deps: [image]
cmds:
- IMAGE={{.IMAGE}}:{{.VERSION}} test/e2e/cluster/deploy-foyer.sh
- test/e2e/cluster/front-door.sh
- test/e2e/cluster/room-pass.sh
demo:
desc: "Start the hello example in a disposable cluster, for a browser on this machine. task e2e-down removes it."
cmds:
- task: e2e-up
- task: e2e-deploy
- |
cat <<'EOF'
Open https://foyer.localhost:8443 and sign in at Dex with password "password" as
alice@example.com, who may edit the notes, or
bob@example.com, who may only read them.
The certificates come from the fixture's own CA. Import .e2e/ca.crt into your
browser, or accept the warning for foyer.localhost and then for dex.localhost.
EOF
e2e-down:
desc: "Delete the e2e fixture and its generated certificates."
cmds:
- test/e2e/cluster/stop-cluster.sh
lint:
desc: "Vet and lint the Go code, the workflows, the Dockerfiles and the Helm chart."
deps: [lint-go, lint-actions, lint-dockerfiles, lint-helm]
lint-go:
cmds:
- go vet ./...
- golangci-lint run ./...
lint-actions:
desc: "actionlint: expressions, needs/runs-on, and shellcheck on every run: block."
cmds:
- actionlint
lint-dockerfiles:
cmds:
- hadolint Dockerfile .devcontainer/Dockerfile
lint-helm:
desc: "helm lint, with the e2e fixture's values: the chart's defaults leave its required values empty."
cmds:
# The schema and the rendered arguments are tested in cmd/krm-foyer/chart_test.go.
- helm lint --strict charts/krm-foyer -f test/e2e/cluster/foyer-values.yaml
- helm lint --strict charts/krm-foyer -f test/e2e/cluster/foyer-values.yaml -f test/e2e/cluster/foyer-brief-values.yaml
- helm lint --strict charts/krm-foyer -f test/e2e/cluster/foyer-room-values.yaml
fmt:
desc: "Format the Go code."
cmds:
- golangci-lint fmt ./...
tidy-check:
desc: "Fail if go.mod or go.sum is not tidy."
cmds:
- go mod tidy -diff
build:
desc: "Build the binary into bin/."
cmds:
- CGO_ENABLED=0 go build -trimpath -ldflags "-X main.version={{.VERSION}}" -o bin/krm-foyer ./cmd/krm-foyer
run:
desc: "Run krm-foyer locally on :8080."
cmds:
- go run ./cmd/krm-foyer -listen :8080
image:
desc: "Build the container image (IMAGE and VERSION can be overridden)."
cmds:
- docker build --build-arg VERSION={{.VERSION}} -t {{.IMAGE}}:{{.VERSION}} .
image-smoke:
desc: "Start the image and check that it answers /healthz and the start page."
deps: [image]
vars:
# Probing from a container on a private network, not through a published port:
# in the devcontainer Docker runs beside us (docker-outside-of-docker), so a
# port published on the host's 127.0.0.1 is not reachable from here.
CURL: curlimages/curl:8.22.0@sha256:58adaa4e8dca9c988bae2aba4ab3434a0bb2da16bbe3f92dec39ec7785166777
cmds:
- |
set -euo pipefail
net="krm-foyer-smoke-$$"
docker network create "$net" >/dev/null
id="$(docker run -d --rm --network "$net" --name "$net" {{.IMAGE}}:{{.VERSION}})"
trap 'docker stop "$id" >/dev/null; docker network rm "$net" >/dev/null' EXIT
docker run --rm --network "$net" {{.CURL}} \
-fsS --retry 10 --retry-connrefused --retry-delay 1 "http://$net:8080/healthz"
docker run --rm --network "$net" {{.CURL}} -fsS "http://$net:8080/" | grep -q 'krm-foyer is running'
echo "image answers /healthz and serves the start page"