diff --git a/.build.yml b/.build.yml index 0b14bf5..17c80b9 100644 --- a/.build.yml +++ b/.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 diff --git a/.gitignore b/.gitignore index 08ff4c5..f4ad510 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ public/ public_*/ hint-report/ -.hintrc-local +.hintrc-* *.report.html *.report.json +.lighthouseci +lighthouse-reports diff --git a/.hintrc b/.hintrc index 1f23e57..a271d22 100644 --- a/.hintrc +++ b/.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" } } diff --git a/.lighthouserc.yml b/.lighthouserc.yml new file mode 100644 index 0000000..1362333 --- /dev/null +++ b/.lighthouserc.yml @@ -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 diff --git a/Makefile b/Makefile index 81c315e..8849f14 100644 --- a/Makefile +++ b/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 diff --git a/budget.json b/budget.json index 1641c26..8747779 100644 --- a/budget.json +++ b/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 - } - ] } ] diff --git a/config.toml b/config.toml index f65b8de..3f29df0 100644 --- a/config.toml +++ b/config.toml @@ -4,7 +4,8 @@ title = "Seirdy's Home" theme = "etch-custom" enableInlineShortcodes = true -# disablePathToLower = true +enableGitInfo = true +disableHugoGeneratorInject = true # first item in 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" diff --git a/lychee.toml b/lychee.toml index 763208b..88e64e6 100644 --- a/lychee.toml +++ b/lychee.toml @@ -2,5 +2,6 @@ insecure = true method = "get" exclude = [ "^gemini://.*", + "mailto:.*", "git@git.*", ] diff --git a/themes/etch-custom/layouts/partials/head.html b/themes/etch-custom/layouts/partials/head.html index 4d77022..052d0e1 100644 --- a/themes/etch-custom/layouts/partials/head.html +++ b/themes/etch-custom/layouts/partials/head.html @@ -17,7 +17,7 @@ {{ $webmanifest := resources.Get "/manifest.webmanifest" | resources.ExecuteAsTemplate "manifest.webmanifest" . | resources.Fingerprint "md5" -}} {{ printf `` $webmanifest.RelPermalink | safeHTML }} - {{ if eq .Site.BaseURL "https://envs.net/~seirdy/" -}} + {{ if ne .Site.BaseURL "https://seirdy.one/" -}} {{ else -}}