name: 🚀 Release # Manual only — run this deliberately after build and sign are confirmed good. # Provide the 02-sign.yml run ID to pull artifacts from. The release tag is # automatically passed to the tag input. Exports "inputs.version" to $TAG. on: workflow_dispatch: inputs: sign_run_id: description: '02-sign.yml run ID to pull signatures and PDFs from' required: true type: string prerelease: description: 'Mark as pre-release?' required: false default: false type: boolean version: description: 'Version string to record (e.g. v1.2.4) — required' required: true type: string permissions: contents: write # create releases and tags actions: read # download artifacts from other runs jobs: release: name: Publish GitHub Release runs-on: ubuntu-latest steps: - name: 🛠️ Checkout (for pgp/) uses: actions/checkout@v4 with: fetch-depth: 0 sparse-checkout: pgp # Download artifacts from the specified sign run - name: 📥 Download signatures artifact uses: actions/download-artifact@v4 with: name: signatures path: release/ run-id: ${{ inputs.sign_run_id }} github-token: ${{ secrets.GITHUB_TOKEN }} - name: 📥 Download signed PDFs artifact uses: actions/download-artifact@v4 with: name: pdfs-signed path: release/ run-id: ${{ inputs.sign_run_id }} github-token: ${{ secrets.GITHUB_TOKEN }} - name: 📋 List release assets run: ls -lh release/ # Read hashes for the release body - name: "#️⃣ Read hashes" id: hashes run: | read_hash() { cat "release/$1" 2>/dev/null || echo "(not built)"; } echo "light_sha256=$(read_hash thgtoa.pdf.sha256)" >> $GITHUB_OUTPUT echo "dark_sha256=$(read_hash thgtoa-dark.pdf.sha256)" >> $GITHUB_OUTPUT echo "light_b2=$(read_hash thgtoa.pdf.b2sum)" >> $GITHUB_OUTPUT echo "dark_b2=$(read_hash thgtoa-dark.pdf.b2sum)" >> $GITHUB_OUTPUT # VirusTotal - name: 🦠 Upload PDFs to VirusTotal id: vt uses: crazy-max/ghaction-virustotal@v5 with: vt_api_key: ${{ secrets.VT_API_KEY }} files: | release/thgtoa.pdf release/thgtoa-dark.pdf - name: 🔗 Build VT report URLs id: vt_urls run: | light_hash=$(cat release/thgtoa.pdf.sha256 2>/dev/null || echo "") dark_hash=$(cat release/thgtoa-dark.pdf.sha256 2>/dev/null || echo "") if [ -n "$light_hash" ]; then echo "light_vt=https://www.virustotal.com/gui/file/${light_hash}" >> $GITHUB_OUTPUT else echo "light_vt=(not built)" >> $GITHUB_OUTPUT fi if [ -n "$dark_hash" ]; then echo "dark_vt=https://www.virustotal.com/gui/file/${dark_hash}" >> $GITHUB_OUTPUT else echo "dark_vt=(not built)" >> $GITHUB_OUTPUT fi # Generate release tag — timestamp + short SHA, always unique - name: 🏷️ Generate release tag id: tag run: | SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7) DATE=$(date -u +'%Y%m%d') TAG="${{ inputs.version }}" NAME="Release ${DATE} (${SHORT_SHA})" echo "tag=$TAG" >> $GITHUB_OUTPUT echo "name=$NAME" >> $GITHUB_OUTPUT echo "Tag: $TAG" # Create GitHub Release - name: 🚀 Create GitHub Release uses: softprops/action-gh-release@v2 with: tag_name: ${{ steps.tag.outputs.tag }} name: ${{ steps.tag.outputs.name }} prerelease: ${{ inputs.prerelease || false }} draft: true fail_on_unmatched_files: false body: | ## 📖 The Hitchhiker's Guide to Online Anonymity Built from [`${{ inputs.version }}`](${{ github.server_url }}/${{ github.repository }}/releases/tag/${{ inputs.version }}). --- ### 📄 Release assets | File | Description | |------|-------------| | `thgtoa.pdf` | Light mode PDF | | `thgtoa-dark.pdf` | Dark mode PDF (hacker theme) | | `sha256sums.txt` | SHA-256 checksums (both files) | | `b2sums.txt` | BLAKE2b checksums (both files) | | `thgtoa.pdf.sha256` | SHA-256 — light PDF | | `thgtoa-dark.pdf.sha256` | SHA-256 — dark PDF | | `thgtoa.pdf.b2sum` | BLAKE2b — light PDF | | `thgtoa-dark.pdf.b2sum` | BLAKE2b — dark PDF | | `*.asc` | GPG detached signatures (ASCII armor) | --- ### #️⃣ Hashes **thgtoa.pdf** (light) ```text SHA-256 ${{ steps.hashes.outputs.light_sha256 }} BLAKE2b ${{ steps.hashes.outputs.light_b2 }} ``` **thgtoa-dark.pdf** (dark) ```text SHA-256 ${{ steps.hashes.outputs.dark_sha256 }} BLAKE2b ${{ steps.hashes.outputs.dark_b2 }} ``` --- ### 🔏 Verifying GPG signatures ```bash # Import the release signing key gpg --import pgp/anonymousplanet-release.asc # Verify PDFs gpg --verify thgtoa.pdf.asc thgtoa.pdf gpg --verify thgtoa-dark.pdf.asc thgtoa-dark.pdf # Verify hash files gpg --verify sha256sums.txt.asc sha256sums.txt gpg --verify b2sums.txt.asc b2sums.txt ``` --- ### 🦠 VirusTotal scans | File | Report | |------|--------| | `thgtoa.pdf` | ${{ steps.vt_urls.outputs.light_vt }} | | `thgtoa-dark.pdf` | ${{ steps.vt_urls.outputs.dark_vt }} | files: | release/thgtoa.pdf release/thgtoa-dark.pdf release/sha256sums.txt release/b2sums.txt release/thgtoa.pdf.sha256 release/thgtoa-dark.pdf.sha256 release/thgtoa.pdf.b2sum release/thgtoa-dark.pdf.b2sum release/thgtoa.pdf.asc release/thgtoa-dark.pdf.asc release/sha256sums.txt.asc release/b2sums.txt.asc