Pin tailwindcss and check the committed stylesheet against it (closes #231) #473
@@ -28,10 +28,10 @@ jobs:
|
|||||||
|
|
||||||
- name: Fingerprint the build context
|
- name: Fingerprint the build context
|
||||||
# Writes the hash of the commit being checked into the context, which
|
# Writes the hash of the commit being checked into the context, which
|
||||||
# invalidates the `COPY . .` layer of both check stages: a commit
|
# invalidates the `COPY . .` layer of every check stage: a commit
|
||||||
# that was never linted, format-checked, tested and built cannot
|
# that was never linted, format-checked, stylesheet-checked, tested
|
||||||
# report success from cache.
|
# and built cannot report success from cache.
|
||||||
run: git rev-parse HEAD > .ci-fingerprint
|
run: git rev-parse HEAD > .ci-fingerprint
|
||||||
|
|
||||||
- name: Build Docker image (runs make fmt-check, golangci-lint, make test, make build)
|
- name: Build Docker image (runs make fmt-check, golangci-lint, the stylesheet check, make test, make build)
|
||||||
run: script/cibuild
|
run: script/cibuild
|
||||||
|
|||||||
+38
-1
@@ -29,14 +29,51 @@ RUN script/assets
|
|||||||
RUN --network=none golangci-lint config verify --config .golangci.yml
|
RUN --network=none golangci-lint config verify --config .golangci.yml
|
||||||
RUN --network=none golangci-lint run --config .golangci.yml --build-tags browser ./...
|
RUN --network=none golangci-lint run --config .golangci.yml --build-tags browser ./...
|
||||||
|
|
||||||
|
# Stylesheet stages. static/css/tailwind.css is generated, by this pinned
|
||||||
|
# tailwindcss, from static/css/input.css and the files its @source lines
|
||||||
|
# name. `make css` (script/css) writes it out from the css-output stage.
|
||||||
|
# The css-check stage fails when the committed file differs from what is
|
||||||
|
# generated; `make check` runs it, and so does the build stage below.
|
||||||
|
#
|
||||||
|
# tailwindcss v4.2.1 standalone CLI, released 2026-02-23: one binary per
|
||||||
|
# architecture, each pinned by its sha256 from the release's sha256sums.txt.
|
||||||
|
# debian:bookworm-slim, 2026-10-02: the binary needs glibc.
|
||||||
|
FROM debian:bookworm-slim@sha256:3783cc01769c7b2b1b83a5c5ad96c815348e28ed7da68e2e3687004faa906251 AS tailwind-amd64
|
||||||
|
ADD --checksum=sha256:39e8d4e24b3c83b0a6e69e100a972fbc75d5fef8dce47b3ddac3cf92dea81fe3 --chmod=755 \
|
||||||
|
https://github.com/tailwindlabs/tailwindcss/releases/download/v4.2.1/tailwindcss-linux-x64 /usr/local/bin/tailwindcss
|
||||||
|
|
||||||
|
FROM debian:bookworm-slim@sha256:3783cc01769c7b2b1b83a5c5ad96c815348e28ed7da68e2e3687004faa906251 AS tailwind-arm64
|
||||||
|
ADD --checksum=sha256:d87e6486bb3f70b04ef1dcaacc4ee6548a5a15fbf521b31bc24d2c774f68a951 --chmod=755 \
|
||||||
|
https://github.com/tailwindlabs/tailwindcss/releases/download/v4.2.1/tailwindcss-linux-arm64 /usr/local/bin/tailwindcss
|
||||||
|
|
||||||
|
# TARGETARCH, set by docker, is the architecture being built for.
|
||||||
|
FROM tailwind-${TARGETARCH} AS css
|
||||||
|
WORKDIR /src
|
||||||
|
COPY . .
|
||||||
|
RUN tailwindcss -i static/css/input.css -o /out/tailwind.css --minify
|
||||||
|
|
||||||
|
FROM scratch AS css-output
|
||||||
|
COPY --from=css /out/tailwind.css /
|
||||||
|
|
||||||
|
# Both files are split after each "}", one rule per line, so that when they
|
||||||
|
# differ the diff shows the rules that differ.
|
||||||
|
FROM css AS css-check
|
||||||
|
RUN sed 's/}/}\n/g' static/css/tailwind.css > /tmp/committed.css \
|
||||||
|
&& sed 's/}/}\n/g' /out/tailwind.css > /tmp/generated.css \
|
||||||
|
&& diff -U0 /tmp/committed.css /tmp/generated.css || { \
|
||||||
|
echo "static/css/tailwind.css is not what make css generates; run make css" >&2; \
|
||||||
|
exit 1; \
|
||||||
|
}
|
||||||
|
|
||||||
# Build stage
|
# Build stage
|
||||||
# golang:1.26.1-bookworm (Debian-based), 2026-03-17
|
# golang:1.26.1-bookworm (Debian-based), 2026-03-17
|
||||||
# Using Debian-based image because gorm.io/driver/sqlite pulls in
|
# Using Debian-based image because gorm.io/driver/sqlite pulls in
|
||||||
# mattn/go-sqlite3 (CGO), which does not compile on Alpine musl.
|
# mattn/go-sqlite3 (CGO), which does not compile on Alpine musl.
|
||||||
FROM golang:1.26.1-bookworm@sha256:4465644228bc2857a954b092167e12aa59c006a3492282a6c820bf4755fd64a4 AS builder
|
FROM golang:1.26.1-bookworm@sha256:4465644228bc2857a954b092167e12aa59c006a3492282a6c820bf4755fd64a4 AS builder
|
||||||
|
|
||||||
# Depend on lint stage passing
|
# Depend on the lint and stylesheet check stages passing
|
||||||
COPY --from=lint /src/go.sum /dev/null
|
COPY --from=lint /src/go.sum /dev/null
|
||||||
|
COPY --from=css-check /out/tailwind.css /dev/null
|
||||||
|
|
||||||
# jq is a runtime dependency of script/ci-mark-superseded, which the test
|
# jq is a runtime dependency of script/ci-mark-superseded, which the test
|
||||||
# suite executes. git is what script/version derives the version with.
|
# suite executes. git is what script/version derives the version with.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.PHONY: bootstrap setup assets test test-browser lint fmt fmt-check check build run dev deps docker clean hooks css version
|
.PHONY: bootstrap setup assets test test-browser lint fmt fmt-check check build run dev deps docker clean hooks css css-check version
|
||||||
|
|
||||||
# Default target
|
# Default target
|
||||||
.DEFAULT_GOAL := check
|
.DEFAULT_GOAL := check
|
||||||
@@ -74,4 +74,7 @@ hooks:
|
|||||||
@script/install-precommit
|
@script/install-precommit
|
||||||
|
|
||||||
css:
|
css:
|
||||||
tailwindcss -i static/css/input.css -o static/css/tailwind.css --minify
|
@script/css
|
||||||
|
|
||||||
|
css-check:
|
||||||
|
@script/css-check
|
||||||
|
|||||||
@@ -19,12 +19,14 @@ before deploying one.
|
|||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
- Go 1.26.1+ (the version in `go.mod`)
|
- Go 1.26.1+ (the version in `go.mod`)
|
||||||
- Docker (for `make lint` and so for `make check`, for the browser test in
|
- Docker (for `make lint` and `make css`, and so for `make check`, for the
|
||||||
`make test-browser`, for the CI gate, and for containerized deployment)
|
browser test in `make test-browser`, for the CI gate, and for
|
||||||
|
containerized deployment)
|
||||||
|
|
||||||
golangci-lint is not a prerequisite and must not be installed on the
|
golangci-lint is not a prerequisite and must not be installed on the
|
||||||
host: `script/bootstrap` does not install it, and `make lint` runs the
|
host: `script/bootstrap` does not install it, and `make lint` runs the
|
||||||
digest-pinned linter image via `Dockerfile.lint`.
|
digest-pinned linter image via `Dockerfile.lint`. The same holds for
|
||||||
|
tailwindcss (see [Stylesheet](#stylesheet)).
|
||||||
|
|
||||||
### Quick Start
|
### Quick Start
|
||||||
|
|
||||||
@@ -36,7 +38,7 @@ cd webhooker
|
|||||||
# Install the Go toolchain if missing, and the Go dependencies
|
# Install the Go toolchain if missing, and the Go dependencies
|
||||||
make bootstrap
|
make bootstrap
|
||||||
|
|
||||||
# Run all checks (test, lint, format check)
|
# Run all checks (test, lint, format check, stylesheet check)
|
||||||
make check
|
make check
|
||||||
|
|
||||||
# Run the server from the clone. DATA_DIR defaults to
|
# Run the server from the clone. DATA_DIR defaults to
|
||||||
@@ -59,7 +61,7 @@ make fmt-check # Fail if gofmt would change anything (writes nothing)
|
|||||||
make lint # Run golangci-lint in Docker (Dockerfile.lint)
|
make lint # Run golangci-lint in Docker (Dockerfile.lint)
|
||||||
make test # Run tests with race detection
|
make test # Run tests with race detection
|
||||||
make test-browser # Run the browser test in Docker (Dockerfile.browser)
|
make test-browser # Run the browser test in Docker (Dockerfile.browser)
|
||||||
make check # test + lint + fmt-check (CI gate)
|
make check # test + lint + fmt-check + css-check (CI gate)
|
||||||
make build # Build binary to bin/webhooker (version-stamped)
|
make build # Build binary to bin/webhooker (version-stamped)
|
||||||
make version # Print the version this checkout would stamp
|
make version # Print the version this checkout would stamp
|
||||||
make run # build, then run ./bin/webhooker
|
make run # build, then run ./bin/webhooker
|
||||||
@@ -67,7 +69,8 @@ make dev # go run ./cmd/webhooker
|
|||||||
make deps # go mod download + go mod tidy
|
make deps # go mod download + go mod tidy
|
||||||
make docker # Build Docker image
|
make docker # Build Docker image
|
||||||
make hooks # Install git pre-commit hook that runs script/precommit
|
make hooks # Install git pre-commit hook that runs script/precommit
|
||||||
make css # Regenerate static/css/tailwind.css (needs tailwindcss)
|
make css # Regenerate static/css/tailwind.css (tailwindcss in Docker)
|
||||||
|
make css-check # Fail if static/css/tailwind.css is stale (writes nothing)
|
||||||
make clean # Remove bin/
|
make clean # Remove bin/
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1292,11 +1295,11 @@ What that means for an operator:
|
|||||||
This repository adheres to the
|
This repository adheres to the
|
||||||
[Scripts to Rule Them All](https://github.com/github/scripts-to-rule-them-all)
|
[Scripts to Rule Them All](https://github.com/github/scripts-to-rule-them-all)
|
||||||
standard: normalized scripts in `script/` are the entrypoints for the
|
standard: normalized scripts in `script/` are the entrypoints for the
|
||||||
development workflow. Eleven of the Makefile's eighteen targets are thin
|
development workflow. Thirteen of the Makefile's nineteen targets are thin
|
||||||
shims that call them; `build`, `run`, `dev`, `deps`, `clean`, `css` and
|
shims that call them; `build`, `run`, `dev`, `deps`, `clean` and `version`
|
||||||
`version` are inline commands with no script behind them, though `build`,
|
are inline commands with no script behind them, though `build`, `run` and
|
||||||
`run` and `dev` first run `script/assets`, and `build` and `version` both
|
`dev` first run `script/assets`, and `build` and `version` both take their
|
||||||
take their value from `script/version`.
|
value from `script/version`.
|
||||||
|
|
||||||
`script/test`, `make build` and `make dev` each run `script/assets`
|
`script/test`, `make build` and `make dev` each run `script/assets`
|
||||||
first, which writes the ignored `static/js/alpine.min.js` (see
|
first, which writes the ignored `static/js/alpine.min.js` (see
|
||||||
@@ -1318,7 +1321,11 @@ We provide:
|
|||||||
- `script/lint` — run golangci-lint in Docker (see Linting below)
|
- `script/lint` — run golangci-lint in Docker (see Linting below)
|
||||||
- `script/fmt` — format all code (writes)
|
- `script/fmt` — format all code (writes)
|
||||||
- `script/fmt-check` — check formatting (read-only)
|
- `script/fmt-check` — check formatting (read-only)
|
||||||
- `script/check` — run test, lint, and fmt-check
|
- `script/css` — regenerate `static/css/tailwind.css` in Docker (writes;
|
||||||
|
see [Stylesheet](#stylesheet))
|
||||||
|
- `script/css-check` — fail if `static/css/tailwind.css` differs from what
|
||||||
|
`script/css` would generate (read-only)
|
||||||
|
- `script/check` — run test, lint, fmt-check, and css-check
|
||||||
- `script/version` — output the version to stamp into the binary (see
|
- `script/version` — output the version to stamp into the binary (see
|
||||||
[Version stamping](#version-stamping))
|
[Version stamping](#version-stamping))
|
||||||
- `script/docker` — build the Docker image tagged via
|
- `script/docker` — build the Docker image tagged via
|
||||||
@@ -1388,6 +1395,23 @@ the `dist.integrity` hash listed at
|
|||||||
`3p/` with it as `alpinejs-csp-<version>.tgz`, update its file name in
|
`3p/` with it as `alpinejs-csp-<version>.tgz`, update its file name in
|
||||||
`script/assets`, and run `make check` and `make test-browser`.
|
`script/assets`, and run `make check` and `make test-browser`.
|
||||||
|
|
||||||
|
## Stylesheet
|
||||||
|
|
||||||
|
`static/css/tailwind.css` is generated by Tailwind and committed. To change the
|
||||||
|
styles, edit the templates, `static/js/app.js`,
|
||||||
|
`internal/handlers/recent_events.go` or `static/css/input.css`, run `make css`,
|
||||||
|
and commit the regenerated file with the change. Tailwind takes classes only
|
||||||
|
from the files that `input.css` names in its `@source` lines; a class written in
|
||||||
|
any other file is not generated until that file is named there too. `make check`
|
||||||
|
and the image build fail when the committed file differs from what `make css`
|
||||||
|
generates. `static/css/style.css` is hand-written and is not generated.
|
||||||
|
|
||||||
|
`make css` runs the Tailwind standalone CLI in Docker, at the version and sha256
|
||||||
|
pinned in the Dockerfile's stylesheet stages; it is never installed on the host.
|
||||||
|
To move to a new version, change the version in both download URLs and both
|
||||||
|
sha256 sums, taken from the release's `sha256sums.txt`, then run `make css` and
|
||||||
|
commit the result.
|
||||||
|
|
||||||
## Rationale
|
## Rationale
|
||||||
|
|
||||||
Webhook integrations between services are inherently fragile. The
|
Webhook integrations between services are inherently fragile. The
|
||||||
@@ -3140,10 +3164,10 @@ webhooker/
|
|||||||
│ └── js/alpine.min.js # Alpine.js CSP build, extracted from 3p/ by make assets, not committed
|
│ └── js/alpine.min.js # Alpine.js CSP build, extracted from 3p/ by make assets, not committed
|
||||||
├── templates/ # Go HTML templates (base, login, sources, etc.)
|
├── templates/ # Go HTML templates (base, login, sources, etc.)
|
||||||
├── script/ # Scripts to Rule Them All entrypoints
|
├── script/ # Scripts to Rule Them All entrypoints
|
||||||
├── Dockerfile # Three stages: lint, test+build, Alpine runtime
|
├── Dockerfile # Stages: lint, stylesheet, test+build, Alpine runtime
|
||||||
├── Dockerfile.lint # Lint-only image built by script/lint
|
├── Dockerfile.lint # Lint-only image built by script/lint
|
||||||
├── Dockerfile.browser # Browser test image built by script/test-browser
|
├── Dockerfile.browser # Browser test image built by script/test-browser
|
||||||
├── Makefile # 11 of 18 targets shim script/; 7 are inline
|
├── Makefile # 13 of 19 targets shim script/; 6 are inline
|
||||||
├── go.mod / go.sum
|
├── go.mod / go.sum
|
||||||
└── .golangci.yml # Linter configuration
|
└── .golangci.yml # Linter configuration
|
||||||
```
|
```
|
||||||
@@ -3457,18 +3481,26 @@ Three properties are load-bearing:
|
|||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
|
|
||||||
The Dockerfile uses a three-stage build. Each stage is pinned by
|
The Dockerfile uses a multi-stage build. Each stage is pinned by
|
||||||
digest, and the two check stages are separate images so the linter's
|
digest, and the lint and builder stages are separate images so the
|
||||||
version is fixed independently of the compiler's:
|
linter's version is fixed independently of the compiler's:
|
||||||
|
|
||||||
1. **Lint stage** (`golangci/golangci-lint:v2.12.2`, Debian-based) —
|
1. **Lint stage** (`golangci/golangci-lint:v2.12.2`, Debian-based) —
|
||||||
installs `make`, downloads dependencies, copies the source, and runs
|
installs `make`, downloads dependencies, copies the source, and runs
|
||||||
`make fmt-check`, then `script/assets` to extract Alpine.js from
|
`make fmt-check`, then `script/assets` to extract Alpine.js from
|
||||||
`3p/`, then `golangci-lint config verify` and `golangci-lint run`,
|
`3p/`, then `golangci-lint config verify` and `golangci-lint run`,
|
||||||
both with `--network=none`.
|
both with `--network=none`.
|
||||||
2. **Builder stage** (`golang:1.26.1-bookworm`) — depends on the lint
|
2. **Stylesheet stages** (`debian:bookworm-slim`, with the Tailwind
|
||||||
stage passing (it copies a file from it), runs `make test` and
|
standalone CLI pinned by version and sha256, one binary per
|
||||||
`make build` (both extract Alpine.js from `3p/` first), and finally
|
architecture) — generate `static/css/tailwind.css` from
|
||||||
|
`static/css/input.css` and the files its `@source` lines name.
|
||||||
|
`css-check` fails when the committed file differs from the generated
|
||||||
|
one, and `make css` writes the generated file out from `css-output`
|
||||||
|
(see [Stylesheet](#stylesheet)).
|
||||||
|
3. **Builder stage** (`golang:1.26.1-bookworm`) — depends on the lint
|
||||||
|
and `css-check` stages passing (it copies a file from each), runs
|
||||||
|
`make test` and `make build` (both extract Alpine.js from `3p/`
|
||||||
|
first), and finally
|
||||||
rebuilds the binary with `CGO_ENABLED=1` and static linking so it
|
rebuilds the binary with `CGO_ENABLED=1` and static linking so it
|
||||||
runs on musl. Both builds go through `make build`, the relink adding
|
runs on musl. Both builds go through `make build`, the relink adding
|
||||||
its `-extldflags` via `GO_LDFLAGS`, so neither can drop the `-X` that
|
its `-extldflags` via `GO_LDFLAGS`, so neither can drop the `-X` that
|
||||||
@@ -3476,7 +3508,7 @@ version is fixed independently of the compiler's:
|
|||||||
given, otherwise derived from the `.git` in the context, and the
|
given, otherwise derived from the `.git` in the context, and the
|
||||||
stage fails if a context with `.git` would stamp `unknown` (see
|
stage fails if a context with `.git` would stamp `unknown` (see
|
||||||
[Version stamping](#version-stamping)).
|
[Version stamping](#version-stamping)).
|
||||||
3. **Runtime stage** (`alpine:3.21`) — copies the static binary and
|
4. **Runtime stage** (`alpine:3.21`) — copies the static binary and
|
||||||
`deploy/docker-entrypoint.sh`, creates the `/var/lib/webhooker`
|
`deploy/docker-entrypoint.sh`, creates the `/var/lib/webhooker`
|
||||||
directory for all SQLite databases, exposes port 8080, and includes
|
directory for all SQLite databases, exposes port 8080, and includes
|
||||||
a health check against `/.well-known/healthcheck`. It sets no
|
a health check against `/.well-known/healthcheck`. It sets no
|
||||||
@@ -3488,18 +3520,18 @@ The lint stage invokes `golangci-lint` directly rather than `make lint`:
|
|||||||
it is already the pinned linter image, and `make lint` builds
|
it is already the pinned linter image, and `make lint` builds
|
||||||
`Dockerfile.lint`, which would need a docker daemon inside this build.
|
`Dockerfile.lint`, which would need a docker daemon inside this build.
|
||||||
|
|
||||||
Both check stages use Debian rather than Alpine because
|
The lint and builder stages use Debian rather than Alpine because
|
||||||
`gorm.io/driver/sqlite` pulls in `mattn/go-sqlite3`, which needs CGO
|
`gorm.io/driver/sqlite` pulls in `mattn/go-sqlite3`, which needs CGO
|
||||||
and does not compile against musl. Only the final binary is statically
|
and does not compile against musl. Only the final binary is statically
|
||||||
linked, which is what lets it run on the Alpine runtime image.
|
linked, which is what lets it run on the Alpine runtime image.
|
||||||
|
|
||||||
`script/cibuild` — `docker build .` — is the CI gate: the checks run
|
`script/cibuild` — `docker build .` — is the CI gate: the checks run
|
||||||
inside the image, so a build that succeeds is a repo that is formatted,
|
inside the image, so a build that succeeds is a repo that is formatted,
|
||||||
linted, tested and compiled. `script/lint` also uses Docker
|
linted, tested and compiled, with a current stylesheet. `script/lint`
|
||||||
(`Dockerfile.lint`, see Linting above), so `make lint` and `make check`
|
also uses Docker (`Dockerfile.lint`, see Linting above), so `make lint`
|
||||||
run the same pinned linter version the gate does; of the steps
|
and `make check` run the same pinned linter version the gate does; of
|
||||||
`make check` runs, only `script/test` and `script/fmt-check` run on the
|
the steps `make check` runs, only `script/test` and `script/fmt-check`
|
||||||
host.
|
run on the host.
|
||||||
|
|
||||||
#### CI gate honesty
|
#### CI gate honesty
|
||||||
|
|
||||||
@@ -3509,9 +3541,10 @@ check meaningless. The `check` workflow therefore writes
|
|||||||
`.ci-fingerprint` into the build context before building. Its value is
|
`.ci-fingerprint` into the build context before building. Its value is
|
||||||
the hash of the commit being checked, so every commit, docs-only ones
|
the hash of the commit being checked, so every commit, docs-only ones
|
||||||
and a squash merge whose tree matches an already-built branch included,
|
and a squash merge whose tree matches an already-built branch included,
|
||||||
gets a new fingerprint, invalidates the `COPY . .` layer of both check
|
gets a new fingerprint, invalidates the `COPY . .` layer of every check
|
||||||
stages, and really runs `make fmt-check`, `golangci-lint`, `make test`,
|
stage, and really runs `make fmt-check`, `golangci-lint`, the stylesheet
|
||||||
and `make build`. A run that reports success ran them.
|
check, `make test`, and `make build`. A run that reports success ran
|
||||||
|
them.
|
||||||
|
|
||||||
The module download layer sits above `COPY . .` and stays cached.
|
The module download layer sits above `COPY . .` and stays cached.
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -60,9 +60,9 @@ main() {
|
|||||||
if missing go; then pkg_install go golang go go; fi
|
if missing go; then pkg_install go golang go go; fi
|
||||||
|
|
||||||
# Not installed here: docker is platform-specific and out of scope for a
|
# Not installed here: docker is platform-specific and out of scope for a
|
||||||
# package-manager bootstrap, but script/lint needs it.
|
# package-manager bootstrap, but script/lint and script/css need it.
|
||||||
if missing docker; then
|
if missing docker; then
|
||||||
echo "bootstrap: docker not found; script/lint requires it" >&2
|
echo "bootstrap: docker not found; script/lint and script/css require it" >&2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
go mod download
|
go mod download
|
||||||
|
|||||||
+3
-2
@@ -1,8 +1,8 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# script/check: run all checks (test, lint, fmt-check). Our own
|
# script/check: run all checks (test, lint, fmt-check, css-check). Our own
|
||||||
# extension to scripts-to-rule-them-all.
|
# extension to scripts-to-rule-them-all.
|
||||||
# Writes only the ignored static/js/alpine.min.js, through script/test.
|
# Writes only the ignored static/js/alpine.min.js, through script/test.
|
||||||
# Generic: usually needs no adaptation.
|
# Generic, apart from css-check.
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||||
@@ -11,6 +11,7 @@ main() {
|
|||||||
"$SCRIPT_DIR/test"
|
"$SCRIPT_DIR/test"
|
||||||
"$SCRIPT_DIR/lint"
|
"$SCRIPT_DIR/lint"
|
||||||
"$SCRIPT_DIR/fmt-check"
|
"$SCRIPT_DIR/fmt-check"
|
||||||
|
"$SCRIPT_DIR/css-check"
|
||||||
}
|
}
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
||||||
|
|||||||
Executable
+15
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# script/css: regenerate static/css/tailwind.css (writes). tailwindcss is
|
||||||
|
# never installed locally: it runs in docker, at the version and sha256
|
||||||
|
# pinned in the Dockerfile's stylesheet stages, which also say what the
|
||||||
|
# stylesheet is generated from.
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||||
|
|
||||||
|
main() {
|
||||||
|
cd "$ROOT"
|
||||||
|
docker build --target css-output --output type=local,dest=static/css .
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
Executable
+14
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# script/css-check: fail when static/css/tailwind.css differs from what
|
||||||
|
# script/css would generate (read-only). The comparison is the Dockerfile's
|
||||||
|
# css-check stage, which the image build runs too.
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||||
|
|
||||||
|
main() {
|
||||||
|
cd "$ROOT"
|
||||||
|
docker build --target css-check --output type=cacheonly .
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
@import "tailwindcss";
|
/* Classes are taken only from the files named below. A class written in
|
||||||
|
any other file is not generated: name that file here too. */
|
||||||
/* Source the templates */
|
@import "tailwindcss" source(none);
|
||||||
@source "../../templates/**/*.html";
|
@source "../../templates/**/*.html";
|
||||||
|
@source "../js/app.js";
|
||||||
|
/* targetStatus picks a target's status colour class */
|
||||||
|
@source "../../internal/handlers/recent_events.go";
|
||||||
|
|
||||||
/* Material Design inspired theme customization */
|
/* Material Design inspired theme customization */
|
||||||
@theme {
|
@theme {
|
||||||
@@ -53,10 +56,6 @@
|
|||||||
@apply inline-flex items-center justify-center px-4 py-2 rounded-md font-medium text-sm transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed bg-error-500 text-white hover:bg-error-700 active:bg-red-800 focus:ring-red-500 shadow-elevation-1 hover:shadow-elevation-2;
|
@apply inline-flex items-center justify-center px-4 py-2 rounded-md font-medium text-sm transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed bg-error-500 text-white hover:bg-error-700 active:bg-red-800 focus:ring-red-500 shadow-elevation-1 hover:shadow-elevation-2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-text {
|
|
||||||
@apply inline-flex items-center justify-center px-4 py-2 rounded-md font-medium text-sm transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed text-primary-600 hover:bg-primary-50 active:bg-primary-100;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cards */
|
/* Cards */
|
||||||
.card {
|
.card {
|
||||||
@apply bg-white rounded-lg shadow-elevation-1 overflow-hidden;
|
@apply bg-white rounded-lg shadow-elevation-1 overflow-hidden;
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user