Last updated: 2026-06-18 (auto-tag workflow, versioning conventions)
Push to main
│
├──→ deploy.yml Trunk build → GitHub Pages
│ │
│ └──→ quality.yml Lighthouse + pa11y + W3C + headers
│
└──→ release-tag.yml Auto-tag + GitHub Release + cleanup
Merge release/v* → main
└──→ release-tag.yml Tag vX.Y.Z + Release + delete branch
PR to main
└──→ ci.yml Clippy + rustsec
Daily cron (06:00 UTC)
└──→ news-pipeline.yml fetch + score; general synthesis (Mon), AI brief (Mon+Thu)
Weekly cron
├──→ tools-pipeline.yml Open-source tool discovery + article PR
└──→ feeds-smoke.yml Feed reachability check (no AI)
Push / PR touching scripts/**
└──→ tests.yml pytest pipeline (no API key → zero tokens)
See veille-pipeline.md for the tech-watch workflow details.
Trigger: push to develop, PR to main
jobs:
clippy:
- rustup + wasm32-unknown-unknown target
- cargo clippy --target wasm32-unknown-unknown -- -D warnings
# -D warnings: any warning fails CI
audit:
- cargo install cargo-audit
- cargo audit
# Checks known vulnerabilities (RustSec advisory DB)Rule: no PR merges to main if ci.yml fails.
Trigger: push to main, workflow_dispatch
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
- actions/checkout
- rustup (stable + wasm32-unknown-unknown)
- Swatinem/rust-cache # Cache Cargo registry + target/
- install trunk v0.21.14 # Pinned version for reproducibility
- trunk build --release # Compile src/ + copy public/ → dist/
- upload-pages-artifact # Upload dist/ to the GitHub Pages artifact store
deploy:
needs: build
environment: github-pages
- actions/deploy-pages # Publish the artifact to GitHub PagesTypical duration: 4–8 min (~3–5 min Rust compilation, reduced by the cache).
Production URL: https://www.bourbasquetkev.in (custom domain, see below) — https://bourbask.github.io redirects to it (301)
Trigger: workflow_run (deploy.yml completed on main), workflow_dispatch
jobs:
1. Wait (needs: none)
- HTTP polling up to 2 min via curl -sL (follows 301)
- SITE_URL: https://www.bourbasquetkev.in
2. Lighthouse CI (needs: wait)
- npm install -g @lhci/cli
- lhci autorun (config in .lighthouserc.json)
- 3 URLs: /, /blog, /veille
- Thresholds: performance ≥ 0.80 (warn), accessibility ≥ 0.85 (error),
best-practices ≥ 0.80 (warn), seo ≥ 0.90 (error)
3. pa11y — WCAG 2.1 AA (needs: wait)
- npm install -g pa11y
- 3 routes × 2 themes: /, /blog, /veille (light + dark)
- WCAG2AA standard, level AA required across all 6 audits
4. W3C Nu HTML Validator (needs: wait)
- curl validator.w3.org/nu/?doc=<url>
- Zero errors required (known exclusion: Trunk integrity attr on <link rel=icon>)
5. HTTP security headers (needs: wait)
- curl -sIL (follows 301, inspects final response)
- Required: Strict-Transport-Security (set by GitHub Pages)
- Informational: CSP, X-Frame-Options, etc. (not settable on GH Pages)Lighthouse config: .lighthouserc.json at the project root.
{
"ci": {
"collect": { "url": ["https://www.bourbasquetkev.in/"], "numberOfRuns": 2 },
"assert": {
"assertions": {
"categories:performance": ["warn", { "minScore": 0.80 }],
"categories:accessibility": ["error", { "minScore": 0.85 }],
"categories:best-practices": ["warn", { "minScore": 0.80 }],
"categories:seo": ["error", { "minScore": 0.90 }]
}
}
}
}| Secret / Permission | Workflows | Role |
|---|---|---|
ANTHROPIC_API_KEY |
news-pipeline, tools-pipeline | Claude API calls (Haiku/Sonnet) |
VAPID_PUBLIC_KEY |
news-pipeline | Web Push — public key |
VAPID_PRIVATE_KEY |
news-pipeline | Web Push — private key |
NOTIFY_SECRET |
news-pipeline | Auth for Worker push endpoints (X-Notify-Secret header) |
contents: write |
news-pipeline | Auto-commit news.json |
pages: write |
deploy | GitHub Pages publishing |
id-token: write |
deploy | OIDC for GitHub Pages |
The tests.yml workflow gets no ANTHROPIC_API_KEY — proof it cannot spend tokens.
Covers ~/.cargo/registry, ~/.cargo/git, and target/.
Lifetime: 7 days (GitHub default), invalidated when Cargo.lock changes.
Typical gain: compilation from 15–20 min down to 4–6 min after the first build.
Pinned in deploy.yml to avoid silent regressions on Trunk updates. Bump manually and test locally before changing the CI version.
The site is served at www.bourbasquetkev.in in addition to bourbask.github.io.
CNAMEfile (repo root) containingwww.bourbasquetkev.in.- Copied to the build root via
index.html:<link data-trunk rel="copy-file" href="CNAME" />. Required: without this file in the artifact, GitHub unsets the custom domain on every Actions deploy.
Settings → Pages → Custom domain = www.bourbasquetkev.in → verification (TXT) → Enforce HTTPS (auto Let's Encrypt cert).
The domain also hosts VPS services (plex, bitwarden, traefik, nextcloud…) via subdomains plus a * wildcard → VPS. The only site-related records:
www CNAME bourbask.github.io.
@ A 185.199.108.153 (+ .109 / .110 / .111 .153) → apex, redirects to www
- An explicit
wwwwins over the wildcard → the other subdomains stay on the VPS, untouched. - The apex on GitHub IPs replaces any previous host (e.g. leftover Vercel
76.76.21.21must be removed). - Do not touch:
MX,SPF,DKIM, the*wildcard, or the VPS subdomains. - Watch out for
CNAMErecords pointing at the apex (e.g.ftp): repoint them to anArecord on the VPS, otherwise they follow the apex to GitHub.
When a PR from release/vX.Y.Z is merged to main, release-tag.yml automatically:
- Extracts the version from the branch name (
release/v2.14.0→v2.14.0) - Creates a git tag on the merge commit
- Creates a GitHub Release with the PR body as release notes
- Deletes the release branch (ephemeral — tags are the permanent record)
All previous release branches can be safely deleted.
feature/xxx → develop → main
↑ ↑
ci.yml deploy.yml
(clippy) (build + deploy)
quality.yml
(validation)
release-tag.yml
(auto-tag + release)
develop: integration branch — Clippy CI + auditmain: production branch — every push triggers a deployrelease/v*: ephemeral PR vehicle — auto-deleted after merge
Merge rules: rebase for feature→develop, squash for develop→main.
Cargo.lockcommitted → identical artifact on every build- Pinned Trunk version → stable bundling behavior
rust-cachekeyed onCargo.lockhash → auto-invalidation on dependency changes
GitHub Pages keeps the artifact of the last successful deploy. On a regression:
- Identify the culprit commit via
git log git revert <commit>+ push tomaindeploy.ymlre-runs automatically
Or force manually via GitHub → Actions → deploy.yml → Run workflow on the previous commit.