Commit Alpine.js to the repo instead of unpacking it at build time (closes #163) #564

Merged
clawbot merged 1 commits from alpine-committed into next 2026-10-26 05:16:07 +01:00
13 changed files with 28 additions and 52 deletions
+1 -3
View File
@@ -72,10 +72,8 @@
**/*.sublime-*
# This repository's own host-built artifacts: the binary `make build`
# writes, and the Alpine.js file `make assets` extracts from 3p/ (the
# build extracts its own).
# writes.
/bin
/static/js/alpine.min.js
# SQLite databases, which hold the session key and webhook payloads, at
# any depth.
-4
View File
@@ -77,7 +77,3 @@ data/
# Temporary files
tmp/
temp/
# Alpine.js, extracted by `make assets` from its tarball in 3p/, which is
# what is committed.
/static/js/alpine.min.js
+1
View File
@@ -1,2 +1,3 @@
node_modules/
yarn.lock
static/js/alpine.min.js
Binary file not shown.
+2 -11
View File
@@ -92,10 +92,6 @@ COPY . .
# fmt-check` is the markdown-check stage above.
RUN if [ -n "$(gofmt -s -l .)" ]; then echo "gofmt needed on:"; gofmt -s -l .; exit 1; fi
# static/static.go embeds the Alpine.js file this extracts from 3p/; without
# it the static package does not compile and cannot be linted.
RUN script/assets
# The golangci-lint steps run with --network=none. `golangci-lint config
# verify` is documented as fetching its JSON schema over HTTPS; this pinned
# image resolves the schema without any network, and --network=none enforces
@@ -130,9 +126,6 @@ RUN go mod download
COPY . .
# static/static.go embeds the Alpine.js file this extracts from 3p/.
RUN script/assets
# -timeout applies to each package on its own, so 90s has only to clear the
# slowest one. -p 4 -parallel 8 keep the run under 2 GB of memory: at most
# four test binaries build or run at once, each with at most eight parallel
@@ -211,10 +204,8 @@ RUN version="$(make version VERSION="$VERSION")"; \
esac; \
fi
# Builds through the Makefile's build target, which runs script/assets
# (Alpine.js, extracted from its tarball in 3p/) first. The target builds
# with cgo off, so the binary is statically linked and runs on the Alpine
# runtime image below as it is.
# The Makefile's build target builds with cgo off, so the binary is
# statically linked and runs on the Alpine runtime image below.
RUN make build VERSION="$VERSION"
# Runtime stage
+1 -1
View File
@@ -17,7 +17,7 @@ COPY . .
# The test binary embeds the templates and static files, so the browser
# stage needs nothing else. It is built with cgo off and -p 4 keeps the
# compile's memory down, both as in the test phase of Dockerfile.
RUN make assets && CGO_ENABLED=0 go test -c -p 4 -tags browser -o /browser.test ./internal/server
RUN CGO_ENABLED=0 go test -c -p 4 -tags browser -o /browser.test ./internal/server
# chromedp/headless-shell:151.0.7922.109 (Debian trixie), 2026-08-11. The
# browser is on PATH as headless-shell, where the test's browser library
+3 -6
View File
@@ -1,4 +1,4 @@
.PHONY: bootstrap setup assets test test-browser lint fmt fmt-check check build run dev deps docker clean hooks css css-check version
.PHONY: bootstrap setup test test-browser lint fmt fmt-check check build run dev deps docker clean hooks css css-check version
# Default target
.DEFAULT_GOAL := check
@@ -22,9 +22,6 @@ bootstrap:
setup:
@script/setup
assets:
@script/assets
test:
@script/test
@@ -47,13 +44,13 @@ check:
# REPO_POLICIES.md does: the binary carries no build paths, symbol table or
# debug information, and on Linux, the image's included, it is statically
# linked.
build: assets
build:
CGO_ENABLED=0 go build -trimpath -ldflags '-s -w -X main.version=$(VERSION)' -o bin/webhooker ./cmd/webhooker
run: build
./bin/webhooker
dev: assets
dev:
go run ./cmd/webhooker
deps:
+3 -3
View File
@@ -689,8 +689,9 @@ checkout, or `VERSION` when that is set. It is shown at
The pages use one third-party script, Alpine.js. They load `@alpinejs/csp`, the
version of it that works when the Content-Security-Policy forbids running text
as code. The npm registry is where JavaScript packages are published. The
package file in `3p/` is byte for byte the one the npm registry publishes.
as code. The npm registry is where JavaScript packages are published.
`static/js/alpine.min.js` is committed byte for byte as the npm registry
publishes it.
A headless browser is a browser without a window. A browser test in
`internal/server` loads the pages in one under the real Content-Security-Policy.
@@ -710,7 +711,6 @@ application are under [Entrypoint URLs](#entrypoint-urls).
- `script/bootstrap` installs git, make, Go and the Go modules.
- `script/setup` runs `script/bootstrap`, then `script/install-precommit`.
- `script/projectname` prints `webhooker`.
- `script/assets` extracts Alpine.js from `3p/` to `static/js/alpine.min.js`.
- `script/test` runs the tests in Docker.
- `script/test-browser` runs the browser test in Docker.
- `script/lint` runs `gofmt`, `golangci-lint` and ESLint in Docker.
+1 -1
View File
@@ -5,7 +5,7 @@
// REPO_POLICIES.md states that a linter can check: const for everything,
// let only for a variable that is reassigned, never var.
export default [
// Alpine.js, extracted from 3p/ by make assets; not ours to lint.
// Alpine.js, committed as published; not ours to lint.
{ ignores: ["static/js/alpine.min.js"] },
{
// The pages load static/js/app.js as a classic script, not a module.
-3
View File
@@ -13,9 +13,6 @@ import (
// TestBaseTemplateScriptsAreServed walks every /s/ script the base
// template loads on each page and fetches it through the real router.
// Alpine.js is extracted from its tarball in 3p/ at build time, so the
// file is not in the tree: this is the check that the page still gets
// the JavaScript it asks for.
func TestBaseTemplateScriptsAreServed(t *testing.T) {
t.Parallel()
-17
View File
@@ -1,17 +0,0 @@
#!/bin/sh
# script/assets: extract Alpine.js from its npm package tarball, committed
# in 3p/, to static/js/alpine.min.js, where go:embed reads it. The package
# is @alpinejs/csp, Alpine's build for pages whose Content-Security-Policy
# forbids eval. The extracted file is not committed. make build, make dev
# and the Dockerfile's lint, test and build stages run this first.
set -eu
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
main() {
cd "$ROOT"
tar -xzOf 3p/alpinejs-csp-3.14.9.tgz package/dist/cdn.min.js \
>static/js/alpine.min.js
}
main "$@"
+11
View File
File diff suppressed because one or more lines are too long
+5 -3
View File
@@ -6,9 +6,11 @@ import (
)
// Static holds the CSS and JavaScript files the web UI's pages load. They
// are named one by one so that a missing js/alpine.min.js, which make
// assets extracts and git does not track, fails the build instead of
// leaving the pages without Alpine.js.
// are named one by one, so a missing file fails the build instead of
// leaving the pages without it.
//
// js/alpine.min.js is Alpine.js, committed unchanged. It is
// package/dist/cdn.min.js from the npm package @alpinejs/csp 3.14.9.
//
//go:embed css/tailwind.css css/style.css js/app.js js/alpine.min.js
var Static embed.FS