mirror of
https://github.com/Anon-Planet/thgtoa.git
synced 2026-06-11 00:02:29 +02:00
1624 lines
65 KiB
HTML
1624 lines
65 KiB
HTML
|
||
<!doctype html>
|
||
<html lang="en" class="no-js">
|
||
<head>
|
||
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
|
||
<meta name="description" content="The comprehensive guide for online #anonymity and #opsec.">
|
||
|
||
|
||
<meta name="author" content="Anonymous Planet">
|
||
|
||
|
||
<link rel="canonical" href="https://www.anonymousplanet.net/code/develop/">
|
||
|
||
|
||
<link rel="prev" href="../">
|
||
|
||
|
||
<link rel="next" href="../../contribute/">
|
||
|
||
|
||
<link rel="icon" href="../../media/profile.png">
|
||
<meta name="generator" content="mkdocs-1.5.3, mkdocs-material-9.5.17">
|
||
|
||
|
||
|
||
<title>Develop - The Hitchhiker's Guide</title>
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../../assets/stylesheets/main.bcfcd587.min.css">
|
||
|
||
|
||
<link rel="stylesheet" href="../../assets/stylesheets/palette.06af60db.min.css">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Public+Sans:300,300i,400,400i,700,700i%7CLiberation+Mono:400,400i,700,700i&display=fallback">
|
||
<style>:root{--md-text-font:"Public Sans";--md-code-font:"Liberation Mono"}</style>
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../../stylesheets/extra.css">
|
||
|
||
<script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce((e,_)=>(e<<5)-e+_.charCodeAt(0),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<meta property="og:type" content="website" >
|
||
|
||
<meta property="og:title" content="Develop - The Hitchhiker's Guide" >
|
||
|
||
<meta property="og:description" content="The comprehensive guide for online #anonymity and #opsec." >
|
||
|
||
<meta property="og:image" content="https://www.anonymousplanet.net/assets/images/social/code/develop.png" >
|
||
|
||
<meta property="og:image:type" content="image/png" >
|
||
|
||
<meta property="og:image:width" content="1200" >
|
||
|
||
<meta property="og:image:height" content="630" >
|
||
|
||
<meta property="og:url" content="https://www.anonymousplanet.net/code/develop/" >
|
||
|
||
<meta name="twitter:card" content="summary_large_image" >
|
||
|
||
<meta name="twitter:title" content="Develop - The Hitchhiker's Guide" >
|
||
|
||
<meta name="twitter:description" content="The comprehensive guide for online #anonymity and #opsec." >
|
||
|
||
<meta name="twitter:image" content="https://www.anonymousplanet.net/assets/images/social/code/develop.png" >
|
||
|
||
|
||
|
||
</head>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="green" data-md-color-accent="blue">
|
||
|
||
|
||
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
|
||
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
|
||
<label class="md-overlay" for="__drawer"></label>
|
||
<div data-md-component="skip">
|
||
|
||
|
||
<a href="#developer-guide" class="md-skip">
|
||
Skip to content
|
||
</a>
|
||
|
||
</div>
|
||
<div data-md-component="announce">
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<header class="md-header" data-md-component="header">
|
||
<nav class="md-header__inner md-grid" aria-label="Header">
|
||
<a href="../.." title="The Hitchhiker's Guide" class="md-header__button md-logo" aria-label="The Hitchhiker's Guide" data-md-component="logo">
|
||
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m23 11.5-3.05-1.13c-.26-1.15-.91-1.81-.91-1.81a4.189 4.189 0 0 0-5.93 0l-1.48 1.48L5 3c-1 4 0 8 2.45 11.22L2 19.5s8.89 2 14.07-2.05c2.76-2.16 3.38-3.42 3.77-4.75L23 11.5m-5.29.22c-.39.39-1.03.39-1.42 0a.996.996 0 0 1 0-1.41c.39-.39 1.03-.39 1.42 0 .39.39.39 1.02 0 1.41Z"/></svg>
|
||
|
||
</a>
|
||
<label class="md-header__button md-icon" for="__drawer">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2Z"/></svg>
|
||
</label>
|
||
<div class="md-header__title" data-md-component="header-title">
|
||
<div class="md-header__ellipsis">
|
||
<div class="md-header__topic">
|
||
<span class="md-ellipsis">
|
||
The Hitchhiker's Guide
|
||
</span>
|
||
</div>
|
||
<div class="md-header__topic" data-md-component="header-topic">
|
||
<span class="md-ellipsis">
|
||
|
||
Develop
|
||
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<form class="md-header__option" data-md-component="palette">
|
||
|
||
|
||
|
||
|
||
<input class="md-option" data-md-color-media="" data-md-color-scheme="default" data-md-color-primary="green" data-md-color-accent="blue" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_0">
|
||
|
||
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1" hidden>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 9a3 3 0 0 1 3 3 3 3 0 0 1-3 3 3 3 0 0 1-3-3 3 3 0 0 1 3-3m0-4.5c5 0 9.27 3.11 11 7.5-1.73 4.39-6 7.5-11 7.5S2.73 16.39 1 12c1.73-4.39 6-7.5 11-7.5M3.18 12a9.821 9.821 0 0 0 17.64 0 9.821 9.821 0 0 0-17.64 0Z"/></svg>
|
||
</label>
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="grey" data-md-color-accent="teal" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1">
|
||
|
||
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_0" hidden>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0 8a5 5 0 0 1-5-5 5 5 0 0 1 5-5 5 5 0 0 1 5 5 5 5 0 0 1-5 5m0-12.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5Z"/></svg>
|
||
</label>
|
||
|
||
|
||
</form>
|
||
|
||
|
||
|
||
<script>var media,input,key,value,palette=__md_get("__palette");if(palette&&palette.color){"(prefers-color-scheme)"===palette.color.media&&(media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']"),palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent"));for([key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
|
||
|
||
|
||
|
||
<label class="md-header__button md-icon" for="__search">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
|
||
</label>
|
||
<div class="md-search" data-md-component="search" role="dialog">
|
||
<label class="md-search__overlay" for="__search"></label>
|
||
<div class="md-search__inner" role="search">
|
||
<form class="md-search__form" name="search">
|
||
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
|
||
<label class="md-search__icon md-icon" for="__search">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5Z"/></svg>
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg>
|
||
</label>
|
||
<nav class="md-search__options" aria-label="Search">
|
||
|
||
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41Z"/></svg>
|
||
</button>
|
||
</nav>
|
||
|
||
<div class="md-search__suggest" data-md-component="search-suggest"></div>
|
||
|
||
</form>
|
||
<div class="md-search__output">
|
||
<div class="md-search__scrollwrap" data-md-scrollfix>
|
||
<div class="md-search-result" data-md-component="search-result">
|
||
<div class="md-search-result__meta">
|
||
Initializing search
|
||
</div>
|
||
<ol class="md-search-result__list" role="presentation"></ol>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<div class="md-header__source">
|
||
<a href="https://github.com/Anon-Planet/thgtoa" title="Go to repository" class="md-source" data-md-component="source">
|
||
<div class="md-source__icon md-icon">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>
|
||
</div>
|
||
<div class="md-source__repository">
|
||
|
||
</div>
|
||
</a>
|
||
</div>
|
||
|
||
</nav>
|
||
|
||
</header>
|
||
|
||
<div class="md-container" data-md-component="container">
|
||
|
||
|
||
|
||
|
||
|
||
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
|
||
<div class="md-grid">
|
||
<ul class="md-tabs__list">
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href="../.." class="md-tabs__link">
|
||
|
||
|
||
|
||
|
||
Welcome
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href="../../about/" class="md-tabs__link">
|
||
|
||
|
||
|
||
|
||
About
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href="../../verify/" class="md-tabs__link">
|
||
|
||
|
||
|
||
|
||
Verify
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href="../../guide/" class="md-tabs__link">
|
||
|
||
|
||
Guide
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item md-tabs__item--active">
|
||
<a href="../" class="md-tabs__link">
|
||
|
||
|
||
Code
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href="../../contribute/" class="md-tabs__link">
|
||
|
||
|
||
|
||
|
||
Contribute
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href="../../constitution/" class="md-tabs__link">
|
||
|
||
|
||
|
||
|
||
Constitution
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href="../../mirrors/" class="md-tabs__link">
|
||
|
||
|
||
|
||
|
||
Mirrors
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href="../../twitter/" class="md-tabs__link">
|
||
|
||
|
||
|
||
|
||
Twitter
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href="../../changelog/" class="md-tabs__link">
|
||
|
||
|
||
|
||
|
||
Releases
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
</ul>
|
||
</div>
|
||
</nav>
|
||
|
||
|
||
|
||
<main class="md-main" data-md-component="main">
|
||
<div class="md-main__inner md-grid">
|
||
|
||
|
||
|
||
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
|
||
<div class="md-sidebar__scrollwrap">
|
||
<div class="md-sidebar__inner">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<nav class="md-nav md-nav--primary md-nav--lifted md-nav--integrated" aria-label="Navigation" data-md-level="0">
|
||
<label class="md-nav__title" for="__drawer">
|
||
<a href="../.." title="The Hitchhiker's Guide" class="md-nav__button md-logo" aria-label="The Hitchhiker's Guide" data-md-component="logo">
|
||
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m23 11.5-3.05-1.13c-.26-1.15-.91-1.81-.91-1.81a4.189 4.189 0 0 0-5.93 0l-1.48 1.48L5 3c-1 4 0 8 2.45 11.22L2 19.5s8.89 2 14.07-2.05c2.76-2.16 3.38-3.42 3.77-4.75L23 11.5m-5.29.22c-.39.39-1.03.39-1.42 0a.996.996 0 0 1 0-1.41c.39-.39 1.03-.39 1.42 0 .39.39.39 1.02 0 1.41Z"/></svg>
|
||
|
||
</a>
|
||
The Hitchhiker's Guide
|
||
</label>
|
||
|
||
<div class="md-nav__source">
|
||
<a href="https://github.com/Anon-Planet/thgtoa" title="Go to repository" class="md-source" data-md-component="source">
|
||
<div class="md-source__icon md-icon">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>
|
||
</div>
|
||
<div class="md-source__repository">
|
||
|
||
</div>
|
||
</a>
|
||
</div>
|
||
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../.." class="md-nav__link">
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
Welcome
|
||
</span>
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../about/" class="md-nav__link">
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
About
|
||
</span>
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../verify/" class="md-nav__link">
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
Verify
|
||
</span>
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--nested">
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" >
|
||
|
||
|
||
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
Guide
|
||
</span>
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_4">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
Guide
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../guide/" class="md-nav__link">
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
./
|
||
</span>
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" checked>
|
||
|
||
|
||
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="">
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
Code
|
||
</span>
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="true">
|
||
<label class="md-nav__title" for="__nav_5">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
Code
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../" class="md-nav__link">
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
Content Contributions
|
||
</span>
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--active">
|
||
|
||
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
|
||
|
||
|
||
|
||
|
||
|
||
<label class="md-nav__link md-nav__link--active" for="__toc">
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
Develop
|
||
</span>
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<a href="./" class="md-nav__link md-nav__link--active">
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
Develop
|
||
</span>
|
||
|
||
|
||
</a>
|
||
|
||
|
||
|
||
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<label class="md-nav__title" for="__toc">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
Table of contents
|
||
</label>
|
||
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#prerequisites" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
Prerequisites
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#repository-layout" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
Repository layout
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#building-locally" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
Building locally
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Building locally">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#build-both-pdfs" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
Build both PDFs
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#build-only-the-dark-pdf-from-an-existing-light-pdf" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
Build only the dark PDF from an existing light PDF
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#preview-the-mkdocs-site" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
Preview the MkDocs site
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#cicd-pipeline-overview" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
CI/CD pipeline overview
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#release-process-step-by-step" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
Release process (step by step)
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Release process (step by step)">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#1-trigger-a-build" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
1. Trigger a build
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#2-sign-the-pdfs" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
2. Sign the PDFs
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#3-publish-the-release" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
3. Publish the release
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#4-update-the-changelog" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
4. Update the changelog
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#release-tag-format" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
Release tag format
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#commit-message-format" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
Commit message format
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#github-secrets" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
GitHub Secrets
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="GitHub Secrets">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#gpg_private_key" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
GPG_PRIVATE_KEY
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#gpg_passphrase" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
GPG_PASSPHRASE
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#actions_ssh_signing_key" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
ACTIONS_SSH_SIGNING_KEY
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#vt_api_key" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
VT_API_KEY
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#changelog_pat" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
CHANGELOG_PAT
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#secrets-summary" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
Secrets summary
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#verifying-a-release" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
Verifying a release
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#troubleshooting" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
Troubleshooting
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../contribute/" class="md-nav__link">
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
Contribute
|
||
</span>
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../constitution/" class="md-nav__link">
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
Constitution
|
||
</span>
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../mirrors/" class="md-nav__link">
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
Mirrors
|
||
</span>
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../twitter/" class="md-nav__link">
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
Twitter
|
||
</span>
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../changelog/" class="md-nav__link">
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
Releases
|
||
</span>
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<div class="md-content" data-md-component="content">
|
||
<article class="md-content__inner md-typeset">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<h1 id="developer-guide">Developer Guide<a class="headerlink" href="#developer-guide" title="Permanent link">¶</a></h1>
|
||
<p>This page covers everything you need to contribute to the project, run the build pipeline locally, configure GitHub Secrets, and publish a release.</p>
|
||
<hr />
|
||
<h2 id="prerequisites">Prerequisites<a class="headerlink" href="#prerequisites" title="Permanent link">¶</a></h2>
|
||
<p>Install these before anything else.</p>
|
||
<div class="tabbed-set tabbed-alternate" data-tabs="1:2"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Linux / macOS</label><label for="__tabbed_1_2">Windows</label></div>
|
||
<div class="tabbed-content">
|
||
<div class="tabbed-block">
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="c1"># Python 3.11+</span>
|
||
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>python3<span class="w"> </span>--version
|
||
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a>
|
||
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a><span class="c1"># poppler (pdftoppm) and qpdf</span>
|
||
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a>sudo<span class="w"> </span>apt<span class="w"> </span>install<span class="w"> </span>poppler-utils<span class="w"> </span>qpdf<span class="w"> </span><span class="c1"># Debian/Ubuntu</span>
|
||
<a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a>brew<span class="w"> </span>install<span class="w"> </span>poppler<span class="w"> </span>qpdf<span class="w"> </span><span class="c1"># macOS</span>
|
||
<a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a>
|
||
<a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a><span class="c1"># GPG</span>
|
||
<a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a>sudo<span class="w"> </span>apt<span class="w"> </span>install<span class="w"> </span>gnupg<span class="w"> </span><span class="c1"># Debian/Ubuntu</span>
|
||
<a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a>brew<span class="w"> </span>install<span class="w"> </span>gnupg<span class="w"> </span><span class="c1"># macOS</span>
|
||
<a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a>
|
||
<a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a><span class="c1"># Python dependencies</span>
|
||
<a id="__codelineno-0-13" name="__codelineno-0-13" href="#__codelineno-0-13"></a>pip<span class="w"> </span>install<span class="w"> </span><span class="s2">"mkdocs-material[imaging]"</span><span class="w"> </span>pillow<span class="w"> </span>numpy
|
||
</code></pre></div>
|
||
</div>
|
||
<div class="tabbed-block">
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="c"># Python 3.11+ from https://python.org</span>
|
||
<a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a>
|
||
<a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a><span class="c"># poppler: download from https://github.com/oschwartz10612/poppler-windows/releases</span>
|
||
<a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a><span class="c"># Extract and add the bin\ folder to PATH</span>
|
||
<a id="__codelineno-1-5" name="__codelineno-1-5" href="#__codelineno-1-5"></a>
|
||
<a id="__codelineno-1-6" name="__codelineno-1-6" href="#__codelineno-1-6"></a><span class="c"># qpdf: download from https://github.com/qpdf/qpdf/releases</span>
|
||
<a id="__codelineno-1-7" name="__codelineno-1-7" href="#__codelineno-1-7"></a><span class="c"># Extract and add the bin\ folder to PATH</span>
|
||
<a id="__codelineno-1-8" name="__codelineno-1-8" href="#__codelineno-1-8"></a>
|
||
<a id="__codelineno-1-9" name="__codelineno-1-9" href="#__codelineno-1-9"></a><span class="c"># GPG: download Gpg4win from https://gpg4win.org</span>
|
||
<a id="__codelineno-1-10" name="__codelineno-1-10" href="#__codelineno-1-10"></a>
|
||
<a id="__codelineno-1-11" name="__codelineno-1-11" href="#__codelineno-1-11"></a><span class="c"># Python dependencies</span>
|
||
<a id="__codelineno-1-12" name="__codelineno-1-12" href="#__codelineno-1-12"></a><span class="n">pip</span> <span class="n">install</span> <span class="s2">"mkdocs-material[imaging]"</span> <span class="n">pillow</span> <span class="n">numpy</span>
|
||
</code></pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>You also need <strong>Google Chrome</strong> or <strong>Microsoft Edge</strong> installed for the light-mode PDF build (headless Chromium).</p>
|
||
<hr />
|
||
<h2 id="repository-layout">Repository layout<a class="headerlink" href="#repository-layout" title="Permanent link">¶</a></h2>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a>.github/
|
||
<a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a> workflows/
|
||
<a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a> 01-build.yml # builds PDFs, uploads artifact
|
||
<a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a> 02-sign.yml # hashes + GPG signs, uploads signatures artifact
|
||
<a id="__codelineno-2-5" name="__codelineno-2-5" href="#__codelineno-2-5"></a> 03-release.yml # publishes GitHub Release with all assets
|
||
<a id="__codelineno-2-6" name="__codelineno-2-6" href="#__codelineno-2-6"></a> 04-changelog.yml # prepends a new entry to docs/changelog/index.md
|
||
<a id="__codelineno-2-7" name="__codelineno-2-7" href="#__codelineno-2-7"></a> publish.yml # deploys MkDocs site to GitHub Pages
|
||
<a id="__codelineno-2-8" name="__codelineno-2-8" href="#__codelineno-2-8"></a>docs/
|
||
<a id="__codelineno-2-9" name="__codelineno-2-9" href="#__codelineno-2-9"></a> guide/index.md # the guide (single Markdown file)
|
||
<a id="__codelineno-2-10" name="__codelineno-2-10" href="#__codelineno-2-10"></a> changelog/ # release notes
|
||
<a id="__codelineno-2-11" name="__codelineno-2-11" href="#__codelineno-2-11"></a> code/ # this page
|
||
<a id="__codelineno-2-12" name="__codelineno-2-12" href="#__codelineno-2-12"></a>export/ # PDF output (PDFs gitignored; .sha256, .b2sum, .asc tracked)
|
||
<a id="__codelineno-2-13" name="__codelineno-2-13" href="#__codelineno-2-13"></a>pgp/ # public signing keys
|
||
<a id="__codelineno-2-14" name="__codelineno-2-14" href="#__codelineno-2-14"></a>scripts/
|
||
<a id="__codelineno-2-15" name="__codelineno-2-15" href="#__codelineno-2-15"></a> build_guide_pdf.py # MkDocs + Chromium PDF builder
|
||
<a id="__codelineno-2-16" name="__codelineno-2-16" href="#__codelineno-2-16"></a> convert.py # pixel-based dark mode PDF converter
|
||
<a id="__codelineno-2-17" name="__codelineno-2-17" href="#__codelineno-2-17"></a> update_changelog.py # auto-generates changelog entries from git log
|
||
<a id="__codelineno-2-18" name="__codelineno-2-18" href="#__codelineno-2-18"></a> setup_workflow.py # GitHub Secrets setup assistant
|
||
<a id="__codelineno-2-19" name="__codelineno-2-19" href="#__codelineno-2-19"></a> verify_pdf.py # signature verification helper
|
||
<a id="__codelineno-2-20" name="__codelineno-2-20" href="#__codelineno-2-20"></a> archived/
|
||
<a id="__codelineno-2-21" name="__codelineno-2-21" href="#__codelineno-2-21"></a> tag_release.py # ARCHIVED - GPG tag helper (not used in current flow)
|
||
</code></pre></div>
|
||
<hr />
|
||
<h2 id="building-locally">Building locally<a class="headerlink" href="#building-locally" title="Permanent link">¶</a></h2>
|
||
<h3 id="build-both-pdfs">Build both PDFs<a class="headerlink" href="#build-both-pdfs" title="Permanent link">¶</a></h3>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a>python<span class="w"> </span>scripts/build_guide_pdf.py<span class="w"> </span>--both
|
||
</code></pre></div>
|
||
<p>This builds the MkDocs site, renders it to <code>export/thgtoa.pdf</code> via headless Chromium, then calls <code>scripts/convert.py</code> to produce <code>export/thgtoa-dark.pdf</code>.</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Flag</th>
|
||
<th>Effect</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>--both</code></td>
|
||
<td>Light PDF then dark PDF</td>
|
||
</tr>
|
||
<tr>
|
||
<td>(no flag)</td>
|
||
<td>Light PDF only</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>--dark</code></td>
|
||
<td>Dark PDF only (light PDF must already exist)</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<h3 id="build-only-the-dark-pdf-from-an-existing-light-pdf">Build only the dark PDF from an existing light PDF<a class="headerlink" href="#build-only-the-dark-pdf-from-an-existing-light-pdf" title="Permanent link">¶</a></h3>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a>python<span class="w"> </span>scripts/convert.py<span class="w"> </span>export/thgtoa.pdf<span class="w"> </span>export/thgtoa-dark.pdf
|
||
</code></pre></div>
|
||
<p>Options:</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Flag</th>
|
||
<th>Default</th>
|
||
<th>Description</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>--dpi</code></td>
|
||
<td><code>200</code></td>
|
||
<td>Rasterization DPI. 150 = smaller file, 300 = sharper but slow</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>--batch-size</code></td>
|
||
<td><code>50</code></td>
|
||
<td>Pages per batch. Reduce if you hit OOM</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>--bg</code></td>
|
||
<td><code>1f1f31</code></td>
|
||
<td>Background colour (hex)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>--text</code></td>
|
||
<td><code>e0e0e0</code></td>
|
||
<td>Body text colour (hex)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>--link</code></td>
|
||
<td><code>5e8bde</code></td>
|
||
<td>Link / blue element colour (hex)</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<h3 id="preview-the-mkdocs-site">Preview the MkDocs site<a class="headerlink" href="#preview-the-mkdocs-site" title="Permanent link">¶</a></h3>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a>mkdocs<span class="w"> </span>serve
|
||
</code></pre></div>
|
||
<p>Opens at <code>http://127.0.0.1:8000</code>.</p>
|
||
<hr />
|
||
<h2 id="cicd-pipeline-overview">CI/CD pipeline overview<a class="headerlink" href="#cicd-pipeline-overview" title="Permanent link">¶</a></h2>
|
||
<p>The pipeline is fully manual after the initial build - no step automatically triggers the next. This prevents version mismatches between what was built, what was signed, and what gets released. The workflows are numbered to help guide you.</p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a>push to main (or manual trigger)
|
||
<a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a> │
|
||
<a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a> ▼
|
||
<a id="__codelineno-6-4" name="__codelineno-6-4" href="#__codelineno-6-4"></a> 01-build.yml
|
||
<a id="__codelineno-6-5" name="__codelineno-6-5" href="#__codelineno-6-5"></a> Builds thgtoa.pdf + thgtoa-dark.pdf.
|
||
<a id="__codelineno-6-6" name="__codelineno-6-6" href="#__codelineno-6-6"></a> Uploads artifact: pdfs
|
||
<a id="__codelineno-6-7" name="__codelineno-6-7" href="#__codelineno-6-7"></a> Note the run ID.
|
||
<a id="__codelineno-6-8" name="__codelineno-6-8" href="#__codelineno-6-8"></a> │
|
||
<a id="__codelineno-6-9" name="__codelineno-6-9" href="#__codelineno-6-9"></a> │ # manually trigger 02-sign.yml with the build run ID
|
||
<a id="__codelineno-6-10" name="__codelineno-6-10" href="#__codelineno-6-10"></a> ▼
|
||
<a id="__codelineno-6-11" name="__codelineno-6-11" href="#__codelineno-6-11"></a> 02-sign.yml
|
||
<a id="__codelineno-6-12" name="__codelineno-6-12" href="#__codelineno-6-12"></a> Downloads pdfs artifact. Hashes (SHA-256 + BLAKE2b) and GPG-signs
|
||
<a id="__codelineno-6-13" name="__codelineno-6-13" href="#__codelineno-6-13"></a> all files. Commits export/ back to main. Uploads artifacts:
|
||
<a id="__codelineno-6-14" name="__codelineno-6-14" href="#__codelineno-6-14"></a> signatures, pdfs-signed
|
||
<a id="__codelineno-6-15" name="__codelineno-6-15" href="#__codelineno-6-15"></a> Note the run ID.
|
||
<a id="__codelineno-6-16" name="__codelineno-6-16" href="#__codelineno-6-16"></a> │
|
||
<a id="__codelineno-6-17" name="__codelineno-6-17" href="#__codelineno-6-17"></a> │ # manually trigger 03-release.yml with the sign run ID
|
||
<a id="__codelineno-6-18" name="__codelineno-6-18" href="#__codelineno-6-18"></a> ▼
|
||
<a id="__codelineno-6-19" name="__codelineno-6-19" href="#__codelineno-6-19"></a> 03-release.yml
|
||
<a id="__codelineno-6-20" name="__codelineno-6-20" href="#__codelineno-6-20"></a> Downloads signatures + pdfs-signed artifacts. Runs VirusTotal.
|
||
<a id="__codelineno-6-21" name="__codelineno-6-21" href="#__codelineno-6-21"></a> Creates GitHub Release tagged release-YYYYMMDD-<short-sha>.
|
||
<a id="__codelineno-6-22" name="__codelineno-6-22" href="#__codelineno-6-22"></a> │
|
||
<a id="__codelineno-6-23" name="__codelineno-6-23" href="#__codelineno-6-23"></a> │ # manually trigger 04-changelog.yml with the version string
|
||
<a id="__codelineno-6-24" name="__codelineno-6-24" href="#__codelineno-6-24"></a> ▼
|
||
<a id="__codelineno-6-25" name="__codelineno-6-25" href="#__codelineno-6-25"></a> 04-changelog.yml
|
||
<a id="__codelineno-6-26" name="__codelineno-6-26" href="#__codelineno-6-26"></a> Runs update_changelog.py, prepends a new ## [vX.Y.Z] entry,
|
||
<a id="__codelineno-6-27" name="__codelineno-6-27" href="#__codelineno-6-27"></a> commits back to main.
|
||
</code></pre></div>
|
||
<p>Each stage is independent. If signing fails (e.g. an expired/revoked key, other problems in CI), re-run only <code>02-sign.yml</code> pointing at the existing build artifact - no need to rebuild the PDFs.</p>
|
||
<div class="admonition warning">
|
||
<p class="admonition-title">Before you push</p>
|
||
<ul>
|
||
<li>Make sure the working tree is clean (<code>git status</code>)</li>
|
||
<li>Run <code>mkdocs build</code> locally if you changed <code>docs/</code> to catch broken links before CI does</li>
|
||
<li>If you added new footnotes, verify they have both a definition <code>[^N]:</code> and at least one inline citation <code>[^N]</code></li>
|
||
</ul>
|
||
</div>
|
||
<hr />
|
||
<h2 id="release-process-step-by-step">Release process (step by step)<a class="headerlink" href="#release-process-step-by-step" title="Permanent link">¶</a></h2>
|
||
<h3 id="1-trigger-a-build">1. Trigger a build<a class="headerlink" href="#1-trigger-a-build" title="Permanent link">¶</a></h3>
|
||
<p>Push to <code>main</code> - <code>01-build.yml</code> runs automatically when <code>docs/</code>, <code>mkdocs.yml</code>, or <code>scripts/</code> change. You can also trigger it manually from <strong>Actions → Build PDFs → Run workflow</strong>.</p>
|
||
<p>Once it completes successfully, <strong>note the run ID</strong> from the URL or the Actions list.</p>
|
||
<hr />
|
||
<h3 id="2-sign-the-pdfs">2. Sign the PDFs<a class="headerlink" href="#2-sign-the-pdfs" title="Permanent link">¶</a></h3>
|
||
<p>Go to <strong>Actions → Sign PDFs → Run workflow</strong>.</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Input</th>
|
||
<th>Value</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>build_run_id</code></td>
|
||
<td>The run ID from step 1</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p><code>02-sign.yml</code> will:</p>
|
||
<ul>
|
||
<li>Download the PDFs artifact from the build run</li>
|
||
<li>Compute SHA-256 and BLAKE2b hashes, writing <code>thgtoa.pdf.sha256</code>, <code>thgtoa.pdf.b2sum</code>, <code>sha256sums.txt</code>, <code>b2sums.txt</code>, and the dark equivalents</li>
|
||
<li>GPG-sign all PDFs and hash files, writing <code>.asc</code> detached signature files</li>
|
||
<li>Commit the updated <code>export/</code> directory back to <code>main</code></li>
|
||
<li>Upload two artifacts: <code>signatures</code> and <code>pdfs-signed</code></li>
|
||
</ul>
|
||
<p>Once it completes successfully, <strong>note the run ID</strong>.</p>
|
||
<hr />
|
||
<h3 id="3-publish-the-release">3. Publish the release<a class="headerlink" href="#3-publish-the-release" title="Permanent link">¶</a></h3>
|
||
<p>Go to <strong>Actions → Release → Run workflow</strong>.</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Input</th>
|
||
<th>Value</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>sign_run_id</code></td>
|
||
<td>The run ID from step 2</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>prerelease</code></td>
|
||
<td><code>false</code> for a normal release</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p><code>03-release.yml</code> will:</p>
|
||
<ul>
|
||
<li>Download <code>signatures</code> and <code>pdfs-signed</code> artifacts from the sign run</li>
|
||
<li>Upload both PDFs to VirusTotal</li>
|
||
<li>Auto-generate a release tag in the format <code>release-YYYYMMDD-<short-sha></code> (e.g. <code>release-20260527-abc1234</code>)</li>
|
||
<li>Create a GitHub Release with all PDFs, hash files, and signatures attached, and the VirusTotal report URLs in the body</li>
|
||
</ul>
|
||
<p>No version number needs to be chosen at this step - the tag is derived from the date and commit SHA, so it is always unique and always traceable.</p>
|
||
<hr />
|
||
<h3 id="4-update-the-changelog">4. Update the changelog<a class="headerlink" href="#4-update-the-changelog" title="Permanent link">¶</a></h3>
|
||
<p>Go to <strong>Actions → Update Changelog → Run workflow</strong>.</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Input</th>
|
||
<th>Value</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>version</code></td>
|
||
<td>The human-readable version string, e.g. <code>v1.2.4</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>dry_run</code></td>
|
||
<td><code>true</code> to preview without committing</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p><code>04-changelog.yml</code> runs <code>scripts/update_changelog.py</code>, which:</p>
|
||
<ul>
|
||
<li>Reads git log since the last <code>## [vX.Y.Z]</code> heading in the changelog</li>
|
||
<li>Categorises commits into Added / Changed / Fixed using conventional-commit prefixes</li>
|
||
<li>Prepends a new <code>## [version]</code> admonition block to <code>docs/changelog/index.md</code></li>
|
||
<li>Commits the result back to <code>main</code></li>
|
||
</ul>
|
||
<p>The version string is the only human decision in the release process. It goes into the changelog only - it does not affect the release tag.</p>
|
||
<div class="admonition tip">
|
||
<p class="admonition-title">Previewing the changelog entry</p>
|
||
<p>Run with <code>dry_run: true</code> first to review the generated entry before it is committed.</p>
|
||
</div>
|
||
<hr />
|
||
<h2 id="release-tag-format">Release tag format<a class="headerlink" href="#release-tag-format" title="Permanent link">¶</a></h2>
|
||
<p>Release tags use the format <code>release-YYYYMMDD-<short-sha></code>, for example:</p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a>release-20260527-abc1234
|
||
</code></pre></div>
|
||
<p>This format is always unique, requires no version decision at release time, and is directly traceable to the commit that was built. The version string (e.g. <code>v1.2.4</code>) is a separate, human-assigned label that lives only in the changelog.</p>
|
||
<hr />
|
||
<h2 id="commit-message-format">Commit message format<a class="headerlink" href="#commit-message-format" title="Permanent link">¶</a></h2>
|
||
<p>All commits must follow the <a href="https://www.conventionalcommits.org">Conventional Commits</a> format. This is enforced by the <code>commitizen</code> pre-commit hook. Not because we want to limit cooperation with others, but becasue it promotes a cleaner Changelog; we can avoid all the noise by doing this programatically.</p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><type>(<scope>): <description>
|
||
</code></pre></div>
|
||
<p>Accepted types and their changelog bucket:</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Type</th>
|
||
<th>Bucket</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>feat</code>, <code>feature</code>, <code>add</code></td>
|
||
<td>Added</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>fix</code>, <code>bugfix</code>, <code>revert</code>, <code>security</code></td>
|
||
<td>Fixed</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>perf</code>, <code>refactor</code>, <code>change</code>, <code>chore</code>, <code>ci</code>, <code>docs</code>, <code>style</code>, <code>test</code>, <code>build</code></td>
|
||
<td>Changed</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>Examples:</p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a>feat:<span class="w"> </span>add<span class="w"> </span>dark-mode<span class="w"> </span>PDF<span class="w"> </span><span class="nb">export</span>
|
||
<a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a>fix<span class="o">(</span>scripts<span class="o">)</span>:<span class="w"> </span>handle<span class="w"> </span>locked<span class="w"> </span>PDF<span class="w"> </span>on<span class="w"> </span>Windows
|
||
<a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a>docs:<span class="w"> </span>update<span class="w"> </span>developer<span class="w"> </span>workflow<span class="w"> </span>guide
|
||
<a id="__codelineno-9-4" name="__codelineno-9-4" href="#__codelineno-9-4"></a>chore<span class="o">(</span>ci<span class="o">)</span>:<span class="w"> </span>pin<span class="w"> </span>Chrome<span class="w"> </span>version<span class="w"> </span>to<span class="w"> </span><span class="m">120</span>
|
||
</code></pre></div>
|
||
<hr />
|
||
<h2 id="github-secrets">GitHub Secrets<a class="headerlink" href="#github-secrets" title="Permanent link">¶</a></h2>
|
||
<p>Configure these in <strong>Settings → Secrets and variables → Actions</strong> before the pipeline will fully work. The build step requires no secrets; signing and releasing require all of them.</p>
|
||
<h3 id="gpg_private_key"><code>GPG_PRIVATE_KEY</code><a class="headerlink" href="#gpg_private_key" title="Permanent link">¶</a></h3>
|
||
<p>The ASCII-armored private key used to sign PDFs and hash files.</p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a>gpg<span class="w"> </span>--armor<span class="w"> </span>--export-secret-keys<span class="w"> </span>C3023DBEA3FB38C438BA1EEDCEC60AEDE8B992A2
|
||
</code></pre></div>
|
||
<p>Copy the entire output (including <code>-----BEGIN PGP PRIVATE KEY BLOCK-----</code> and the closing line) and paste it as the secret value.</p>
|
||
<div class="admonition danger">
|
||
<p class="admonition-title">Key security</p>
|
||
<p>This is the release signing key. Only repository admins should have access to it. Never commit it to the repository or share it outside of GitHub Secrets.</p>
|
||
</div>
|
||
<h3 id="gpg_passphrase"><code>GPG_PASSPHRASE</code><a class="headerlink" href="#gpg_passphrase" title="Permanent link">¶</a></h3>
|
||
<p>The passphrase protecting the private key above. Must match exactly - no trailing newline.</p>
|
||
<h3 id="actions_ssh_signing_key"><code>ACTIONS_SSH_SIGNING_KEY</code><a class="headerlink" href="#actions_ssh_signing_key" title="Permanent link">¶</a></h3>
|
||
<p>An SSH private key used by <code>02-sign.yml</code> to sign the commit that pushes <code>export/</code> back to <code>main</code>. Generate a dedicated key for this:</p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a>ssh-keygen<span class="w"> </span>-t<span class="w"> </span>ed25519<span class="w"> </span>-C<span class="w"> </span><span class="s2">"github-actions signing key"</span><span class="w"> </span>-f<span class="w"> </span>actions_signing_key
|
||
</code></pre></div>
|
||
<p>Add the <strong>private key</strong> as the <code>ACTIONS_SSH_SIGNING_KEY</code> secret, and the <strong>public key</strong> to the repository's Deploy Keys (Settings → Deploy Keys) with write access.</p>
|
||
<h3 id="vt_api_key"><code>VT_API_KEY</code><a class="headerlink" href="#vt_api_key" title="Permanent link">¶</a></h3>
|
||
<p>A <a href="https://www.virustotal.com">VirusTotal</a> API key with file upload permissions. Used by <code>03-release.yml</code> to scan both PDFs before publishing. Get one by creating a free account at <code>virustotal.com</code> → API key under your profile. The free tier (4 lookups/minute, 500/day) is sufficient.</p>
|
||
<h3 id="changelog_pat"><code>CHANGELOG_PAT</code><a class="headerlink" href="#changelog_pat" title="Permanent link">¶</a></h3>
|
||
<p>A GitHub Personal Access Token with <code>contents: write</code> scope on this repository. Needed because <code>04-changelog.yml</code> commits back to <code>main</code> - commits made with the default <code>GITHUB_TOKEN</code> do not trigger further workflow runs (GitHub loop-prevention). A PAT bypasses this. If absent, falls back to <code>GITHUB_TOKEN</code> - the commit still happens, it just won't trigger downstream workflows.</p>
|
||
<p><strong>Creating one:</strong> GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens → set Contents to Read and write for this repo only.</p>
|
||
<h3 id="secrets-summary">Secrets summary<a class="headerlink" href="#secrets-summary" title="Permanent link">¶</a></h3>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Secret</th>
|
||
<th>Required by</th>
|
||
<th>What happens if missing</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>GPG_PRIVATE_KEY</code></td>
|
||
<td><code>02-sign.yml</code></td>
|
||
<td>Signing step fails - no <code>.asc</code> files produced</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>GPG_PASSPHRASE</code></td>
|
||
<td><code>02-sign.yml</code></td>
|
||
<td>GPG import succeeds but signing fails</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>ACTIONS_SSH_SIGNING_KEY</code></td>
|
||
<td><code>02-sign.yml</code></td>
|
||
<td>Export commit is unsigned (may fail if branch protection requires signed commits)</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>VT_API_KEY</code></td>
|
||
<td><code>03-release.yml</code></td>
|
||
<td>VirusTotal step fails - release is not published</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>CHANGELOG_PAT</code></td>
|
||
<td><code>04-changelog.yml</code></td>
|
||
<td>Falls back to <code>GITHUB_TOKEN</code> - changelog updates but commit won't trigger downstream workflows</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<hr />
|
||
<h2 id="verifying-a-release">Verifying a release<a class="headerlink" href="#verifying-a-release" title="Permanent link">¶</a></h2>
|
||
<p>Anyone can verify the authenticity of a release download.</p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="c1"># Import the release signing key</span>
|
||
<a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a>gpg<span class="w"> </span>--import<span class="w"> </span>pgp/anonymousplanet-release.asc
|
||
<a id="__codelineno-12-3" name="__codelineno-12-3" href="#__codelineno-12-3"></a>
|
||
<a id="__codelineno-12-4" name="__codelineno-12-4" href="#__codelineno-12-4"></a><span class="c1"># Verify the PDFs</span>
|
||
<a id="__codelineno-12-5" name="__codelineno-12-5" href="#__codelineno-12-5"></a>gpg<span class="w"> </span>--verify<span class="w"> </span>thgtoa.pdf.asc<span class="w"> </span>thgtoa.pdf
|
||
<a id="__codelineno-12-6" name="__codelineno-12-6" href="#__codelineno-12-6"></a>gpg<span class="w"> </span>--verify<span class="w"> </span>thgtoa-dark.pdf.asc<span class="w"> </span>thgtoa-dark.pdf
|
||
<a id="__codelineno-12-7" name="__codelineno-12-7" href="#__codelineno-12-7"></a>
|
||
<a id="__codelineno-12-8" name="__codelineno-12-8" href="#__codelineno-12-8"></a><span class="c1"># Verify the hash files</span>
|
||
<a id="__codelineno-12-9" name="__codelineno-12-9" href="#__codelineno-12-9"></a>gpg<span class="w"> </span>--verify<span class="w"> </span>sha256sums.txt.asc<span class="w"> </span>sha256sums.txt
|
||
<a id="__codelineno-12-10" name="__codelineno-12-10" href="#__codelineno-12-10"></a>gpg<span class="w"> </span>--verify<span class="w"> </span>b2sums.txt.asc<span class="w"> </span>b2sums.txt
|
||
<a id="__codelineno-12-11" name="__codelineno-12-11" href="#__codelineno-12-11"></a>
|
||
<a id="__codelineno-12-12" name="__codelineno-12-12" href="#__codelineno-12-12"></a><span class="c1"># Check the PDF hashes match</span>
|
||
<a id="__codelineno-12-13" name="__codelineno-12-13" href="#__codelineno-12-13"></a>sha256sum<span class="w"> </span>-c<span class="w"> </span>sha256sums.txt
|
||
<a id="__codelineno-12-14" name="__codelineno-12-14" href="#__codelineno-12-14"></a>b2sum<span class="w"> </span>-c<span class="w"> </span>b2sums.txt
|
||
</code></pre></div>
|
||
<p>A successful verify looks like:</p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a>gpg: Signature made Sun 31 May 2026 03:23:26 AM EDT
|
||
<a id="__codelineno-13-2" name="__codelineno-13-2" href="#__codelineno-13-2"></a>gpg: using EDDSA key C3023DBEA3FB38C438BA1EEDCEC60AEDE8B992A2
|
||
<a id="__codelineno-13-3" name="__codelineno-13-3" href="#__codelineno-13-3"></a>gpg: Good signature from "Anonymous Planet Release Signing Key" [ultimate]
|
||
<a id="__codelineno-13-4" name="__codelineno-13-4" href="#__codelineno-13-4"></a>Primary key fingerprint: C302 3DBE A3FB 38C4 38BA 1EED CEC6 0AED E8B9 92A2
|
||
</code></pre></div>
|
||
<p>You can safely ignore Github, Codeberg, etc. warnings like "The email in this signature doesn’t match the committer email."</p>
|
||
<div class="highlight"><pre><span></span><code><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a>λ > git tag -v v1.2.3
|
||
<a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a>object cdc54d8b3bc2b286827b23921d8d4062f85295cf
|
||
<a id="__codelineno-14-3" name="__codelineno-14-3" href="#__codelineno-14-3"></a>type commit
|
||
<a id="__codelineno-14-4" name="__codelineno-14-4" href="#__codelineno-14-4"></a>tag v1.2.3
|
||
<a id="__codelineno-14-5" name="__codelineno-14-5" href="#__codelineno-14-5"></a>tagger nopeitsnothing <no@anonymousplanet.net> 1780212206 -0400
|
||
<a id="__codelineno-14-6" name="__codelineno-14-6" href="#__codelineno-14-6"></a>
|
||
<a id="__codelineno-14-7" name="__codelineno-14-7" href="#__codelineno-14-7"></a>v1.2.3
|
||
<a id="__codelineno-14-8" name="__codelineno-14-8" href="#__codelineno-14-8"></a>gpg: Signature made Sun 31 May 2026 03:23:26 AM EDT
|
||
<a id="__codelineno-14-9" name="__codelineno-14-9" href="#__codelineno-14-9"></a>gpg: using EDDSA key C3023DBEA3FB38C438BA1EEDCEC60AEDE8B992A2
|
||
<a id="__codelineno-14-10" name="__codelineno-14-10" href="#__codelineno-14-10"></a>gpg: Good signature from "Anonymous Planet Release Signing Key" [ultimate]
|
||
<a id="__codelineno-14-11" name="__codelineno-14-11" href="#__codelineno-14-11"></a>Primary key fingerprint: C302 3DBE A3FB 38C4 38BA 1EED CEC6 0AED E8B9 92A2
|
||
</code></pre></div>
|
||
<hr />
|
||
<h2 id="troubleshooting">Troubleshooting<a class="headerlink" href="#troubleshooting" title="Permanent link">¶</a></h2>
|
||
<p><strong><code>cairosvg</code> missing during MkDocs build</strong>
|
||
Install the imaging extras: <code>pip install "mkdocs-material[imaging]"</code>. Required by the <code>social</code> plugin.</p>
|
||
<p><strong><code>KeyError: 'JPEG'</code> in convert.py</strong>
|
||
Pillow needs libjpeg. Reinstall after installing the system lib: <code>sudo apt install libjpeg-dev && pip install --force-reinstall pillow</code>.</p>
|
||
<p><strong><code>qpdf: can't find PDF header</code></strong>
|
||
Ensure you are on the current version of <code>convert.py</code> - qpdf only accepts PDF inputs, not PNG.</p>
|
||
<p><strong>GPG signing fails on CI with <code>No secret key</code></strong>
|
||
The <code>GPG_PRIVATE_KEY</code> secret is missing or malformed. Re-export with <code>gpg --armor --export-secret-keys <fingerprint></code> and paste the full block including header and footer lines.</p>
|
||
<p><strong>GPG signing fails with <code>Bad passphrase</code></strong>
|
||
The <code>GPG_PASSPHRASE</code> secret has a trailing space or newline. Paste it again with no surrounding whitespace.</p>
|
||
<p><strong><code>03-release.yml</code> fails on VirusTotal</strong>
|
||
The <code>VT_API_KEY</code> is missing, invalid, or over the rate limit (500 requests/day on the free tier). Check the secret and re-run after a few minutes.</p>
|
||
<p><strong><code>02-sign.yml</code> fails downloading PDF artifact</strong>
|
||
The <code>build_run_id</code> is wrong, or the artifact has expired (90-day retention). Trigger a new build and use the fresh run ID.</p>
|
||
<p><strong>Changelog already contains version X</strong>
|
||
<code>update_changelog.py</code> will error if <code>MANUAL_VERSION</code> is set to a version already in the changelog. Choose the next version string.</p>
|
||
<p><strong>Footnote warnings from MkDocs (<code>link '#fnref:N' has no anchor</code>)</strong>
|
||
A footnote definition <code>[^N]:</code> exists without a matching inline citation. Add the citation or remove the orphaned definition.</p>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</article>
|
||
</div>
|
||
|
||
|
||
<script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var tab,labels=set.querySelector(".tabbed-labels");for(tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
|
||
|
||
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
|
||
</div>
|
||
|
||
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12Z"/></svg>
|
||
Back to top
|
||
</button>
|
||
|
||
</main>
|
||
|
||
<footer class="md-footer">
|
||
|
||
<div class="md-footer-meta md-typeset">
|
||
<div class="md-footer-meta__inner md-grid">
|
||
<div class="md-copyright">
|
||
|
||
<div class="md-copyright__highlight">
|
||
<a href="https://anonymousplanet.net/">The Hitchhiker's Guide</a> ©2023-2026 by <a href="https://psa.anonymousplanet.net/">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>
|
||
|
||
</div>
|
||
|
||
|
||
Made with
|
||
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
|
||
Material for MkDocs
|
||
</a>
|
||
|
||
</div>
|
||
|
||
<div class="md-social">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<a href="https://mastodon.social/@anonymousplanet" target="_blank" rel="noopener me" title="Mastodon" class="md-social__link">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z"/></svg>
|
||
</a>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="http://wmj5kiic7b6kjplpbvwadnht2nh2qnkbnqtcv3dyvpqtz7ssbssftxid.onion/" target="_blank" rel="noopener" title="0xacab" class="md-social__link">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m23.6 9.593-.033-.086L20.3.98a.851.851 0 0 0-.336-.405.875.875 0 0 0-1 .054.875.875 0 0 0-.29.44L16.47 7.818H7.537L5.332 1.07a.857.857 0 0 0-.29-.441.875.875 0 0 0-1-.054.859.859 0 0 0-.336.405L.433 9.502l-.032.086a6.066 6.066 0 0 0 2.012 7.01l.01.009.03.021 4.977 3.727 2.462 1.863 1.5 1.132a1.008 1.008 0 0 0 1.22 0l1.499-1.132 2.461-1.863 5.006-3.75.013-.01a6.068 6.068 0 0 0 2.01-7.002z"/></svg>
|
||
</a>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="http://it7otdanqu7ktntxzm427cba6i53w6wlanlh23v5i3siqmos47pzhvyd.onion/anonypla" target="_blank" rel="noopener" title="Darktea" class="md-social__link">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4.209 4.603c-.247 0-.525.02-.84.088-.333.07-1.28.283-2.054 1.027C-.403 7.25.035 9.685.089 10.052c.065.446.263 1.687 1.21 2.768 1.749 2.141 5.513 2.092 5.513 2.092s.462 1.103 1.168 2.119c.955 1.263 1.936 2.248 2.89 2.367 2.406 0 7.212-.004 7.212-.004s.458.004 1.08-.394c.535-.324 1.013-.893 1.013-.893s.492-.527 1.18-1.73c.21-.37.385-.729.538-1.068 0 0 2.107-4.471 2.107-8.823-.042-1.318-.367-1.55-.443-1.627-.156-.156-.366-.153-.366-.153s-4.475.252-6.792.306c-.508.011-1.012.023-1.512.027v4.474l-.634-.301c0-1.39-.004-4.17-.004-4.17-1.107.016-3.405-.084-3.405-.084s-5.399-.27-5.987-.324c-.187-.011-.401-.032-.648-.032zm.354 1.832h.111s.271 2.269.6 3.597C5.549 11.147 6.22 13 6.22 13s-.996-.119-1.641-.348c-.99-.324-1.409-.714-1.409-.714s-.73-.511-1.096-1.52C1.444 8.73 2.021 7.7 2.021 7.7s.32-.859 1.47-1.145c.395-.106.863-.12 1.072-.12zm8.33 2.554c.26.003.509.127.509.127l.868.422-.529 1.075a.686.686 0 0 0-.614.359.685.685 0 0 0 .072.756l-.939 1.924a.69.69 0 0 0-.66.527.687.687 0 0 0 .347.763.686.686 0 0 0 .867-.206.688.688 0 0 0-.069-.882l.916-1.874a.667.667 0 0 0 .237-.02.657.657 0 0 0 .271-.137 8.826 8.826 0 0 1 1.016.512.761.761 0 0 1 .286.282c.073.21-.073.569-.073.569-.087.29-.702 1.55-.702 1.55a.692.692 0 0 0-.676.477.681.681 0 1 0 1.157-.252c.073-.141.141-.282.214-.431.19-.397.515-1.16.515-1.16.035-.066.218-.394.103-.814-.095-.435-.48-.638-.48-.638-.467-.301-1.116-.58-1.116-.58s0-.156-.042-.27a.688.688 0 0 0-.148-.241l.516-1.062 2.89 1.401s.48.218.583.619c.073.282-.019.534-.069.657-.24.587-2.1 4.317-2.1 4.317s-.232.554-.748.588a1.065 1.065 0 0 1-.393-.045l-.202-.08-4.31-2.1s-.417-.218-.49-.596c-.083-.31.104-.691.104-.691l2.073-4.272s.183-.37.466-.497a.855.855 0 0 1 .35-.077z"/></svg>
|
||
</a>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="https://github.com/anon-planet" target="_blank" rel="noopener" title="Github" class="md-social__link">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>
|
||
</a>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="https://gitlab.com/anonymousplanetorg" target="_blank" rel="noopener" title="Gitlab" class="md-social__link">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m23.6 9.593-.033-.086L20.3.98a.851.851 0 0 0-.336-.405.875.875 0 0 0-1 .054.875.875 0 0 0-.29.44L16.47 7.818H7.537L5.332 1.07a.857.857 0 0 0-.29-.441.875.875 0 0 0-1-.054.859.859 0 0 0-.336.405L.433 9.502l-.032.086a6.066 6.066 0 0 0 2.012 7.01l.01.009.03.021 4.977 3.727 2.462 1.863 1.5 1.132a1.008 1.008 0 0 0 1.22 0l1.499-1.132 2.461-1.863 5.006-3.75.013-.01a6.068 6.068 0 0 0 2.01-7.002z"/></svg>
|
||
</a>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="https://codeberg.org/anonymousplanet" target="_blank" rel="noopener" title="Codeberg" class="md-social__link">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11.955.49A12 12 0 0 0 0 12.49a12 12 0 0 0 1.832 6.373L11.838 5.928a.187.14 0 0 1 .324 0l10.006 12.935A12 12 0 0 0 24 12.49a12 12 0 0 0-12-12 12 12 0 0 0-.045 0zm.375 6.467 4.416 16.553a12 12 0 0 0 5.137-4.213z"/></svg>
|
||
</a>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
|
||
</div>
|
||
<div class="md-dialog" data-md-component="dialog">
|
||
<div class="md-dialog__inner md-typeset"></div>
|
||
</div>
|
||
|
||
|
||
<script id="__config" type="application/json">{"base": "../..", "features": ["navigation.instant", "navigation.instant.prefetch", "navigation.tabs", "navigation.sections", "toc.integrate", "navigation.top", "search.suggest", "search.highlight", "content.tabs.link", "content.code.annotation", "content.code.copy"], "search": "../../assets/javascripts/workers/search.b8dbb3d2.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script>
|
||
|
||
|
||
<script src="../../assets/javascripts/bundle.1e8ae164.min.js"></script>
|
||
|
||
|
||
</body>
|
||
</html> |