1
0
Fork 0
mirror of https://git.sr.ht/~seirdy/seirdy.one synced 2024-11-27 14:12:09 +00:00

CI: test with lighthouse, webhint in staging

This commit is contained in:
Rohan Kumar 2020-12-23 17:02:43 -08:00
parent 34ba9e30cf
commit 51a6d4edde
No known key found for this signature in database
GPG key ID: 1E892DB2A5F84479
9 changed files with 175 additions and 61 deletions

View file

@ -2,10 +2,11 @@
image: alpine/edge image: alpine/edge
packages: packages:
- rsync - rsync
- hugo
- zopfli - zopfli
- git # for Hugo's gitInfo - git # for Hugo's gitInfo
- make - make
- npm
- chromium
sources: sources:
- https://git.sr.ht/~seirdy/seirdy.one - https://git.sr.ht/~seirdy/seirdy.one
secrets: secrets:
@ -15,7 +16,13 @@ triggers:
condition: always condition: always
to: seirdy@seirdy.one to: seirdy@seirdy.one
tasks: tasks:
- deps: |
echo "StrictHostKeyChecking=no" >> ~/.ssh/config
rsync deploy@seirdy.one:/home/deploy/binaries.tar.gz .
tar x -ozC /bin -f binaries.tar.gz
npm i -g npm pnpm
pnpm i -g @lhci/cli hint @hint/configuration-web-recommended @hint/hint-doctype @hint/hint-https-only @hint/hint-performance-budget @hint/formatter-codeframe
- build_deploy: | - build_deploy: |
cd seirdy.one cd seirdy.one
echo "StrictHostKeyChecking=no" >> ~/.ssh/config make DOMAIN=staging.seirdy.one test-staging
make build deploy make clean deploy

4
.gitignore vendored
View file

@ -1,6 +1,8 @@
public/ public/
public_*/ public_*/
hint-report/ hint-report/
.hintrc-local .hintrc-*
*.report.html *.report.html
*.report.json *.report.json
.lighthouseci
lighthouse-reports

27
.hintrc
View file

@ -1,22 +1,21 @@
{ {
"extends": [
"web-recommended"
],
"connector": { "connector": {
"name": "puppeteer", "name": "puppeteer",
"options": { "options": {
"headless": true, "browser": "Chromium",
"browser": "Chromium" "headless": true
} }
}, },
"extends": [
"web-recommended"
],
"formatters": [
"codeframe"
],
"hints": { "hints": {
"apple-touch-icons": "off",
"axe/other": "error", "axe/other": "error",
"https-only": "error",
"doctype": "error",
"performance-budget": "error",
"compat-api/css": "error", "compat-api/css": "error",
"manifest-is-valid": "error",
"manifest-file-extension": "error",
"compat-api/html": [ "compat-api/html": [
"error", "error",
{ {
@ -27,6 +26,7 @@
] ]
} }
], ],
"doctype": "error",
"http-compression": [ "http-compression": [
"warning", "warning",
{ {
@ -37,6 +37,11 @@
"brotli": false "brotli": false
} }
} }
] ],
"https-only": "error",
"manifest-file-extension": "error",
"manifest-is-valid": "error",
"performance-budget": "error",
"ssllabs": "off"
} }
} }

59
.lighthouserc.yml Normal file
View file

@ -0,0 +1,59 @@
---
ci:
assert:
preset: lighthouse:recommended
assertions:
errors-in-console: "off" # false positive for CSP violation
installable-manifest: "off" # not a PWA
offline-start-url: "off" # not a PWA
performance-budget: "error"
render-blocking-resources:
- warn
# the CSS file.
# My site doesn't use JS so it doesn't use the recommended async hack
- maxLength: 1
robots-txt: "off" # Lighthouse is incompatible with a hardened CSP
service-worker: "off" # not a PWA
splash-screen: "off" # not a PWA
themed-omnibox: "off" # antifeature, not a PWA
works-offline: "off" # not a PWA. Use caching.
is-crawlable: "off" # staging server won't be indexed
timing-budget: "off" # buggy; manually use the below assertions instead
speed-index:
- warn
- maxNumericValue: 3000
largest-contentful-paint:
- warn
- maxNumericValue: 3000
first-contentful-paint:
- warn
- maxNumericValue: 3000
first-meaningful-paint:
- warn
- maxNumericValue: 3000
total-blocking-time:
- warn
- maxNumericValue: 0
cumulative-layout-shift:
- warn
- maxNumericValue: 0
collect:
method: node
settings:
budgetPath: budget.json
chromeFlags: "--disable-gpu --no-sandbox --disable-extensions --no-first-run --headless"
skipAudits:
- robots-txt
- canonical
throttling:
cpuSlowdownMultiplier: 2
throttlingMethod: devtools
url:
- https://staging.seirdy.one/
- https://staging.seirdy.one/about.html
- https://staging.seirdy.one/2020/11/23/website-best-practices.html
numberOfRuns: 5
upload:
outputDir: lighthouse-reports
reportFilenamePattern: lighthouse-report-%%DATE%%.%%EXTENSION%%
target: filesystem

