mirror of
https://git.sr.ht/~seirdy/seirdy.one
synced 2024-11-23 21:02:09 +00:00
CI: test with lighthouse, webhint in staging
This commit is contained in:
parent
34ba9e30cf
commit
51a6d4edde
9 changed files with 175 additions and 61 deletions
15
.build.yml
15
.build.yml
|
@ -2,10 +2,11 @@
|
|||
image: alpine/edge
|
||||
packages:
|
||||
- rsync
|
||||
- hugo
|
||||
- zopfli
|
||||
- git # for Hugo's gitInfo
|
||||
- git # for Hugo's gitInfo
|
||||
- make
|
||||
- npm
|
||||
- chromium
|
||||
sources:
|
||||
- https://git.sr.ht/~seirdy/seirdy.one
|
||||
secrets:
|
||||
|
@ -15,7 +16,13 @@ triggers:
|
|||
condition: always
|
||||
to: seirdy@seirdy.one
|
||||
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: |
|
||||
cd seirdy.one
|
||||
echo "StrictHostKeyChecking=no" >> ~/.ssh/config
|
||||
make build deploy
|
||||
make DOMAIN=staging.seirdy.one test-staging
|
||||
make clean deploy
|
||||
|
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,6 +1,8 @@
|
|||
public/
|
||||
public_*/
|
||||
hint-report/
|
||||
.hintrc-local
|
||||
.hintrc-*
|
||||
*.report.html
|
||||
*.report.json
|
||||
.lighthouseci
|
||||
lighthouse-reports
|
||||
|
|
27
.hintrc
27
.hintrc
|
@ -1,22 +1,21 @@
|
|||
{
|
||||
"extends": [
|
||||
"web-recommended"
|
||||
],
|
||||
"connector": {
|
||||
"name": "puppeteer",
|
||||
"options": {
|
||||
"headless": true,
|
||||
"browser": "Chromium"
|
||||
"browser": "Chromium",
|
||||
"headless": true
|
||||
}
|
||||
},
|
||||
"extends": [
|
||||
"web-recommended"
|
||||
],
|
||||
"formatters": [
|
||||
"codeframe"
|
||||
],
|
||||
"hints": {
|
||||
"apple-touch-icons": "off",
|
||||
"axe/other": "error",
|
||||
"https-only": "error",
|
||||
"doctype": "error",
|
||||
"performance-budget": "error",
|
||||
"compat-api/css": "error",
|
||||
"manifest-is-valid": "error",
|
||||
"manifest-file-extension": "error",
|
||||
"compat-api/html": [
|
||||
"error",
|
||||
{
|
||||
|
@ -27,6 +26,7 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"doctype": "error",
|
||||
"http-compression": [
|
||||
"warning",
|
||||
{
|
||||
|
@ -37,6 +37,11 @@
|
|||
"brotli": false
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
"https-only": "error",
|
||||
"manifest-file-extension": "error",
|
||||
"manifest-is-valid": "error",
|
||||
"performance-budget": "error",
|
||||
"ssllabs": "off"
|
||||
}
|
||||
}
|
||||
|
|
59
.lighthouserc.yml
Normal file
59
.lighthouserc.yml
Normal 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
|
68
Makefile
68
Makefile
|
@ -1,39 +1,65 @@
|
|||
CSS_DIR = themes/etch-custom/assets/css
|
||||
DEVSERVER_URL="http://localhost:1313/"
|
||||
|
||||
USER = deploy@seirdy.one
|
||||
WWW_ROOT = /var/www/seirdy.one
|
||||
GEMINI_ROOT = /srv/gemini/seirdy.one
|
||||
DOMAIN = seirdy.one
|
||||
HUGO_BASEURL = "https://$(DOMAIN)/"
|
||||
USER = deploy@$(DOMAIN)
|
||||
WWW_ROOT = /var/www/$(DOMAIN)
|
||||
GEMINI_ROOT = /srv/gemini/$(DOMAIN)
|
||||
|
||||
WWW_RSYNC_DEST = $(USER):$(WWW_ROOT)
|
||||
GEMINI_RSYNC_DEST = $(USER):$(GEMINI_ROOT)
|
||||
|
||||
OUTPUT_DIR = public
|
||||
|
||||
RSYNCFLAGS += -rlvz --zc=zstd
|
||||
|
||||
hugo:
|
||||
hugo --gc --enableGitInfo
|
||||
.PHONY: hugo
|
||||
hugo: clean
|
||||
hugo --gc -b $(HUGO_BASEURL)
|
||||
|
||||
# .hintrc-local for linting local files
|
||||
# same as regular .hintrc but with a different connector.
|
||||
.hintrc-local: .hintrc
|
||||
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:
|
||||
rm -rf $(OUTPUT_DIR) .hintrc-local
|
||||
rm -rf $(OUTPUT_DIR) .lighthouseci lighthouse-reports
|
||||
|
||||
.PHONY: lint-css
|
||||
lint-css:
|
||||
stylelint $(CSS_DIR)/main.css $(CSS_DIR)/dark.css
|
||||
csslint $(CSS_DIR)
|
||||
stylelint --di --rd --rdd $(CSS_DIR)/main.css $(CSS_DIR)/dark.css
|
||||
csslint --quiet $(CSS_DIR)
|
||||
|
||||
lint: lint-css hugo .hintrc-local
|
||||
.PHONY: hint
|
||||
hint: hugo .hintrc-local
|
||||
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
|
||||
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
|
||||
# gzip_static + max zopfli compression
|
||||
ifndef NO_GZIP_STATIC
|
||||
|
@ -43,11 +69,23 @@ ifndef NO_GZIP_STATIC
|
|||
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 '*.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
|
||||
|
||||
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
|
||||
|
|
37
budget.json
37
budget.json
|
@ -3,7 +3,7 @@
|
|||
"options": {
|
||||
"firstPartyHostnames": [
|
||||
"seirdy.one",
|
||||
"localhost"
|
||||
"staging.seirdy.one"
|
||||
]
|
||||
},
|
||||
"timings": [
|
||||
|
@ -14,6 +14,14 @@
|
|||
{
|
||||
"metric": "cumulative-layout-shift",
|
||||
"budget": 0
|
||||
},
|
||||
{
|
||||
"metric": "interactive",
|
||||
"budget": 3200
|
||||
},
|
||||
{
|
||||
"metric": "largest-contentful-paint",
|
||||
"budget": 3200
|
||||
}
|
||||
],
|
||||
"resourceSizes": [
|
||||
|
@ -48,32 +56,5 @@
|
|||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
23
config.toml
23
config.toml
|
@ -4,7 +4,8 @@ title = "Seirdy's Home"
|
|||
theme = "etch-custom"
|
||||
|
||||
enableInlineShortcodes = true
|
||||
# disablePathToLower = true
|
||||
enableGitInfo = true
|
||||
disableHugoGeneratorInject = true # first item in <head> should be charset=utf-8
|
||||
uglyurls = true
|
||||
pygmentsCodeFences = true
|
||||
pygmentsUseClasses = true
|
||||
|
@ -76,3 +77,23 @@ path = "gemini/"
|
|||
|
||||
[outputs]
|
||||
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"
|
||||
|
|
|
@ -2,5 +2,6 @@ insecure = true
|
|||
method = "get"
|
||||
exclude = [
|
||||
"^gemini://.*",
|
||||
"mailto:.*",
|
||||
"git@git.*",
|
||||
]
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
{{ $webmanifest := resources.Get "/manifest.webmanifest" | resources.ExecuteAsTemplate "manifest.webmanifest" . | resources.Fingerprint "md5" -}}
|
||||
{{ 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 }}">
|
||||
{{ if eq .Site.BaseURL "https://envs.net/~seirdy/" -}}
|
||||
{{ if ne .Site.BaseURL "https://seirdy.one/" -}}
|
||||
<meta name="robots" content="noindex">
|
||||
{{ else -}}
|
||||
<link rel="canonical" href="https://seirdy.one{{ .RelPermalink }}">
|
||||
|
|
Loading…
Reference in a new issue