mirror of
https://github.com/Anon-Planet/thgtoa.git
synced 2026-05-07 03:54:18 +02:00
Compare commits
29 Commits
4c3ca7bfd7
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| f3cb57230f | |||
| 5e8057bb1f | |||
| ac3d2ceb37 | |||
| 5eded0af38 | |||
| 1bb0acc3e8 | |||
| 25bc901ece | |||
| 78a0a37ee8 | |||
| aeb63cd7ba | |||
| 64ddd18535 | |||
| 7c9847e7d1 | |||
| 1e8c90513f | |||
| 2d09d7c01c | |||
| 1938e031ee | |||
| 8483d6336b | |||
| 1c168691c5 | |||
| ae50911375 | |||
| df2dd61676 | |||
| 904fa24478 | |||
| 28556c016c | |||
| 7bc3ed6bb6 | |||
| 9a58ca1b7c | |||
| 655e47fb8d | |||
| c0eb8aa6f3 | |||
| 90aa8b5442 | |||
| 85912692d2 | |||
| 6305e1fbbb | |||
| 0b71c3f49a | |||
| 468ff8f4a1 | |||
| 11c2882ba5 |
@@ -1,137 +0,0 @@
|
|||||||
name: 📖 Build PDF
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- "docs/**"
|
|
||||||
- "mkdocs.yml"
|
|
||||||
- "scripts/build_guide_pdf.py"
|
|
||||||
- ".github/workflows/build-pdf.yml"
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
paths:
|
|
||||||
- "docs/**"
|
|
||||||
- "mkdocs.yml"
|
|
||||||
- "scripts/build_guide_pdf.py"
|
|
||||||
- ".github/workflows/build-pdf.yml"
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
pdf:
|
|
||||||
name: PDF build and sign
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: 🛠️ Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: 🐍 Set up Python
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: "3.13"
|
|
||||||
|
|
||||||
- name: 📦 Install MkDocs Material
|
|
||||||
run: pip install mkdocs-material
|
|
||||||
|
|
||||||
- name: 🌐 Install Chromium
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y --no-install-recommends chromium
|
|
||||||
|
|
||||||
- name: 🔑 Install GPG tools
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install gnupg
|
|
||||||
|
|
||||||
- name: 🖨️ Build PDF
|
|
||||||
env:
|
|
||||||
CI: true
|
|
||||||
run: python scripts/build_guide_pdf.py --both
|
|
||||||
|
|
||||||
- name: 🔢 Generate SHA256 hashes for root directory
|
|
||||||
run: |
|
|
||||||
cd ${{ github.workspace }}
|
|
||||||
sha256sum export/thgtoa.pdf > sha256sum-light.txt
|
|
||||||
sha256sum export/thgtoa-dark.pdf >> sha256sum-light.txt
|
|
||||||
|
|
||||||
# Create separate hash files for each PDF
|
|
||||||
sha256sum export/thgtoa.pdf > thgtoa.pdf.sha256
|
|
||||||
sha256sum export/thgtoa-dark.pdf > thgtoa-dark.pdf.sha256
|
|
||||||
|
|
||||||
- name: 🔒 Sign PDFs with GPG key
|
|
||||||
env:
|
|
||||||
GPG_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
|
|
||||||
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
|
||||||
run: |
|
|
||||||
cd ${{ github.workspace }}
|
|
||||||
|
|
||||||
# Import GPG key
|
|
||||||
echo "$GPG_KEY" | gpg --batch --import 2>/dev/null || true
|
|
||||||
|
|
||||||
# Sign the PDFs (detach signature)
|
|
||||||
gpg --batch --yes --armor --detach-sign --output export/thgtoa.pdf.sig export/thgtoa.pdf
|
|
||||||
gpg --batch --yes --armor --detach-sign --output export/thgtoa-dark.pdf.sig export/thgtoa-dark.pdf
|
|
||||||
|
|
||||||
# Also sign the hash files
|
|
||||||
gpg --batch --yes --armor --detach-sign --output sha256sum-light.txt.sig sha256sum-light.txt
|
|
||||||
|
|
||||||
upload:
|
|
||||||
name: Upload artifacts
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: pdf
|
|
||||||
steps:
|
|
||||||
- name: 📤 Upload PDF artifact (Light Mode)
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: light-pdf-files
|
|
||||||
path: |
|
|
||||||
export/thgtoa.pdf
|
|
||||||
export/thgtoa.pdf.sig
|
|
||||||
thgtoa.pdf.sha256
|
|
||||||
archive: false
|
|
||||||
if-no-files-found: error
|
|
||||||
retention-days: 90
|
|
||||||
|
|
||||||
- name: 📤 Upload PDF artifact (Dark Mode)
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: dark-pdf-files
|
|
||||||
path: |
|
|
||||||
export/thgtoa-dark.pdf
|
|
||||||
export/thgtoa-dark.pdf.sig
|
|
||||||
thgtoa-dark.pdf.sha256
|
|
||||||
archive: false
|
|
||||||
if-no-files-found: error
|
|
||||||
retention-days: 90
|
|
||||||
|
|
||||||
- name: 📤 Upload combined hash file to root
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: hash-files
|
|
||||||
path: |
|
|
||||||
sha256sum-light.txt
|
|
||||||
archive: false
|
|
||||||
if-no-files-found: error
|
|
||||||
retention-days: 90
|
|
||||||
|
|
||||||
release:
|
|
||||||
name: Create Release
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: pdf
|
|
||||||
steps:
|
|
||||||
- name: 🚀 Create Release (if tag exists)
|
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
|
||||||
uses: softprops/action-gh-release@v1
|
|
||||||
with:
|
|
||||||
files: |
|
|
||||||
export/thgtoa.pdf
|
|
||||||
export/thgtoa-dark.pdf
|
|
||||||
export/thgtoa.pdf.sig
|
|
||||||
export/thgtoa-dark.pdf.sig
|
|
||||||
sha256sum-light.txt
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
name: 📖 Build & Sign PDFs
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
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:
|
||||||
|
contents: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-sign-release:
|
||||||
|
name: Build, Sign & Release PDFs
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: 🛠️ Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: 🐍 Set up Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: "3.13"
|
||||||
|
|
||||||
|
- name: 📦 Install MkDocs Material
|
||||||
|
run: pip install mkdocs-material
|
||||||
|
|
||||||
|
- name: Setup Chrome
|
||||||
|
uses: browser-actions/setup-chrome@v2
|
||||||
|
with:
|
||||||
|
chrome-version: 120
|
||||||
|
install-dependencies: true
|
||||||
|
install-chromedriver: true
|
||||||
|
|
||||||
|
- name: 🔑 Install GPG tools
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install gnupg
|
||||||
|
|
||||||
|
- name: 🖨️ Build & Hash PDFs
|
||||||
|
env:
|
||||||
|
CI: true
|
||||||
|
run: |
|
||||||
|
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
|
||||||
|
|
||||||
|
- name: 🦠 Upload PDFs to VirusTotal
|
||||||
|
uses: crazy-max/ghaction-virustotal@v5
|
||||||
|
with:
|
||||||
|
vt_api_key: ${{ secrets.VT_API_KEY }}
|
||||||
|
files: |
|
||||||
|
export/thgtoa.pdf
|
||||||
|
export/thgtoa-dark.pdf
|
||||||
|
|
||||||
|
- name: 📊 Extract VT scan results
|
||||||
|
id: vt-scan
|
||||||
|
run: |
|
||||||
|
echo "status=completed" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: 🔗 Generate VT report links
|
||||||
|
run: |
|
||||||
|
# Create a markdown file with VT scan results and links
|
||||||
|
cat > export/virus-total-results.md << EOF
|
||||||
|
## VirusTotal Scan Results
|
||||||
|
|
||||||
|
**Scan Date:** \$(date -u +"%Y-%m-%d %H:%M UTC")
|
||||||
|
|
||||||
|
### thgtoa.pdf (Light Mode)
|
||||||
|
- **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
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: upload pdf artifact
|
||||||
|
path: |
|
||||||
|
export/*
|
||||||
|
if-no-files-found: error
|
||||||
|
retention-days: 90
|
||||||
|
compression-level: 0
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
name: '🦠 VirusTotal Scan'
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- 'main'
|
|
||||||
tags:
|
|
||||||
- 'v*'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
steps:
|
|
||||||
- name: '📦 Checkout'
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
|
|
||||||
- name: '🔍 Download PDF artifacts from build workflow'
|
|
||||||
uses: actions/download-artifact@v7
|
|
||||||
with:
|
|
||||||
pattern: light-pdf-files,dark-pdf-files
|
|
||||||
path: pdfs
|
|
||||||
merge-multiple: true
|
|
||||||
|
|
||||||
- name: '🦠 Scan PDF files using VT'
|
|
||||||
uses: crazy-max/ghaction-virustotal@v5
|
|
||||||
with:
|
|
||||||
vt_api_key: ${{ secrets.VT_API_KEY }}
|
|
||||||
update_release_body: false # We'll handle this manually in the next step
|
|
||||||
files: |
|
|
||||||
./pdfs/thgtoa.pdf
|
|
||||||
./pdfs/thgtoa-dark.pdf
|
|
||||||
|
|
||||||
- name: '📊 Extract VT scan results'
|
|
||||||
id: vt-scan
|
|
||||||
run: |
|
|
||||||
echo "scan completed" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: '🔗 Generate VT report links'
|
|
||||||
run: |
|
|
||||||
# Create a markdown file with VT scan results and links
|
|
||||||
cat > vt-results.md << EOF
|
|
||||||
## VirusTotal Scan Results
|
|
||||||
|
|
||||||
**Scan Date:** $(date -u +"%Y-%m-%d %H:%M UTC")
|
|
||||||
|
|
||||||
### thgtoa.pdf (Light Mode)
|
|
||||||
- **VT Report:** https://www.virustotal.com/gui/file/$(sha256sum pdfs/thgtoa.pdf | cut -d' ' -f1)
|
|
||||||
|
|
||||||
### thgtoa-dark.pdf (Dark Mode)
|
|
||||||
- **VT Report:** https://www.virustotal.com/gui/file/$(sha256sum pdfs/thgtoa-dark.pdf | cut -d' ' -f1)
|
|
||||||
|
|
||||||
---
|
|
||||||
*Scan performed automatically by GitHub Actions*
|
|
||||||
EOF
|
|
||||||
|
|
||||||
- name: '📝 Update release with VT results (if tag exists)'
|
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
GH_REPO: ${{ github.repository }}
|
|
||||||
run: |
|
|
||||||
# Get the latest release notes
|
|
||||||
RELEASE_NOTES=$(gh release view ${{ github.ref_name }} --json body --jq .body 2>/dev/null || echo "")
|
|
||||||
|
|
||||||
# Append VT results to release notes
|
|
||||||
if [ -n "$RELEASE_NOTES" ]; then
|
|
||||||
echo "" >> vt-results.md
|
|
||||||
echo "---" >> vt-results.md
|
|
||||||
echo "### Previous Release Notes" >> vt-results.md
|
|
||||||
echo "$RELEASE_NOTES" >> vt-results.md
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Update the release with VT results
|
|
||||||
gh release edit ${{ github.ref_name }} --notes-file vt-results.md
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
# Changelog
|
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
||||||
|
|
||||||
## [Unreleased]
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Add ways to verify the files
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- Refactored GitHub Actions workflow **Build PDF** (`scripts\build_guide_pdf.py`): now builds both light and dark mode PDFs (`export/thgtoa.pdf` and `export/thgtoa-dark.pdf` respectively).
|
|
||||||
- Restored previous VT scans workflow **VirusTotal Scan** (`.github/workflows/vt-scan.yml`): submit files to VT for malware scanning. Links will be published on the site.
|
|
||||||
|
|
||||||
## Fixed
|
|
||||||
|
|
||||||
- `docs/about/index.md`: replace broken reference-style internal links
|
|
||||||
- `docs/guide/index.md`: Appendix A6: comment out deprecated ODT information because we don't and probably won't use it in the future
|
|
||||||
|
|
||||||
### Feature
|
|
||||||
|
|
||||||
- Updated `scripts/build_guide_pdf.py` to use `--print-to-pdf` instead of `--save-as` for PDF generation, and added a new `--dark-mode` flag to generate dark mode PDFs. The script now supports generating both light and dark mode PDFs with a single command invocation by using the `--both` flag. This change improves the PDF generation process and provides better support for dark mode users. Save your eyes - you only get one pair.
|
|
||||||
|
|
||||||
## [1.2.1] - 2026-04-11
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- GitHub Actions workflow **Build PDF** (`.github/workflows/build-pdf.yml`): installs Chromium on `ubuntu-latest`, runs `scripts/build_guide_pdf.py`, uploads `export/guide.pdf` as the `guide-pdf` artifact. Runs on `workflow_dispatch`, on pushes to `main` that touch docs or build inputs, and on matching pull requests.
|
|
||||||
|
|
||||||
- `scripts/build_guide_pdf.py` to build the MkDocs site and render the guide to a single PDF (`export/guide.pdf` by default) using a Chromium-based browser (Chrome or Edge) headless print-to-PDF.
|
|
||||||
- `docs/stylesheets/extra.css` and `extra_css` in `mkdocs.yml` for shared site styling.
|
|
||||||
- This `CHANGELOG.md`.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- `README.md` “Ways to read or export the guide”: hosted link, local `mkdocs serve`, PDF build via the script, ODT note, raw Markdown link.
|
|
||||||
- Guide landing layout: wrap the opening block in `docs/guide/index.md` with a `guide-intro-lead` container so the logo and first sections share one layout context for web and print.
|
|
||||||
- `.gitignore` to exclude local build outputs `export/`, `site/`, and `_site_test/`.
|
|
||||||
- `scripts/build_guide_pdf.py`: when the `CI` environment variable is set, pass Chromium flags (`--no-sandbox`, `--disable-setuid-sandbox`, `--disable-dev-shm-usage`) so headless print works on typical CI images.
|
|
||||||
- `README.md`: note the **Build PDF** GitHub Actions workflow and the `guide-pdf` artifact.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- `docs/guide/index.md`: replace broken reference-style internal links (`[label][label:]`) with working same-page fragment links to the correct headings; correct the mismatched “Real-Name System” cross-reference; fix a broken footnote marker on the “free (unallocated) space of your hard drive” list item.
|
|
||||||
|
|
||||||
[Unreleased]: https://github.com/Anon-Planet/thgtoa/compare/v1.2.1...HEAD
|
|
||||||
[1.2.1]: https://github.com/Anon-Planet/thgtoa/releases/tag/v1.2.1
|
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
Welcome.
|
Welcome.
|
||||||
|
|
||||||
**[IMPORTANT RECOMMENDATION FOR UKRAINIANS. ВАЖЛИВА РЕКОМЕНДАЦІЯ ДЛЯ УКРАЇНЦІВ](briar.html)**
|
This is a guide with the aim of providing an introduction to various online tracking techniques, online ID verification techniques, and detailed guidance to creating and maintaining (truly) anonymous online identities. <span style="color: red">**It is written with hope for activists, journalists, scientists, lawyers, whistle-blowers, and good people being oppressed, censored, harassed anywhere!**</span> This guide has no affiliation with the [Anonymous](https://en.wikipedia.org/wiki/Anonymous_(hacker_group)) <sup>[[Wikiless]](https://wikiless.com/wiki/Anonymous_(hacker_group))</sup> <sup>[[Archive.org]](https://web.archive.org/web/https://en.wikipedia.org/wiki/Anonymous_(hacker_group))</sup> collective/movement.
|
||||||
|
|
||||||
This is a maintained guide with the aim of providing an introduction to various online tracking techniques, online ID verification techniques, and detailed guidance to creating and maintaining (truly) anonymous online identities. <span style="color: red">**It is written with hope for activists, journalists, scientists, lawyers, whistle-blowers, and good people being oppressed, censored, harassed anywhere!**</span> This guide has no affiliation with the [Anonymous](https://en.wikipedia.org/wiki/Anonymous_(hacker_group)) <sup>[[Wikiless]](https://wikiless.com/wiki/Anonymous_(hacker_group))</sup> <sup>[[Archive.org]](https://web.archive.org/web/https://en.wikipedia.org/wiki/Anonymous_(hacker_group))</sup> collective/movement.
|
|
||||||
|
|
||||||
This guide is an open-source non-profit initiative, [licensed](LICENSE.html) under **Creative Commons Attribution-NonCommercial 4.0 International** ([cc-by-nc-4.0](https://creativecommons.org/licenses/by-nc/4.0/) <sup>[[Archive.org]](https://web.archive.org/web/https://creativecommons.org/licenses/by-nc/4.0/)</sup>) and is **not sponsored/endorsed by any commercial/governmental entity**. This means that you are free to use our guide for pretty much any purpose **excluding commercially** as long as you do attribute it. There are no ads or any affiliate links.
|
This guide is an open-source non-profit initiative, [licensed](LICENSE.html) under **Creative Commons Attribution-NonCommercial 4.0 International** ([cc-by-nc-4.0](https://creativecommons.org/licenses/by-nc/4.0/) <sup>[[Archive.org]](https://web.archive.org/web/https://creativecommons.org/licenses/by-nc/4.0/)</sup>) and is **not sponsored/endorsed by any commercial/governmental entity**. This means that you are free to use our guide for pretty much any purpose **excluding commercially** as long as you do attribute it. There are no ads or any affiliate links.
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: "About Anonymous Planet"
|
title: "Anonymous Planet"
|
||||||
description: We are the maintainers of the Hitchhiker's Guide and the PSA Matrix space.
|
description: We are the maintainers of the Hitchhiker's Guide and the PSA Matrix space.
|
||||||
schema:
|
schema:
|
||||||
"@context": https://schema.org
|
"@context": https://schema.org
|
||||||
@@ -7,7 +7,7 @@ schema:
|
|||||||
"@id": https://www.anonymousplanet.org/
|
"@id": https://www.anonymousplanet.org/
|
||||||
name: Anonymous Planet
|
name: Anonymous Planet
|
||||||
url: https://www.anonymousplanet.org/about/
|
url: https://www.anonymousplanet.org/about/
|
||||||
logo: ../media/favicon.png
|
logo: ../media/profile.png
|
||||||
sameAs:
|
sameAs:
|
||||||
- https://github.com/Anon-Planet
|
- https://github.com/Anon-Planet
|
||||||
- https://opencollective.com/anonymousplanetorg
|
- https://opencollective.com/anonymousplanetorg
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
---
|
||||||
|
title: "Release Notes"
|
||||||
|
description: "Release Notes"
|
||||||
|
schema:
|
||||||
|
"@context": https://schema.org
|
||||||
|
"@type": Organization
|
||||||
|
"@id": https://www.anonymousplanet.org/
|
||||||
|
name: Anonymous Planet
|
||||||
|
url: https://www.anonymousplanet.org/authors/
|
||||||
|
logo: ../media/profile.png
|
||||||
|
sameAs:
|
||||||
|
- https://github.com/Anon-Planet
|
||||||
|
- https://opencollective.com/anonymousplanetorg
|
||||||
|
- https://mastodon.social/@anonymousplanet
|
||||||
|
---
|
||||||
|
|
||||||
|
# Release Notes
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
!!! Note "Added"
|
||||||
|
|
||||||
|
- This changelog page
|
||||||
|
- Add ways to verify the files
|
||||||
|
|
||||||
|
!!! Note "Changed"
|
||||||
|
|
||||||
|
- Refactored GitHub Actions workflow **Build PDF** (`scripts\build_guide_pdf.py`): now builds both light and dark mode PDFs
|
||||||
|
- Restored previous VT scans
|
||||||
|
|
||||||
|
!!! Note "Fixed"
|
||||||
|
|
||||||
|
- `docs/about/index.md`: replace broken reference-style internal links
|
||||||
|
- `docs/guide/index.md`: Appendix A6: comment out deprecated ODT information because we don't and probably won't use it in the future
|
||||||
|
|
||||||
|
!!! Note "Feature"
|
||||||
|
|
||||||
|
- Updated `scripts/build_guide_pdf.py` to use `--print-to-pdf` instead of `--save-as` for PDF generation
|
||||||
|
- Added a new `--dark-mode` flag to generate dark mode PDFs. Save your eyes - you only get one pair.
|
||||||
|
|
||||||
|
## [v1.2.1]
|
||||||
|
|
||||||
|
!!! Note "Added"
|
||||||
|
|
||||||
|
- GitHub Actions workflow **Build PDF** (`.github/workflows/build-pdf.yml`): installs Chromium on `ubuntu-latest`, runs `scripts/build_guide_pdf.py`, uploads `export/guide.pdf` as the `guide-pdf` artifact. Runs on `workflow_dispatch`, on pushes to `main` that touch docs or build inputs, and on matching pull requests.
|
||||||
|
|
||||||
|
- `scripts/build_guide_pdf.py` to build the MkDocs site and render the guide to a single PDF (`export/guide.pdf` by default) using a Chromium-based browser (Chrome or Edge) headless print-to-PDF.
|
||||||
|
- `docs/stylesheets/extra.css` and `extra_css` in `mkdocs.yml` for shared site styling.
|
||||||
|
- This `CHANGELOG.md`.
|
||||||
|
|
||||||
|
!!! Note "Changed"
|
||||||
|
|
||||||
|
- `README.md` “Ways to read or export the guide”: hosted link, local `mkdocs serve`, PDF build via the script, ODT note, raw Markdown link.
|
||||||
|
- Guide landing layout: wrap the opening block in `docs/guide/index.md` with a `guide-intro-lead` container so the logo and first sections share one layout context for web and print.
|
||||||
|
- `.gitignore` to exclude local build outputs `export/`, `site/`, and `_site_test/`.
|
||||||
|
- `scripts/build_guide_pdf.py`: when the `CI` environment variable is set, pass Chromium flags (`--no-sandbox`, `--disable-setuid-sandbox`, `--disable-dev-shm-usage`) so headless print works on typical CI images.
|
||||||
|
- `README.md`: note the **Build PDF** GitHub Actions workflow and the `guide-pdf` artifact.
|
||||||
|
|
||||||
|
!!! Note "Fixed"
|
||||||
|
|
||||||
|
- `docs/guide/index.md`: replace broken reference-style internal links (`[label][label:]`) with working same-page fragment links to the correct headings; correct the mismatched “Real-Name System” cross-reference; fix a broken footnote marker on the “free (unallocated) space of your hard drive” list item.
|
||||||
|
|
||||||
|
[Unreleased]: https://github.com/Anon-Planet/thgtoa/compare/v1.2.1...HEAD
|
||||||
|
[v1.2.1]: https://github.com/Anon-Planet/thgtoa/releases/tag/v1.2.1
|
||||||
|
|
||||||
|
***The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),***
|
||||||
|
***and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).***
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
# Development
|
||||||
|
|
||||||
|
??? Note "How the pipeline works"
|
||||||
|
|
||||||
|
**Automatic PDF Generation:** - Builds both light and dark mode PDFs from MkDocs source
|
||||||
|
**SHA256 Hash Generation:** - Creates hash files for integrity verification
|
||||||
|
**GPG Signature Signing:** - Signs all PDFs and hash files with repository GPG key
|
||||||
|
**VirusTotal Scanning:** - Automatically scans PDFs and updates release notes
|
||||||
|
**Release Automation:** - Packages everything into GitHub releases
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Build PDF Workflow (`build-sign-release.yml`)
|
||||||
|
|
||||||
|
!!! Note "Steps"
|
||||||
|
|
||||||
|
- Checkout repository
|
||||||
|
- Set up Python and MkDocs Material
|
||||||
|
- Install Chromium browser
|
||||||
|
- Generate both light and dark mode PDFs with `scripts\build_guide_pdf.py`
|
||||||
|
- Create SHA256 and blake2 hash files in `export/`
|
||||||
|
- Sign all files with GPG in `export/`
|
||||||
|
- Upload artifacts to GitHub Actions **manually**
|
||||||
|
|
||||||
|
### SHA256 Hash Verification
|
||||||
|
|
||||||
|
!!! Note "**How it works**"
|
||||||
|
|
||||||
|
- Each PDF gets a unique SHA256 hash calculated at build time
|
||||||
|
- Hash stored in `.sha256` files alongside the PDFs
|
||||||
|
- Combined `sha256sum.txt` for batch verification
|
||||||
|
|
||||||
|
### GPG Signature Verification
|
||||||
|
|
||||||
|
**Purpose:** Verify authenticity and prevent tampering
|
||||||
|
|
||||||
|
!!! Note "How it works"
|
||||||
|
|
||||||
|
- Detached signatures created for each PDF and hash file
|
||||||
|
- Public keys available in `/pgp/` directory
|
||||||
|
|
||||||
|
**Verification command:**
|
||||||
|
```bash
|
||||||
|
gpg --import pgp/anonymousplanet-master.asc
|
||||||
|
gpg --verify export/thgtoa.pdf.sig export/thgtoa.pdf
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*This workflow is designed for security-conscious users who need to verify the authenticity and integrity of downloaded documents.*
|
||||||
@@ -1,193 +0,0 @@
|
|||||||
# Development
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
This repository now includes an automated workflow that handles PDF generation, verification, and distribution with the following features:
|
|
||||||
|
|
||||||
??? Note "How the pipeline works"
|
|
||||||
|
|
||||||
1. **Automatic PDF Generation** - Builds both light and dark mode PDFs from MkDocs source
|
|
||||||
2. **SHA256 Hash Generation** - Creates hash files for integrity verification
|
|
||||||
3. **GPG Signature Signing** - Signs all PDFs and hash files with repository GPG key
|
|
||||||
4. **VirusTotal Scanning** - Automatically scans PDFs and updates release notes
|
|
||||||
5. **Release Automation** - Packages everything into GitHub releases
|
|
||||||
|
|
||||||
## Workflow Architecture
|
|
||||||
|
|
||||||
### 1. Build PDF Workflow (`build-pdf.yml`)
|
|
||||||
|
|
||||||
**Trigger:** Push to main, pull requests, or manual dispatch
|
|
||||||
|
|
||||||
??? Note "Steps"
|
|
||||||
|
|
||||||
- Checkout repository
|
|
||||||
- Set up Python 3.13 and MkDocs Material
|
|
||||||
- Install Chromium browser
|
|
||||||
- Generate both light and dark mode PDFs
|
|
||||||
- Create SHA256 hash files
|
|
||||||
- Sign all files with GPG
|
|
||||||
- Upload artifacts to GitHub Actions
|
|
||||||
- Publish release
|
|
||||||
|
|
||||||
### 2. VirusTotal Scan Workflow (`vt-scan.yml`)
|
|
||||||
|
|
||||||
**Trigger:** Push to main, tags, or manual dispatch (runs after build-pdf)
|
|
||||||
|
|
||||||
??? Note "Steps"
|
|
||||||
|
|
||||||
- Download PDF artifacts from build workflow
|
|
||||||
- Scan both PDFs with VirusTotal API
|
|
||||||
- Extract scan results and generate report links
|
|
||||||
- Update release notes with VT scan status and URLs
|
|
||||||
|
|
||||||
## File Structure
|
|
||||||
|
|
||||||
After a successful build, the repository will contain:
|
|
||||||
|
|
||||||
```
|
|
||||||
.../
|
|
||||||
├── export/
|
|
||||||
│ ├── thgtoa.pdf # Light mode PDF
|
|
||||||
│ ├── thgtoa-dark.pdf # Dark mode PDF
|
|
||||||
│ ├── thgtoa.pdf.sig # GPG signature (light)
|
|
||||||
│ └── thgtoa-dark.pdf.sig # GPG signature (dark)
|
|
||||||
├── thgtoa.pdf.sha256 # Hash file (light)
|
|
||||||
├── thgtoa-dark.pdf.sha256 # Hash file (dark)
|
|
||||||
├── sha256sum-light.txt # Combined hash file
|
|
||||||
└── scripts/
|
|
||||||
├── build_guide_pdf.py # PDF generation script
|
|
||||||
└── verify_pdf.py # Verification utility
|
|
||||||
```
|
|
||||||
|
|
||||||
## Security Features
|
|
||||||
|
|
||||||
### 1. SHA256 Hash Verification
|
|
||||||
|
|
||||||
**Purpose:** Ensure file integrity during download/transit
|
|
||||||
|
|
||||||
**How it works:**
|
|
||||||
- Each PDF gets a unique SHA256 hash calculated at build time
|
|
||||||
- Hash stored in `.sha256` files alongside the PDFs
|
|
||||||
- Combined `sha256sum-light.txt` for batch verification
|
|
||||||
|
|
||||||
**Verification command:**
|
|
||||||
```bash
|
|
||||||
sha256sum -c sha256sum-light.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. GPG Signature Verification
|
|
||||||
|
|
||||||
**Purpose:** Verify authenticity and prevent tampering
|
|
||||||
|
|
||||||
??? Note "How it works"
|
|
||||||
|
|
||||||
- Detached signatures created for each PDF and hash file
|
|
||||||
- Public keys available in `/pgp/` directory
|
|
||||||
|
|
||||||
**Verification command:**
|
|
||||||
```bash
|
|
||||||
gpg --import pgp/anonymousplanet-master.asc
|
|
||||||
gpg --verify export/thgtoa.pdf.sig export/thgtoa.pdf
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. VirusTotal Integration
|
|
||||||
|
|
||||||
**Purpose:** Malware detection and security scanning
|
|
||||||
|
|
||||||
??? Note "How it works"
|
|
||||||
|
|
||||||
- Automatic scan of all generated PDFs
|
|
||||||
- Results published in release notes with direct links
|
|
||||||
- Provides third-party validation of file safety
|
|
||||||
|
|
||||||
## Usage Examples
|
|
||||||
|
|
||||||
### Local Development
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build PDFs locally
|
|
||||||
python scripts/build_guide_pdf.py --both
|
|
||||||
|
|
||||||
# Verify hashes
|
|
||||||
python scripts/verify_pdf.py --hashes
|
|
||||||
|
|
||||||
# Verify signatures (requires GPG installed)
|
|
||||||
python scripts/verify_pdf.py --signatures
|
|
||||||
|
|
||||||
# Full verification with VirusTotal check
|
|
||||||
export VT_API_KEY=your_api_key
|
|
||||||
python scripts/verify_pdf.py --all
|
|
||||||
```
|
|
||||||
|
|
||||||
### CI/CD Verification
|
|
||||||
|
|
||||||
The workflows automatically verify everything during the build process. To manually trigger:
|
|
||||||
|
|
||||||
1. Go to Actions tab
|
|
||||||
2. Select "Build guide PDF" or "VirusTotal Scan"
|
|
||||||
3. Click "Run workflow"
|
|
||||||
4. Download artifacts from successful run
|
|
||||||
|
|
||||||
## Release Process
|
|
||||||
|
|
||||||
When you create a tag (e.g., `v1.0.0`):
|
|
||||||
|
|
||||||
1. Push the tag: `git push origin v1.0.0`
|
|
||||||
2. Build PDF workflow triggers automatically
|
|
||||||
3. VirusTotal scan workflow runs after build completes
|
|
||||||
4. Both workflows update/create GitHub release with:
|
|
||||||
- Light and dark mode PDFs
|
|
||||||
- GPG signatures for all files
|
|
||||||
- Hash files for verification
|
|
||||||
- Release notes with VT scan results
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Common Issues
|
|
||||||
|
|
||||||
**GPG signing fails:**
|
|
||||||
- Check that `GPG_PRIVATE_KEY` is in ASCII armor format
|
|
||||||
- Verify passphrase is correct
|
|
||||||
- Ensure key has signing capability
|
|
||||||
|
|
||||||
**Hash mismatch after download:**
|
|
||||||
- Re-download the file (corruption during transfer)
|
|
||||||
- Verify you're using the correct hash file
|
|
||||||
- Check disk integrity
|
|
||||||
|
|
||||||
**VirusTotal scan fails:**
|
|
||||||
- Verify `VT_API_KEY` is set correctly
|
|
||||||
- Check API quota limits (free tier: 4 requests/minute)
|
|
||||||
- Ensure PDF files exist before scanning
|
|
||||||
|
|
||||||
### Debug Mode
|
|
||||||
|
|
||||||
Enable verbose output by adding to workflow:
|
|
||||||
```yaml
|
|
||||||
- name: Debug
|
|
||||||
run: |
|
|
||||||
echo "Current directory:" && pwd
|
|
||||||
echo "Files in export:" && ls -la export/
|
|
||||||
echo "Hash file contents:" && cat sha256sum-light.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
## Best Practices
|
|
||||||
|
|
||||||
1. **Always verify signatures** before opening PDFs from untrusted sources
|
|
||||||
2. **Check VirusTotal results** for any suspicious detections
|
|
||||||
3. **Keep GPG keys secure** - never commit private keys to repository
|
|
||||||
4. **Monitor API usage** for VirusTotal to avoid rate limiting
|
|
||||||
5. **Test locally** before pushing tags to production
|
|
||||||
|
|
||||||
## Future Enhancements
|
|
||||||
|
|
||||||
Potential improvements:
|
|
||||||
- Multi-signature support (multiple maintainers)
|
|
||||||
- Automated changelog generation with hashes
|
|
||||||
- Cross-platform signature verification scripts
|
|
||||||
- Integration with additional malware scanners
|
|
||||||
- Automatic mirror updates with verified files
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
*This workflow is designed for security-conscious users who need to verify the authenticity and integrity of downloaded documents.*
|
|
||||||
+1
-1
@@ -7,7 +7,7 @@ schema:
|
|||||||
"@id": https://www.anonymousplanet.org/
|
"@id": https://www.anonymousplanet.org/
|
||||||
name: Anonymous Planet
|
name: Anonymous Planet
|
||||||
url: https://www.anonymousplanet.org/guide/
|
url: https://www.anonymousplanet.org/guide/
|
||||||
logo: ../media/favicon.ico
|
logo: ../media/profile.png
|
||||||
sameAs:
|
sameAs:
|
||||||
- https://github.com/Anon-Planet
|
- https://github.com/Anon-Planet
|
||||||
- https://opencollective.com/anonymousplanetorg
|
- https://opencollective.com/anonymousplanetorg
|
||||||
|
|||||||
+4
-5
@@ -7,7 +7,7 @@ schema:
|
|||||||
"@id": https://www.anonymousplanet.org/
|
"@id": https://www.anonymousplanet.org/
|
||||||
name: Anonymous Planet
|
name: Anonymous Planet
|
||||||
url: https://www.anonymousplanet.org/authors/
|
url: https://www.anonymousplanet.org/authors/
|
||||||
logo: ../media/favicon.png
|
logo: ../media/profile.png
|
||||||
sameAs:
|
sameAs:
|
||||||
- https://github.com/Anon-Planet
|
- https://github.com/Anon-Planet
|
||||||
- https://opencollective.com/anonymousplanetorg
|
- https://opencollective.com/anonymousplanetorg
|
||||||
@@ -18,13 +18,12 @@ schema:
|
|||||||
|
|
||||||
**9FA5 436D 0EE3 6098 5157 3825 17EC A05F 768D EDF6**
|
**9FA5 436D 0EE3 6098 5157 3825 17EC A05F 768D EDF6**
|
||||||
|
|
||||||
This is the master signing key fingerprint for Anonymous Planet.
|
You'll use it to [**verify the checksum** and **GPG signature** of all files for authenticity.](verify/index.md)
|
||||||
You'll use it to [**verify the checksum** and **GPG signature** of all files for authenticity.](verify/index.md)
|
Please share this project if you enjoy it and you think it might be useful to others.
|
||||||
Please share this project if you enjoy it and you think it might be useful to others.
|
|
||||||
|
|
||||||
{ align=right }
|
{ align=right }
|
||||||
|
|
||||||
Anonymous Planet is a collective of volunteers and contributors. No one person is considered more valuable than another, and no one person should be viewed as having "more impact" on Anonymous Planet.
|
Anonymous Planet is a collective of volunteers.
|
||||||
|
|
||||||
??? person "Das Kolburn"
|
??? person "Das Kolburn"
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ schema:
|
|||||||
"@id": https://www.anonymousplanet.org/
|
"@id": https://www.anonymousplanet.org/
|
||||||
name: Anonymous Planet
|
name: Anonymous Planet
|
||||||
url: https://www.anonymousplanet.org/mirrors/
|
url: https://www.anonymousplanet.org/mirrors/
|
||||||
logo: ../media/favicon.png
|
logo: ../media/profile.png
|
||||||
sameAs:
|
sameAs:
|
||||||
- https://github.com/Anon-Planet
|
- https://github.com/Anon-Planet
|
||||||
- https://opencollective.com/anonymousplanetorg
|
- https://opencollective.com/anonymousplanetorg
|
||||||
@@ -27,7 +27,7 @@ schema:
|
|||||||
|
|
||||||
!!! Note "PDF export (single file)"
|
!!! Note "PDF export (single file)"
|
||||||
|
|
||||||
The guide is also available as a **PDF** (images and layout preserved). It is built automatically in GitHub Actions: open [**Build guide PDF**](https://github.com/Anon-Planet/thgtoa/actions/workflows/build-pdf.yml) on the [**source repository**](https://github.com/Anon-Planet/thgtoa), pick a successful run, and download the **`thgtoa`** and **`thgtoa-dark`** artifacts. You can start a fresh build anytime (**Actions** → **Build guide PDF** → **Run workflow**).
|
The guide is also available as a **PDF** (images and layout preserved). It is built automatically in GitHub Actions: open [**Build guide PDF**](https://github.com/Anon-Planet/thgtoa/actions/workflows/build-sign-release.yml) on the [**source repository**](https://github.com/Anon-Planet/thgtoa), pick a successful run, and download the **`thgtoa`** and **`thgtoa-dark`** artifacts. You can start a fresh build anytime (**Actions** → **Build guide PDF** → **Run workflow**).
|
||||||
|
|
||||||
To produce the same file locally, clone the repository and run `python3 scripts/build_guide_pdf.py --both` (Python, [MkDocs Material](https://squidfunk.github.io/mkdocs-material/getting-started/), and **Google Chrome** or **Microsoft Edge** required). More detail is in the [repository README](https://github.com/Anon-Planet/thgtoa#ways-to-read-or-export-the-guide).
|
To produce the same file locally, clone the repository and run `python3 scripts/build_guide_pdf.py --both` (Python, [MkDocs Material](https://squidfunk.github.io/mkdocs-material/getting-started/), and **Google Chrome** or **Microsoft Edge** required). More detail is in the [repository README](https://github.com/Anon-Planet/thgtoa#ways-to-read-or-export-the-guide).
|
||||||
|
|
||||||
|
|||||||
@@ -62,9 +62,12 @@ gpg --verify export/thgtoa-dark.pdf.sig export/thgtoa-dark.pdf
|
|||||||
|
|
||||||
Expected output for successful verification:
|
Expected output for successful verification:
|
||||||
```
|
```
|
||||||
gpg: Signature made [date]
|
gpg: Signature made Mon 20 Apr 2026 01:46:40 AM EDT
|
||||||
gpg: using RSA key [key-id]
|
gpg: using EDDSA key 9FA5436D0EE360985157382517ECA05F768DEDF6
|
||||||
gpg: Good signature from "[owner]"
|
gpg: Good signature from "Anonymous Planet Master Signing Key" [unknown]
|
||||||
|
gpg: WARNING: This key is not certified with a trusted signature!
|
||||||
|
gpg: There is no indication that the signature belongs to the owner.
|
||||||
|
Primary key fingerprint: 9FA5 436D 0EE3 6098 5157 3825 17EC A05F 768D EDF6
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 3. Check VirusTotal Status
|
#### 3. Check VirusTotal Status
|
||||||
@@ -114,7 +117,7 @@ The GitHub Actions workflows automatically:
|
|||||||
|
|
||||||
## Key Information
|
## Key Information
|
||||||
|
|
||||||
**Signing Key:** Anonymous Planet Master Key
|
**Signing Key:** Anonymous Planet Master Signing Key ("MSK")
|
||||||
**Key ID:** See `pgp/anonymousplanet-master.asc` for details
|
**Key ID:** See `pgp/anonymousplanet-master.asc` for details
|
||||||
**Fingerprint:** Verify from the repository's official documentation
|
**Fingerprint:** Verify from the repository's official documentation
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -0,0 +1,8 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iJEEABYKADkWIQSfpUNtDuNgmFFXOCUX7KBfdo3t9gUCaeXaqxsUgAAAAAAEAA5t
|
||||||
|
YW51MiwyLjUrMS4xMiwyLDIACgkQF+ygX3aN7fY6QAD/YCGJqs9HiRllFrF9EluE
|
||||||
|
Ga4XUEQ/R6Q2zc+X6lX856sBAJIpxeMxUmMUXyr3xBAHxUf5eV+nQYkQQMKI81L1
|
||||||
|
x8gL
|
||||||
|
=VX6l
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
f212d0425b38d5cd10da6dc804b60f143da23d4b07051aae31d0966082519b300af0e1c423683e0223738b33b138c687232b1c8bd68cf643777bbc5b588152bd ./export/thgtoa-dark.pdf
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iJEEABYKADkWIQSfpUNtDuNgmFFXOCUX7KBfdo3t9gUCaeXaqxsUgAAAAAAEAA5t
|
||||||
|
YW51MiwyLjUrMS4xMiwyLDIACgkQF+ygX3aN7fbdDgEAoSslLR47ydW/3r1wJOPY
|
||||||
|
X/waLkVbkGZpHqwd4RjywwcA/3B7Ci+jUg+yP5TRsuChagEhwyO5vw2DxSlUGoB4
|
||||||
|
+ksH
|
||||||
|
=2ja9
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iJEEABYKADkWIQSfpUNtDuNgmFFXOCUX7KBfdo3t9gUCaeXaqxsUgAAAAAAEAA5t
|
||||||
|
YW51MiwyLjUrMS4xMiwyLDIACgkQF+ygX3aN7faErgD/Svj1G+B7gmrZQ6AsLZ5J
|
||||||
|
HfeldxjmrXE99dig1iHtl5IBAMndZZb+95TO03IZ9eLGfYuyTz4GCUanmftsY9yv
|
||||||
|
LAIN
|
||||||
|
=MEd0
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
Binary file not shown.
@@ -0,0 +1,8 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iJEEABYKADkWIQSfpUNtDuNgmFFXOCUX7KBfdo3t9gUCaeXaqxsUgAAAAAAEAA5t
|
||||||
|
YW51MiwyLjUrMS4xMiwyLDIACgkQF+ygX3aN7favvgEAvFFSB5NrsrKMYvGG5ZYB
|
||||||
|
iLIyt8Sn1rZmlVkibssMPq0BAImpZe8S7hWNkbukyEC4sLbKiOYvjbVipQHnrIUV
|
||||||
|
xPMH
|
||||||
|
=0hnj
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
436ed0df78c299f95b8d5ff94f43f26ec2e7825d92d843fc15419630d55ed5e0c98485e738c12715a2b6242633faae38e8a98935b361d44ddde97a1692cb01a1 ./export/thgtoa.pdf
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iJEEABYKADkWIQSfpUNtDuNgmFFXOCUX7KBfdo3t9gUCaeXaqxsUgAAAAAAEAA5t
|
||||||
|
YW51MiwyLjUrMS4xMiwyLDIACgkQF+ygX3aN7fatsgEAixDzH+zTnKYMEx3sikWp
|
||||||
|
dsNTiHTU6wJY/brVJIU879UBAJntBIq72vqwKtMb/ZlVvomdDvKVllZw8ZsYBz1n
|
||||||
|
aTkM
|
||||||
|
=vkgy
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iJEEABYKADkWIQSfpUNtDuNgmFFXOCUX7KBfdo3t9gUCaeXaqxsUgAAAAAAEAA5t
|
||||||
|
YW51MiwyLjUrMS4xMiwyLDIACgkQF+ygX3aN7faAGQEAyEhVKrRoXIsV3E5f1FZg
|
||||||
|
8fcsmbxCnKBqxichCkf0dWYBAIvbI146mQLHaNqLDaTIqCUQbkq1aE/YMFDGykUG
|
||||||
|
ngsJ
|
||||||
|
=/0RY
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
## VirusTotal Scan Results
|
||||||
|
|
||||||
|
**Scan Date:** 2026-04-19 01:48 UTC
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### thgtoa.pdf
|
||||||
|
- **SHA256 Hash:** `f82f6f53319315568fc2524b4eaf01126fe52356a20363cd358ad5977388ba28`
|
||||||
|
- **VirusTotal Report:** VT_API_KEY not configured, scan skipped
|
||||||
|
|
||||||
|
### thgtoa-dark.pdf
|
||||||
|
- **SHA256 Hash:** `94a0c8e3b81b0aeeb921029a41713d81b836da893a9bc9f905ca7296e82bd70f`
|
||||||
|
- **VirusTotal Report:** VT_API_KEY not configured, scan skipped
|
||||||
|
|
||||||
|
---
|
||||||
|
*Scan performed automatically by GitHub Actions*
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iJEEABYKADkWIQSfpUNtDuNgmFFXOCUX7KBfdo3t9gUCaeXaqxsUgAAAAAAEAA5t
|
||||||
|
YW51MiwyLjUrMS4xMiwyLDIACgkQF+ygX3aN7fYpCgEA209U3QewChp7mdrrFjH1
|
||||||
|
CaBMIk2sCHwRMCcmbMDkNTAA/RIchAKex13ZjZWC9xsJpZEktvBENFsQLsNPReqR
|
||||||
|
UZ8C
|
||||||
|
=TYsa
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
+9
-4
@@ -9,6 +9,7 @@ repo_name: ""
|
|||||||
#edit_uri: ""
|
#edit_uri: ""
|
||||||
theme:
|
theme:
|
||||||
name: material
|
name: material
|
||||||
|
locale: en
|
||||||
favicon: media/profile.png
|
favicon: media/profile.png
|
||||||
icon:
|
icon:
|
||||||
logo: material/bird
|
logo: material/bird
|
||||||
@@ -17,6 +18,8 @@ theme:
|
|||||||
text: Public Sans
|
text: Public Sans
|
||||||
code: Liberation Mono
|
code: Liberation Mono
|
||||||
features:
|
features:
|
||||||
|
- navigation.instant
|
||||||
|
- navigation.instant.prefetch
|
||||||
- navigation.tabs
|
- navigation.tabs
|
||||||
- navigation.sections
|
- navigation.sections
|
||||||
- toc.integrate
|
- toc.integrate
|
||||||
@@ -122,17 +125,19 @@ markdown_extensions:
|
|||||||
toc_depth: 3
|
toc_depth: 3
|
||||||
|
|
||||||
nav:
|
nav:
|
||||||
- Home: index.md
|
- Welcome: index.md
|
||||||
- About: about/index.md
|
- About: about/index.md
|
||||||
- Verify: verify/index.md
|
- Verify: verify/index.md
|
||||||
- Guide:
|
- Guide:
|
||||||
- guide/index.md
|
- guide/index.md
|
||||||
- Workflow Documentation: guide/dev-workflow.md
|
- Code:
|
||||||
- Code: code/index.md
|
- code/index.md
|
||||||
|
- Develop: code/develop.md
|
||||||
- Contribute: contribute/index.md
|
- Contribute: contribute/index.md
|
||||||
- Constitution: constitution/index.md
|
- Constitution: constitution/index.md
|
||||||
- Mirrors: mirrors/index.md
|
- Mirrors: mirrors/index.md
|
||||||
- Twitter: twitter/index.md
|
- Twitter: twitter/index.md
|
||||||
|
- Releases: changelog/index.md
|
||||||
|
|
||||||
copyright: |
|
copyright: |
|
||||||
© 2023-2026 <a href="https://anonymousplanet.org/" target="_blank" rel="noopener">Anonymous Planet</a>
|
<a href="https://anonymousplanet.org/">The Hitchhiker's Guide</a> ©2023-2026 by <a href="https://psa.anonymousplanet.org/">Anonymous Planet</a> is licensed under <a href="https://creativecommons.org/licenses/by-nc/4.0/">CC BY-NC 4.0</a><img src="https://mirrors.creativecommons.org/presskit/icons/cc.svg" alt="" style="max-width: 1em;max-height:1em;margin-left: .2em;"><img src="https://mirrors.creativecommons.org/presskit/icons/by.svg" alt="" style="max-width: 1em;max-height:1em;margin-left: .2em;"><img src="https://mirrors.creativecommons.org/presskit/icons/nc.svg" alt="" style="max-width: 1em;max-height:1em;margin-left: .2em;"></a>
|
||||||
|
|||||||
@@ -177,13 +177,13 @@ def main() -> int:
|
|||||||
"--pdf-light",
|
"--pdf-light",
|
||||||
type=Path,
|
type=Path,
|
||||||
default=root / "export" / "thgtoa.pdf",
|
default=root / "export" / "thgtoa.pdf",
|
||||||
help="Output PDF path for light mode (default: ./export/guide.pdf)",
|
help="Output PDF path for light mode (default: ./export/thgtoa.pdf)",
|
||||||
)
|
)
|
||||||
ap.add_argument(
|
ap.add_argument(
|
||||||
"--pdf-dark",
|
"--pdf-dark",
|
||||||
type=Path,
|
type=Path,
|
||||||
default=root / "export" / "thgtoa-dark.pdf",
|
default=root / "export" / "thgtoa-dark.pdf",
|
||||||
help="Output PDF path for dark mode (default: ./export/guide-dark.pdf)",
|
help="Output PDF path for dark mode (default: ./export/thgtoa-dark.pdf)",
|
||||||
)
|
)
|
||||||
ap.add_argument("--skip-mkdocs", action="store_true", help="Reuse existing site dir; only run print-to-pdf.")
|
ap.add_argument("--skip-mkdocs", action="store_true", help="Reuse existing site dir; only run print-to-pdf.")
|
||||||
ap.add_argument("--dark-mode", action="store_true", help="Generate dark mode PDF only")
|
ap.add_argument("--dark-mode", action="store_true", help="Generate dark mode PDF only")
|
||||||
|
|||||||
@@ -169,44 +169,12 @@ GitHub repository:
|
|||||||
|
|
||||||
3. VT_API_KEY (optional but recommended)
|
3. VT_API_KEY (optional but recommended)
|
||||||
- VirusTotal API key for malware scanning
|
- VirusTotal API key for malware scanning
|
||||||
- Get a free key at: https://www.virustotal.com/gui/join-us
|
|
||||||
|
|
||||||
|
|
||||||
HOW TO ADD SECRETS:
|
|
||||||
|
|
||||||
1. Go to your repository on GitHub
|
|
||||||
2. Click 'Settings' → 'Secrets and variables' → 'Actions'
|
|
||||||
3. Click 'New repository secret' for each secret below:
|
|
||||||
|
|
||||||
Secret Name | Value Format
|
|
||||||
---------------------|--------------------------------------------------
|
|
||||||
GPG_PRIVATE_KEY | Paste the entire ASCII armored key (BEGIN PGP...)
|
|
||||||
GPG_PASSPHRASE | Your key's passphrase (no special characters issues)
|
|
||||||
VT_API_KEY | Your VirusTotal API key
|
|
||||||
|
|
||||||
|
|
||||||
VERIFYING YOUR SETUP:
|
|
||||||
|
|
||||||
After adding secrets, you can test by:
|
|
||||||
1. Going to 'Actions' tab
|
|
||||||
2. Selecting 'Build guide PDF' workflow
|
|
||||||
3. Clicking 'Run workflow'
|
|
||||||
4. Checking if the workflow completes successfully
|
|
||||||
|
|
||||||
|
|
||||||
TROUBLESHOOTING:
|
TROUBLESHOOTING:
|
||||||
|
|
||||||
- If GPG signing fails: Check that your key has signing capability ('s' flag)
|
- If GPG signing fails: Check that your key has signing capability ('s' flag)
|
||||||
- If passphrase is wrong: Verify you're using the correct passphrase
|
- If passphrase is wrong: Verify you're using the correct passphrase
|
||||||
- If VT scan fails: Ensure API key is valid and within rate limits
|
- If VT scan fails: Ensure API key is valid and within rate limits
|
||||||
|
|
||||||
|
|
||||||
SECURITY NOTES:
|
|
||||||
|
|
||||||
⚠ NEVER share your private key or passphrase publicly
|
|
||||||
⚠ Always use repository secrets, never hardcode in scripts
|
|
||||||
⚠ Rotate keys periodically if compromised
|
|
||||||
⚠ Use strong passphrases (12+ characters recommended)
|
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
|
||||||
@@ -220,8 +188,6 @@ def main() -> int:
|
|||||||
print("⚠ WARNING: GPG is not installed or not in PATH")
|
print("⚠ WARNING: GPG is not installed or not in PATH")
|
||||||
print("Please install GPG before continuing:")
|
print("Please install GPG before continuing:")
|
||||||
print(" - Linux: sudo apt install gnupg")
|
print(" - Linux: sudo apt install gnupg")
|
||||||
print(" - macOS: brew install gnupg")
|
|
||||||
print(" - Windows: https://www.gpg4win.org/")
|
|
||||||
print("\nContinuing anyway...")
|
print("\nContinuing anyway...")
|
||||||
|
|
||||||
# List available keys
|
# List available keys
|
||||||
@@ -313,7 +279,7 @@ To get your private key for the GPG_PRIVATE_KEY secret:
|
|||||||
print("1. Export your private key (see instructions above)")
|
print("1. Export your private key (see instructions above)")
|
||||||
print("2. Add all three secrets to GitHub repository settings")
|
print("2. Add all three secrets to GitHub repository settings")
|
||||||
print("3. Test the workflow by triggering a manual build")
|
print("3. Test the workflow by triggering a manual build")
|
||||||
print("\nFor more information, see: docs/guide/pdf-workflow.md\n")
|
print("\nFor more information, see: docs/guide/dev-workflow.md\n")
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|||||||
+4
-12
@@ -26,11 +26,9 @@ import subprocess
|
|||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
def repo_root() -> Path:
|
def repo_root() -> Path:
|
||||||
return Path(__file__).resolve().parent.parent
|
return Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
|
||||||
def calculate_sha256(file_path: Path) -> str:
|
def calculate_sha256(file_path: Path) -> str:
|
||||||
"""Calculate SHA256 hash of a file."""
|
"""Calculate SHA256 hash of a file."""
|
||||||
sha256_hash = hashlib.sha256()
|
sha256_hash = hashlib.sha256()
|
||||||
@@ -39,7 +37,6 @@ def calculate_sha256(file_path: Path) -> str:
|
|||||||
sha256_hash.update(byte_block)
|
sha256_hash.update(byte_block)
|
||||||
return sha256_hash.hexdigest()
|
return sha256_hash.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
def verify_hash(file_path: Path, expected_hash: str) -> bool:
|
def verify_hash(file_path: Path, expected_hash: str) -> bool:
|
||||||
"""Verify file hash against expected value."""
|
"""Verify file hash against expected value."""
|
||||||
actual_hash = calculate_sha256(file_path)
|
actual_hash = calculate_sha256(file_path)
|
||||||
@@ -50,7 +47,6 @@ def verify_hash(file_path: Path, expected_hash: str) -> bool:
|
|||||||
print(f" Actual: {actual_hash}")
|
print(f" Actual: {actual_hash}")
|
||||||
return is_valid
|
return is_valid
|
||||||
|
|
||||||
|
|
||||||
def verify_signature(file_path: Path, sig_file: Path) -> bool:
|
def verify_signature(file_path: Path, sig_file: Path) -> bool:
|
||||||
"""Verify GPG signature of a file."""
|
"""Verify GPG signature of a file."""
|
||||||
if not sig_file.exists():
|
if not sig_file.exists():
|
||||||
@@ -81,7 +77,6 @@ def verify_signature(file_path: Path, sig_file: Path) -> bool:
|
|||||||
print("⚠ WARNING: GPG not installed. Skipping signature verification.")
|
print("⚠ WARNING: GPG not installed. Skipping signature verification.")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def verify_from_hash_file(file_path: Path, hash_file: Path) -> bool:
|
def verify_from_hash_file(file_path: Path, hash_file: Path) -> bool:
|
||||||
"""Verify file hash from a hash file."""
|
"""Verify file hash from a hash file."""
|
||||||
if not hash_file.exists():
|
if not hash_file.exists():
|
||||||
@@ -102,7 +97,6 @@ def verify_from_hash_file(file_path: Path, hash_file: Path) -> bool:
|
|||||||
|
|
||||||
return verify_hash(file_path, expected_hash)
|
return verify_hash(file_path, expected_hash)
|
||||||
|
|
||||||
|
|
||||||
def check_virustotal(file_hash: str, api_key: str | None = None) -> dict | None:
|
def check_virustotal(file_hash: str, api_key: str | None = None) -> dict | None:
|
||||||
"""Check VirusTotal scan status for a file hash."""
|
"""Check VirusTotal scan status for a file hash."""
|
||||||
if not api_key:
|
if not api_key:
|
||||||
@@ -127,9 +121,9 @@ def check_virustotal(file_hash: str, api_key: str | None = None) -> dict | None:
|
|||||||
|
|
||||||
if stats:
|
if stats:
|
||||||
print(f" Malicious: {stats.get('malicious', 0)}")
|
print(f" Malicious: {stats.get('malicious', 0)}")
|
||||||
print(f" Suspicious: {stats.get('suspicious', 0)}")
|
print(f" Suspicious: {stats.get('suspicious', 0)}")
|
||||||
print(f" Undetected: {stats.get('undetected', 0)}")
|
print(f" Undetected: {stats.get('undetected', 0)}")
|
||||||
print(f" Clean: {stats.get('harmless', 0)}")
|
print(f" Clean: {stats.get('harmless', 0)}")
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@@ -137,7 +131,6 @@ def check_virustotal(file_hash: str, api_key: str | None = None) -> dict | None:
|
|||||||
print(f"⚠ ERROR checking VirusTotal: {e}")
|
print(f"⚠ ERROR checking VirusTotal: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
def main() -> int:
|
||||||
root = repo_root()
|
root = repo_root()
|
||||||
ap = argparse.ArgumentParser(description="Verify PDF files (hashes, signatures, VT).")
|
ap = argparse.ArgumentParser(description="Verify PDF files (hashes, signatures, VT).")
|
||||||
@@ -158,7 +151,7 @@ def main() -> int:
|
|||||||
ap.add_argument(
|
ap.add_argument(
|
||||||
"--hash-file",
|
"--hash-file",
|
||||||
type=Path,
|
type=Path,
|
||||||
default=root / "sha256sum-light.txt",
|
default=root / "export" / "thgtoa.pdf.sha256",
|
||||||
help="Hash file to verify against",
|
help="Hash file to verify against",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -217,6 +210,5 @@ def main() -> int:
|
|||||||
print("✗ Some verifications FAILED")
|
print("✗ Some verifications FAILED")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
raise SystemExit(main())
|
raise SystemExit(main())
|
||||||
|
|||||||
Reference in New Issue
Block a user