View file

@ -1,39 +1,65 @@
CSS_DIR = themes/etch-custom/assets/css CSS_DIR = themes/etch-custom/assets/css
DEVSERVER_URL="http://localhost:1313/"
USER = deploy@seirdy.one DOMAIN = seirdy.one
WWW_ROOT = /var/www/seirdy.one HUGO_BASEURL = "https://$(DOMAIN)/"
GEMINI_ROOT = /srv/gemini/seirdy.one USER = deploy@$(DOMAIN)
WWW_ROOT = /var/www/$(DOMAIN)
GEMINI_ROOT = /srv/gemini/$(DOMAIN)
WWW_RSYNC_DEST = $(USER):$(WWW_ROOT) WWW_RSYNC_DEST = $(USER):$(WWW_ROOT)
GEMINI_RSYNC_DEST = $(USER):$(GEMINI_ROOT) GEMINI_RSYNC_DEST = $(USER):$(GEMINI_ROOT)
OUTPUT_DIR = public OUTPUT_DIR = public
RSYNCFLAGS += -rlvz --zc=zstd RSYNCFLAGS += -rlvz --zc=zstd
hugo: .PHONY: hugo
hugo --gc --enableGitInfo hugo: clean
hugo --gc -b $(HUGO_BASEURL)
# .hintrc-local for linting local files # .hintrc-local for linting local files
# same as regular .hintrc but with a different connector. # same as regular .hintrc but with a different connector.
.hintrc-local: .hintrc .hintrc-local: .hintrc
jq --tab '.connector .name = "local" | del(.connector .options)' <.hintrc >.hintrc-local jq --tab '.connector .name = "local" | del(.connector .options)' <.hintrc >.hintrc-local
.hintrc-devserver: .hintrc
jq --tab '.extends = ["development"] | .hints["http-compression","https-only","ssllabs","sri"] = "off"' <.hintrc >.hintrc-devserver
.PHONY: clean
clean: clean:
rm -rf $(OUTPUT_DIR) .hintrc-local rm -rf $(OUTPUT_DIR) .lighthouseci lighthouse-reports
.PHONY: lint-css
lint-css: lint-css:
stylelint $(CSS_DIR)/main.css $(CSS_DIR)/dark.css stylelint --di --rd --rdd $(CSS_DIR)/main.css $(CSS_DIR)/dark.css
csslint $(CSS_DIR) csslint --quiet $(CSS_DIR)
lint: lint-css hugo .hintrc-local .PHONY: hint
hint: hugo .hintrc-local
hint --config .hintrc-local -f codeframe $(OUTPUT_DIR) hint --config .hintrc-local -f codeframe $(OUTPUT_DIR)
rm .hintrc-local
.PHONY: lint-local
lint-local: lint-css hint
# dev server
.PHONY: serve
serve:
hugo serve --disableLiveReload
.PHONY: hint-devserver
hint-devserver: .hintrc-devserver
hint --config .hintrc-devserver -f codeframe $(DEVSERVER_URL)
rm .hintrc-devserver
.PHONY: check-links
check-links: hugo check-links: hugo
lychee --verbose $(find public -type f -name '*.html' -o -name '*.gmi' -o -name '*.txt') content/posts/*.md content/posts/*.gmi lychee --verbose $(find public -type f -name '*.html' -o -name '*.gmi' -o -name '*.txt') content/posts/*.md content/posts/*.gmi
test: lint check-links .PHONY: test
test: lint-css hint-devserver check-links
.PHONY: build
build: hugo build: hugo
# gzip_static + max zopfli compression # gzip_static + max zopfli compression
ifndef NO_GZIP_STATIC ifndef NO_GZIP_STATIC
@ -43,11 +69,23 @@ ifndef NO_GZIP_STATIC
endif endif
deploy: build .PHONY: deploy-html
deploy-html: build
rsync $(RSYNCFLAGS) --exclude 'gemini' --exclude '*.gmi' --exclude-from .rsyncignore $(OUTPUT_DIR)/ $(WWW_RSYNC_DEST) --delete rsync $(RSYNCFLAGS) --exclude 'gemini' --exclude '*.gmi' --exclude-from .rsyncignore $(OUTPUT_DIR)/ $(WWW_RSYNC_DEST) --delete
rsync $(RSYNCFLAGS) --exclude '*.html' --exclude '*.xml' --exclude-from .rsyncignore $(OUTPUT_DIR)/gemini/ $(OUTPUT_DIR)/about $(OUTPUT_DIR)/posts $(OUTPUT_DIR)/publickey.txt $(GEMINI_RSYNC_DEST)/ --delete
.PHONY: deploy-gemini
deploy-gemini: hugo
rsync $(RSYNCFLAGS) --exclude '*.html' --exclude '*.xml' --exclude '*.gz' --exclude-from .rsyncignore $(OUTPUT_DIR)/gemini/ $(OUTPUT_DIR)/about $(OUTPUT_DIR)/posts $(OUTPUT_DIR)/publickey.txt $(GEMINI_RSYNC_DEST)/ --delete
rsync $(RSYNCFLAGS) $(OUTPUT_DIR)/posts/gemini.xml $(GEMINI_RSYNC_DEST)/feed.xml rsync $(RSYNCFLAGS) $(OUTPUT_DIR)/posts/gemini.xml $(GEMINI_RSYNC_DEST)/feed.xml
all: clean test deploy .PHONY: deploy
deploy: deploy-html deploy-gemini
.PHONY: clean lint-css lint check-links test hugo build deploy all ## stuff for the staging server
.PHONY: test-staging
test-staging: deploy-html
yq e '.ci .collect .url | .[]' .lighthouserc.yml | xargs hint -f codeframe
lhci autorun
.PHONY: all
all: test deploy

View file

@ -3,7 +3,7 @@
"options": { "options": {
"firstPartyHostnames": [ "firstPartyHostnames": [
"seirdy.one", "seirdy.one",
"localhost" "staging.seirdy.one"
] ]
}, },
"timings": [ "timings": [
@ -14,6 +14,14 @@
{ {
"metric": "cumulative-layout-shift", "metric": "cumulative-layout-shift",
"budget": 0 "budget": 0
},
{
"metric": "interactive",
"budget": 3200
},
{
"metric": "largest-contentful-paint",
"budget": 3200
} }
], ],
"resourceSizes": [ "resourceSizes": [
@ -48,32 +56,5 @@
"budget": 0 "budget": 0
} }
] ]
},
{
"path": "/index.html",
"timings": [
{
"metric": "largest-contentful-paint",
"budget": 1000
}
],
"resourceSizes": [
{
"resourceType": "total",
"budget": 10
},
{
"resourceType": "document",
"budget": 8
},
{
"resourceType": "image",
"budget": 5
},
{
"resourceType": "stylesheet",
"budget": 2
}
]
} }
] ]

View file

@ -4,7 +4,8 @@ title = "Seirdy's Home"
theme = "etch-custom" theme = "etch-custom"
enableInlineShortcodes = true enableInlineShortcodes = true
# disablePathToLower = true enableGitInfo = true
disableHugoGeneratorInject = true # first item in <head> should be charset=utf-8
uglyurls = true uglyurls = true
pygmentsCodeFences = true pygmentsCodeFences = true
pygmentsUseClasses = true pygmentsUseClasses = true
@ -76,3 +77,23 @@ path = "gemini/"
[outputs] [outputs]
section = ["HTML", "RSS", "GEMRSS"] section = ["HTML", "RSS", "GEMRSS"]
[server]
[[server.headers]]
for = "/**.{css,png,webp,webm}"
[server.headers.values]
X-Content-Type-Options = "nosniff"
Strict-Transport-Security = "max-age=31536000; includeSubDomains; preload"
Cache-Control = "max-age=31557600, immutable"
[[server.headers]]
for = "/**"
[server.headers.values]
X-Content-Type-Options = "nosniff"
Strict-Transport-Security = "max-age=31536000; includeSubDomains; preload"
Referrer-Policy = "no-referrer"
X-XSS-Protection = "1; mode=block"
X-FROG-UNSAFE = "1"
X-UA-Compatible = "IE=edge"
Content-Security-Policy = "default-src 'none'; img-src 'self'; style-src 'self'; script-src 'none'; frame-ancestors 'none'; base-uri 'none'; form-action 'none'; manifest-src 'self'; upgrade-insecure-requests;"
Permissions-Policy = "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()"
Cache-Control = "max-age=120, no-transform"

View file

@ -2,5 +2,6 @@ insecure = true
method = "get" method = "get"
exclude = [ exclude = [
"^gemini://.*", "^gemini://.*",
"mailto:.*",
"git@git.*", "git@git.*",
] ]

View file

@ -17,7 +17,7 @@
{{ $webmanifest := resources.Get "/manifest.webmanifest" | resources.ExecuteAsTemplate "manifest.webmanifest" . | resources.Fingerprint "md5" -}} {{ $webmanifest := resources.Get "/manifest.webmanifest" | resources.ExecuteAsTemplate "manifest.webmanifest" . | resources.Fingerprint "md5" -}}
{{ printf `<link rel="manifest" href="%s">` $webmanifest.RelPermalink | safeHTML }} {{ printf `<link rel="manifest" href="%s">` $webmanifest.RelPermalink | safeHTML }}
<link rel="alternate" type="application/rss+xml" href="{{ .Site.BaseURL }}posts/index.xml" title="{{ $.Site.Title }}"> <link rel="alternate" type="application/rss+xml" href="{{ .Site.BaseURL }}posts/index.xml" title="{{ $.Site.Title }}">
{{ if eq .Site.BaseURL "https://envs.net/~seirdy/" -}} {{ if ne .Site.BaseURL "https://seirdy.one/" -}}
<meta name="robots" content="noindex"> <meta name="robots" content="noindex">
{{ else -}} {{ else -}}
<link rel="canonical" href="https://seirdy.one{{ .RelPermalink }}"> <link rel="canonical" href="https://seirdy.one{{ .RelPermalink }}">