Repository navigation
117 lines (101 loc) · 4.85 KB
/
Copy pathdeploy.yml
File metadata and controls
117 lines (101 loc) · 4.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
name: Deploy Pelican Site
on:
push:
branches: [main]
pull_request:
branches: [main]
concurrency:
group: pages-${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || 'deploy' }}
cancel-in-progress: true
permissions:
contents: write
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Initialize submodules
run: git submodule update --init --depth=1
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.13"
cache: pip
- name: Install dependencies
# --no-deps: every transitive dep is already pinned with hashes in
# requirements.txt, so pip's resolver adds nothing here.
# Pygments stays at 2.19.2 because Pelican 4.12 caps it at <2.20.0, and
# pip-compile washed out the manual 2.20.0 override twice. The ReDoS
# advisory it was meant to fix (GHSA-5239-wwwm-4pmq, low: GUID lexer)
# was dismissed as tolerable risk on 2026-07-28 (Dependabot alert #1):
# the build only highlights repo-authored code fences. Bump to >=2.20.0
# once a Pelican release lifts the cap.
run: pip install --require-hashes --no-deps -r requirements.txt
- name: Refresh About page from GitHub profile README
run: scripts/fetch_about.sh
- name: Build site
run: pelican content -o output -s publishconf.py
- name: Build search index (Pagefind)
# Static same-origin search: writes the UI assets and chunked index to
# output/pagefind/, all fetched same-origin, so a strict script-src /
# connect-src 'self' CSP keeps working. Indexing is scoped by
# data-pagefind-body (articles + content pages only), which keeps the
# noindexed /drafts/ pages OUT of the search index. Version pinned;
# the runner's preinstalled Node is sufficient.
run: npx --yes pagefind@1.5.2 --site output
- name: Add CNAME file
run: echo rivassec.com > output/CNAME
- name: Add static tool to sitemap
# The IAM Blast Radius tool ships as a static file (STATIC_PATHS), so
# Pelican's sitemap plugin does not emit it. Inject its canonical URL
# after the build. Idempotent. The page is index,follow, so the
# canonical/noindex guard is satisfied.
run: |
python3 - <<'PY'
from pathlib import Path
p = Path('output/sitemap.xml')
s = p.read_text(encoding='utf-8')
url = '<url><loc>https://rivassec.com/tools/iam-blast-radius/</loc><changefreq>monthly</changefreq><priority>0.6</priority></url>'
if 'tools/iam-blast-radius' not in s and '</urlset>' in s:
p.write_text(s.replace('</urlset>', url + '\n</urlset>'), encoding='utf-8')
print('sitemap: tool URL injected')
else:
print('sitemap: tool URL already present or no </urlset>')
PY
- name: Enforce strict CSP preconditions (no inline styles/scripts)
# Keeps style-src 'self' / script-src 'self' safe: if a template
# change ever introduces an inline style="..." or <style> block
# or onclick= handler, this fails CI before deploy. See
# docs/security-headers.md for the CSP we ship.
run: |
python3 scripts/csp_audit.py output
- name: Check links in built site
# URL exclusions live in .lycheeignore (single source of truth, shared
# with the weekly link-rot workflow; lychee reads it automatically).
# Path exclusions stay inline: .lycheeignore holds URL patterns only.
# 503 is accepted because github.com throttles Actions runners on
# /blob/ pages for hours at a time (2026-10-10: every deploy blocked
# while the same URLs returned 200 elsewhere). A 503 says nothing
# about whether a link is broken, so it must not block a deploy;
# 404s still fail, and the weekly link-rot job still reports 503s.
uses: lycheeverse/lychee-action@e7477775783ea5526144ba13e8db5eec57747ce8 # v2.9.0
with:
args: >-
--no-progress
--base https://rivassec.com
--remap "https://rivassec.com/ file://${{ github.workspace }}/output/"
--verbose
--accept 200..=299,429,503
--max-retries 5
--retry-wait-time 2
--exclude-path output/feeds
--exclude-path output/tools
'./output/**/*.html'
format: detailed
fail: true
- name: Deploy to GitHub Pages
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
run: |
ghp-import -n output -b gh-pages
git push origin gh-pages --force