ci: refactor pipeline into independent build/sign/release/changelog workflows

Signed-off-by: nopeitsnothing <no@anonymousplanet.org>
This commit is contained in:
nopeitsnothing
2026-05-22 16:20:46 -04:00
parent f3cb57230f
commit 3184181fa8
+164 -51
View File
@@ -1,25 +1,10 @@
name: 📖 Build & Sign PDFs # DEPRECATED — replaced by build.yml, sign.yml, and release.yml
# This file is kept temporarily so in-flight runs are not broken.
#
# name: 📖 Build & Sign PDFs
on: on:
workflow_dispatch: workflow_dispatch: # manual only — no automatic triggers (deprecated)
inputs:
build_mode:
description: 'PDF build mode'
required: true
default: 'both'
type: choice
options:
- light
- dark
- both
push:
branches:
- main
paths:
- "docs/**"
- "mkdocs.yml"
- "scripts/**"
- ".github/workflows/**"
permissions: permissions:
contents: write contents: write
@@ -38,8 +23,13 @@ jobs:
with: with:
python-version: "3.13" python-version: "3.13"
- name: 📦 Install MkDocs Material - name: 📦 Install Python dependencies
run: pip install mkdocs-material run: pip install mkdocs-material pillow numpy
- name: 🖼️ Install poppler (pdftoppm) and qpdf
run: |
sudo apt-get update
sudo apt-get install -y poppler-utils qpdf
- name: Setup Chrome - name: Setup Chrome
uses: browser-actions/setup-chrome@v2 uses: browser-actions/setup-chrome@v2
@@ -49,21 +39,71 @@ jobs:
install-chromedriver: true install-chromedriver: true
- name: 🔑 Install GPG tools - name: 🔑 Install GPG tools
run: | run: sudo apt-get install -y gnupg
sudo apt-get update
sudo apt-get install gnupg
- name: 🖨️ Build & Hash PDFs # ------------------------------------------------------------------ #
# Build PDFs
# ------------------------------------------------------------------ #
- name: 🖨️ Build PDFs
env: env:
CI: true CI: true
run: | run: python scripts/build_guide_pdf.py --${{ inputs.build_mode || 'both' }}
python scripts/build_guide_pdf.py --${{ inputs.build_mode || 'both' }}
for f in ./export/*.pdf; do
echo "sha256sums: $f"; sha256sum "$f" >> export/sha256sums.txt; done
for f in ./export/*.pdf; do
echo "b2sums: $f"; b2sum "$f" >> export/b2sums.txt; done
# ------------------------------------------------------------------ #
# Hash (SHA-256 + BLAKE2b)
# ------------------------------------------------------------------ #
- name: #️⃣ Hash PDFs
id: hashes
run: |
mkdir -p export
sha256sum export/thgtoa.pdf | awk '{print $1}' > export/thgtoa.pdf.sha256
sha256sum export/thgtoa-dark.pdf | awk '{print $1}' > export/thgtoa-dark.pdf.sha256
b2sum export/thgtoa.pdf | awk '{print $1}' > export/thgtoa.pdf.b2
b2sum export/thgtoa-dark.pdf | awk '{print $1}' > export/thgtoa-dark.pdf.b2
# Also write combined human-readable files
sha256sum export/thgtoa.pdf export/thgtoa-dark.pdf > export/sha256sums.txt
b2sum export/thgtoa.pdf export/thgtoa-dark.pdf > export/b2sums.txt
# Expose hashes as step outputs for the release body
echo "light_sha256=$(cat export/thgtoa.pdf.sha256)" >> $GITHUB_OUTPUT
echo "dark_sha256=$(cat export/thgtoa-dark.pdf.sha256)" >> $GITHUB_OUTPUT
echo "light_b2=$(cat export/thgtoa.pdf.b2)" >> $GITHUB_OUTPUT
echo "dark_b2=$(cat export/thgtoa-dark.pdf.b2)" >> $GITHUB_OUTPUT
# ------------------------------------------------------------------ #
# GPG sign (detached .sig for each PDF + each hash file)
# ------------------------------------------------------------------ #
- name: 🔏 Import GPG key
env:
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
run: |
echo "$GPG_PRIVATE_KEY" | gpg --batch --import
# Pre-cache the passphrase so signing doesn't prompt
echo "$GPG_PASSPHRASE" | gpg --batch --yes --passphrase-fd 0 \
--pinentry-mode loopback --list-secret-keys
- name: 🔏 GPG sign PDFs and hash files
env:
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
run: |
sign() {
echo "$GPG_PASSPHRASE" | gpg --batch --yes --passphrase-fd 0 \
--pinentry-mode loopback \
--detach-sign --armor --output "${1}.sig" "$1"
}
sign export/thgtoa.pdf
sign export/thgtoa-dark.pdf
sign export/sha256sums.txt
sign export/b2sums.txt
# ------------------------------------------------------------------ #
# VirusTotal
# ------------------------------------------------------------------ #
- name: 🦠 Upload PDFs to VirusTotal - name: 🦠 Upload PDFs to VirusTotal
id: vt
uses: crazy-max/ghaction-virustotal@v5 uses: crazy-max/ghaction-virustotal@v5
with: with:
vt_api_key: ${{ secrets.VT_API_KEY }} vt_api_key: ${{ secrets.VT_API_KEY }}
@@ -71,35 +111,108 @@ jobs:
export/thgtoa.pdf export/thgtoa.pdf
export/thgtoa-dark.pdf export/thgtoa-dark.pdf
- name: 📊 Extract VT scan results - name: 🔗 Build VT report URLs
id: vt-scan id: vt_urls
run: | run: |
echo "status=completed" >> $GITHUB_OUTPUT light_hash=$(cat export/thgtoa.pdf.sha256)
dark_hash=$(cat export/thgtoa-dark.pdf.sha256)
echo "light_vt=https://www.virustotal.com/gui/file/${light_hash}" >> $GITHUB_OUTPUT
echo "dark_vt=https://www.virustotal.com/gui/file/${dark_hash}" >> $GITHUB_OUTPUT
- name: 🔗 Generate VT report links # ------------------------------------------------------------------ #
# Create GitHub Release
# ------------------------------------------------------------------ #
- name: 🏷️ Generate release tag
id: tag
run: | run: |
# Create a markdown file with VT scan results and links TAG="release-$(date -u +'%Y%m%d-%H%M%S')"
cat > export/virus-total-results.md << EOF echo "tag=$TAG" >> $GITHUB_OUTPUT
## VirusTotal Scan Results echo "name=Release $(date -u +'%Y-%m-%d %H:%M UTC')" >> $GITHUB_OUTPUT
**Scan Date:** \$(date -u +"%Y-%m-%d %H:%M UTC") - name: 🚀 Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.tag.outputs.tag }}
name: ${{ steps.tag.outputs.name }}
body: |
## 📖 The Hitchhiker's Guide to Online Anonymity
### thgtoa.pdf (Light Mode) Built from commit ${{ github.sha }} on `${{ github.ref_name }}`.
- **VT Report:** https://www.virustotal.com/gui/file/\$(sha256sum export/thgtoa.pdf | cut -d' ' -f1)
### thgtoa-dark.pdf (Dark Mode) (currently broken)
- **VT Report:** https://www.virustotal.com/gui/file/\$(sha256sum export/thgtoa-dark.pdf | cut -d' ' -f1)
--- ---
*Scan performed automatically by GitHub Actions*
EOF
- name: 📤 Upload export directory as artifact ### 📄 Files
| File | Description |
|------|-------------|
| `thgtoa.pdf` | Light mode PDF |
| `thgtoa-dark.pdf` | Dark mode PDF (hacker theme) |
| `sha256sums.txt` | SHA-256 checksums |
| `b2sums.txt` | BLAKE2b checksums |
| `*.sig` | GPG detached signatures (ASCII armor) |
---
### #️⃣ Hashes
#### thgtoa.pdf (Light)
```
SHA-256: ${{ steps.hashes.outputs.light_sha256 }}
BLAKE2b: ${{ steps.hashes.outputs.light_b2 }}
```
#### thgtoa-dark.pdf (Dark)
```
SHA-256: ${{ steps.hashes.outputs.dark_sha256 }}
BLAKE2b: ${{ steps.hashes.outputs.dark_b2 }}
```
---
### 🔏 GPG Signatures
Detached signatures (`.sig`) are included in the release assets.
Verify with:
```bash
gpg --verify thgtoa.pdf.sig thgtoa.pdf
gpg --verify thgtoa-dark.pdf.sig thgtoa-dark.pdf
```
The signing key is published at `pgp/anonymousplanet-release.asc`.
---
### 🦠 VirusTotal Scans
| File | Report |
|------|--------|
| `thgtoa.pdf` | ${{ steps.vt_urls.outputs.light_vt }} |
| `thgtoa-dark.pdf` | ${{ steps.vt_urls.outputs.dark_vt }} |
files: |
export/thgtoa.pdf
export/thgtoa-dark.pdf
export/sha256sums.txt
export/b2sums.txt
export/thgtoa.pdf.sha256
export/thgtoa-dark.pdf.sha256
export/thgtoa.pdf.b2
export/thgtoa-dark.pdf.b2
export/thgtoa.pdf.sig
export/thgtoa-dark.pdf.sig
export/sha256sums.txt.sig
export/b2sums.txt.sig
draft: false
prerelease: false
fail_on_unmatched_files: true
# ------------------------------------------------------------------ #
# Upload everything as a workflow artifact (90-day archive)
# ------------------------------------------------------------------ #
- name: 📤 Upload export as workflow artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: upload pdf artifact name: pdf-release-${{ steps.tag.outputs.tag }}
path: | path: export/*
export/*
if-no-files-found: error if-no-files-found: error
retention-days: 90 retention-days: 90
compression-level: 0 compression-level: 0