From c01af92c320b3e7866bbf657d9c6f97e1e201494 Mon Sep 17 00:00:00 2001 From: Maxim Salnikov Date: Sun, 20 Sep 2026 17:41:53 +0200 Subject: [PATCH] Gate book PDF downloads behind Substack Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/prompts/release-content.prompt.md | 2 +- .github/workflows/deploy-pages.yml | 7 ++- .gitignore | 6 +-- README.md | 21 ++++---- scripts/README.md | 2 +- site/book.html | 4 +- site/chapters/anatomy-and-compile-model.html | 4 +- .../continuous-review-and-testing.html | 4 +- site/chapters/continuous-triage-and-docs.html | 4 +- site/chapters/defense-in-depth.html | 4 +- site/chapters/engines.html | 4 +- site/chapters/fleets-and-adoption.html | 4 +- site/chapters/governance-and-finops.html | 4 +- .../chapters/observability-and-debugging.html | 4 +- site/chapters/reuse-and-memory.html | 4 +- site/chapters/safe-outputs.html | 4 +- site/chapters/tools-and-mcp.html | 4 +- site/chapters/triggers.html | 4 +- site/chapters/what-are-agentic-workflows.html | 4 +- site/chapters/your-first-workflow.html | 4 +- site/generate.py | 51 +++++++++++-------- site/index.html | 6 +-- site/llms-full.txt | 2 +- site/llms.txt | 2 +- site/sitemap.xml | 32 ++++++------ site/versions.html | 17 +++---- 26 files changed, 109 insertions(+), 99 deletions(-) diff --git a/.github/prompts/release-content.prompt.md b/.github/prompts/release-content.prompt.md index 0bebdb2..0e196c0 100644 --- a/.github/prompts/release-content.prompt.md +++ b/.github/prompts/release-content.prompt.md @@ -91,7 +91,7 @@ refresh, first run `.github/prompts/update-book.prompt.md`. ## After the human merges `validate-book.yml` builds and gates the exact artifacts consumed by both publishing -workflows. `deploy-pages.yml` publishes that site/PDF without rebuilding; +workflows. `deploy-pages.yml` publishes the online site without the gated PDF; `release-content.yml` creates `content-v` with the matching `gh-aw-book-v.pdf` and changelog notes. Verify both workflow outcomes, the release asset, and the live version-history page before calling the edition published. diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml index f192f05..32776b4 100644 --- a/.github/workflows/deploy-pages.yml +++ b/.github/workflows/deploy-pages.yml @@ -39,13 +39,16 @@ jobs: permissions: contents: write steps: - - name: Download the validated site, analytics beacon, and PDF + - name: Download the validated site and analytics beacon uses: actions/download-artifact@v4 with: name: validated-pages path: artifact - - name: Publish the exact validated site to gh-pages + - name: Remove the gated PDF from the public site + run: rm -f artifact/site/gh-aw-book.pdf + + - name: Publish the validated site to gh-pages run: | cd artifact/site touch .nojekyll diff --git a/.gitignore b/.gitignore index b70c8f3..3fce241 100644 --- a/.gitignore +++ b/.gitignore @@ -14,9 +14,9 @@ __pycache__/ dist/ build/ -# Downloadable book PDF — a binary build artifact rendered from site/book.html by -# scripts/build_pdf.py (in CI on every deploy, and locally on demand). It is -# published to gh-pages but not committed to main. +# Book PDF — a binary build artifact rendered from site/book.html by +# scripts/build_pdf.py for release assets and local use. It is not committed to main +# or published on the public website. site/gh-aw-book.pdf # Playwright browser-download marker (browsers install to a shared cache, not here) diff --git a/README.md b/README.md index 74cf02c..d4b27b9 100644 --- a/README.md +++ b/README.md @@ -256,13 +256,14 @@ python scripts\verify_examples.py --compiler --- -## Download the book as a PDF +## Get the book as a PDF -The whole book is also available as a **single downloadable PDF**, linked from the site (home page -"Download PDF", the reader nav, and every chapter). It is rendered from a **single-page edition** -(`site/book.html`, which `site/generate.py` produces alongside the chapter pages) using headless -Chromium via [Playwright](https://playwright.dev/python/), so code blocks keep their syntax -highlighting and the PDF carries page numbers and a chapter outline. +The whole book is available as a **single downloadable PDF** through the +[Substack download page](https://isainative.substack.com/p/free-agentic-workflows-book). The +website links to that gated page rather than publishing the PDF directly. The PDF is rendered from +a **single-page edition** (`site/book.html`, which `site/generate.py` produces alongside the chapter +pages) using headless Chromium via [Playwright](https://playwright.dev/python/), so code blocks keep +their syntax highlighting and the PDF carries page numbers and a chapter outline. ```powershell # 1. (re)generate the site, including site/book.html (the PDF's source) @@ -275,10 +276,10 @@ python scripts/build_pdf.py ``` The PDF (`site/gh-aw-book.pdf`) is a **binary build artifact**: it is gitignored, not committed to -`main`. On every push that changes the book, the deploy workflow -([`.github/workflows/deploy-pages.yml`](.github/workflows/deploy-pages.yml)) regenerates it right -after `generate.py` and publishes it to the live site — so the downloadable PDF always matches the -current book. +`main`, and removed before the site is published. The deploy workflow +([`.github/workflows/deploy-pages.yml`](.github/workflows/deploy-pages.yml)) still validates the +single-page source and release tooling, while the public site sends readers to the gated Substack +page. --- diff --git a/scripts/README.md b/scripts/README.md index e40a548..fca4aa5 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -135,7 +135,7 @@ not committed sources. helpers, release/evidence contract, pinned whole-corpus compilation, and HTML/PDF generation. The PR still needs human review/merge; these workflows do not configure branch protection. -After merge, `deploy-pages.yml` publishes the current online/PDF edition and +After merge, `deploy-pages.yml` publishes the current online edition and `release-content.yml` publishes its matching tag, changelog notes, and versioned PDF. Both consume the exact artifacts produced by validation instead of rebuilding afterward. The release workflow also evaluates content/example/tooling pushes; a complete existing diff --git a/site/book.html b/site/book.html index b718ef8..748d0b2 100644 --- a/site/book.html +++ b/site/book.html @@ -120,7 +120,7 @@ @@ -130,7 +130,7 @@

GitHub Agentic Workflows

A progressive guide that starts with agentic-workflow concepts and builds toward GitHub Agentic Workflows authoring, compilation, MCP tools, safe outputs, and CI hosting.

By Maxim Salnikov · Microsoft

-

Content edition v1.2 · 14 chapters · Single-page edition · Generated 2026-09-16

+

Content edition v1.2 · 14 chapters · Single-page edition · Generated 2026-09-20

Verified with gh-aw v0.88.7

diff --git a/site/chapters/anatomy-and-compile-model.html b/site/chapters/anatomy-and-compile-model.html index 7c55504..69f2ae2 100644 --- a/site/chapters/anatomy-and-compile-model.html +++ b/site/chapters/anatomy-and-compile-model.html @@ -99,7 +99,7 @@
- +

chapter: 03·part: The Individual (one workflow)

Anatomy & the Compile Model

Read any workflow's frontmatter + Markdown, run the compile-and-iterate loop, and understand what the generated .lock.yml contains.

@@ -371,7 +371,7 @@

-

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Download the PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

+

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Get the free PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

diff --git a/site/chapters/continuous-review-and-testing.html b/site/chapters/continuous-review-and-testing.html index 840a120..9d10fd4 100644 --- a/site/chapters/continuous-review-and-testing.html +++ b/site/chapters/continuous-review-and-testing.html @@ -99,7 +99,7 @@
- +

chapter: 10·part: The Team (safe, reviewed, patterned)

Continuous Review, Testing & CI-Doctor

Close the quality loop with Review, Testing, CI-Doctor, and Refactoring patterns while keeping humans on the merge decision.

@@ -383,7 +383,7 @@

-

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Download the PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

+

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Get the free PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

diff --git a/site/chapters/continuous-triage-and-docs.html b/site/chapters/continuous-triage-and-docs.html index b0abf90..5f881d0 100644 --- a/site/chapters/continuous-triage-and-docs.html +++ b/site/chapters/continuous-triage-and-docs.html @@ -99,7 +99,7 @@
- +

chapter: 09·part: The Team (safe, reviewed, patterned)

Continuous Triage & Docs: Reading the Room

Ship two production-shaped patterns — Continuous Triage and Continuous Docs — as mini-products the Repo Assistant runs on its own.

@@ -418,7 +418,7 @@

-

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Download the PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

+

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Get the free PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

diff --git a/site/chapters/defense-in-depth.html b/site/chapters/defense-in-depth.html index 3e70b53..333565a 100644 --- a/site/chapters/defense-in-depth.html +++ b/site/chapters/defense-in-depth.html @@ -99,7 +99,7 @@
- +

chapter: 07·part: The Team (safe, reviewed, patterned)

Defense in Depth: Permissions, Firewall & Strict Mode

Reduce a workflow's authority and exposure with least-privilege permissions, runtime isolation, egress controls, and strict mode while explaining the remaining risks.

@@ -376,7 +376,7 @@

-

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Download the PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

+

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Get the free PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

diff --git a/site/chapters/engines.html b/site/chapters/engines.html index 662da8d..35afa64 100644 --- a/site/chapters/engines.html +++ b/site/chapters/engines.html @@ -99,7 +99,7 @@
- +

chapter: 05·part: The Individual (one workflow)

Engines: Choosing the Agent's Brain

Select and configure Copilot, Claude, Codex, Gemini, or Pi, control CLI/model selection, and distinguish portable intent from engine-specific runtime requirements.

@@ -336,7 +336,7 @@

-

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Download the PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

+

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Get the free PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

diff --git a/site/chapters/fleets-and-adoption.html b/site/chapters/fleets-and-adoption.html index 02ca897..1101830 100644 --- a/site/chapters/fleets-and-adoption.html +++ b/site/chapters/fleets-and-adoption.html @@ -99,7 +99,7 @@
- +

chapter: 14·part: The Organization (fleet at scale)

Fleets & Adoption: From One Repo to the Org

Scale the Repo Assistant into a governed multi-repo fleet and follow an enterprise adoption playbook to roll it out.

@@ -395,7 +395,7 @@

-

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Download the PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

+

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Get the free PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

diff --git a/site/chapters/governance-and-finops.html b/site/chapters/governance-and-finops.html index 88aca98..e97cbc6 100644 --- a/site/chapters/governance-and-finops.html +++ b/site/chapters/governance-and-finops.html @@ -99,7 +99,7 @@
- +

chapter: 13·part: The Organization (fleet at scale)

Governance & FinOps: Policy and Cost at Scale

Separate agent, detector, admission, and compute costs; apply scoped budgets and policy; and use forecasts without mistaking them for a complete bill cap.

@@ -421,7 +421,7 @@

-

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Download the PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

+

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Get the free PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

diff --git a/site/chapters/observability-and-debugging.html b/site/chapters/observability-and-debugging.html index 93fc183..e26299a 100644 --- a/site/chapters/observability-and-debugging.html +++ b/site/chapters/observability-and-debugging.html @@ -99,7 +99,7 @@
- +

chapter: 12·part: The Organization (fleet at scale)

Trust & Operate: Observability and Debugging

Inspect, debug, and audit runs with gh aw logs, gh aw audit, and OpenTelemetry so you can trust what the fleet does.

@@ -372,7 +372,7 @@

-

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Download the PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

+

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Get the free PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

diff --git a/site/chapters/reuse-and-memory.html b/site/chapters/reuse-and-memory.html index ba1f6e1..91cf48c 100644 --- a/site/chapters/reuse-and-memory.html +++ b/site/chapters/reuse-and-memory.html @@ -99,7 +99,7 @@
- +

chapter: 11·part: The Organization (fleet at scale)

Reuse & Memory: Shared Components and Repo Knowledge

Factor common intent into imported shared components and give the Repo Assistant memory that persists across runs.

@@ -418,7 +418,7 @@

-

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Download the PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

+

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Get the free PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

diff --git a/site/chapters/safe-outputs.html b/site/chapters/safe-outputs.html index 7256dc2..f986273 100644 --- a/site/chapters/safe-outputs.html +++ b/site/chapters/safe-outputs.html @@ -99,7 +99,7 @@
- +

chapter: 06·part: The Team (safe, reviewed, patterned)

Safe Outputs: Acting Without Overreach

Let the Repo Assistant write to the repo — issues, comments, PRs — through the sanitized safe-outputs boundary instead of raw permissions.

@@ -339,7 +339,7 @@

-

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Download the PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

+

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Get the free PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

diff --git a/site/chapters/tools-and-mcp.html b/site/chapters/tools-and-mcp.html index 73d719b..c7c96bb 100644 --- a/site/chapters/tools-and-mcp.html +++ b/site/chapters/tools-and-mcp.html @@ -99,7 +99,7 @@
- +

chapter: 08·part: The Team (safe, reviewed, patterned)

Tools & MCP: Real Capabilities, Governed

Give the Repo Assistant real capabilities with the tools: block and MCP servers while keeping every capability governed.

@@ -325,7 +325,7 @@

-

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Download the PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

+

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Get the free PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

diff --git a/site/chapters/triggers.html b/site/chapters/triggers.html index a925006..05519aa 100644 --- a/site/chapters/triggers.html +++ b/site/chapters/triggers.html @@ -99,7 +99,7 @@
- +

chapter: 04·part: The Individual (one workflow)

Triggers: When Workflows Wake Up

Choose repository events and admission controls for the Repo Assistant's intended work without assuming punctual or exclusive execution.

@@ -438,7 +438,7 @@

-

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Download the PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

+

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Get the free PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

diff --git a/site/chapters/what-are-agentic-workflows.html b/site/chapters/what-are-agentic-workflows.html index bf560ec..5f17df1 100644 --- a/site/chapters/what-are-agentic-workflows.html +++ b/site/chapters/what-are-agentic-workflows.html @@ -99,7 +99,7 @@
- +

chapter: 01·part: The Individual (one workflow)

What Are Agentic Workflows?

Explain what an agentic workflow is, why the outer loop matters, and when to reach for gh-aw instead of plain GitHub Actions.

@@ -303,7 +303,7 @@

-

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Download the PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

+

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Get the free PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

diff --git a/site/chapters/your-first-workflow.html b/site/chapters/your-first-workflow.html index 1840e00..9e1b74a 100644 --- a/site/chapters/your-first-workflow.html +++ b/site/chapters/your-first-workflow.html @@ -99,7 +99,7 @@
- +

chapter: 02·part: The Individual (one workflow)

The 10-Minute Win: Your First Workflow

Install the gh aw CLI and ship a first working Repo Assistant that triages a new issue end to end.

@@ -447,7 +447,7 @@

-

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Download the PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

+

By Maxim Salnikov · Microsoft · LinkedIn · Book repository on GitHub ↗ · Get the free PDF · Content edition v1.2 · Verified with gh-aw v0.88.7

diff --git a/site/generate.py b/site/generate.py index 40f6d20..75b4498 100644 --- a/site/generate.py +++ b/site/generate.py @@ -48,13 +48,12 @@ GH_AW_DOCS = "https://github.github.com/gh-aw/" GH_AW_REPO = "https://github.com/github/gh-aw" -# Downloadable editions ------------------------------------------------------- +# Book editions --------------------------------------------------------------- # book.html is the single-page "print edition" (all chapters on one page), emitted -# by render_book(); it is also the source Playwright renders into the PDF. -# gh-aw-book.pdf is a binary BUILD ARTIFACT: it is gitignored and produced by -# scripts/build_pdf.py (locally and in CI), not committed to main. +# by render_book(). The downloadable PDF is gated through Substack. BOOK_PAGE = "book.html" -PDF_FILENAME = "gh-aw-book.pdf" +BOOK_DOWNLOAD_URL = "https://isainative.substack.com/p/free-agentic-workflows-book" +BOOK_DOWNLOAD_LABEL = "Get the free PDF" # Content edition version -------------------------------------------------------- # The book is a living document: its prose (content/) is versioned independently of the @@ -229,6 +228,15 @@ def framework_link(css_class: str = "") -> str: ) +def book_download_link(css_class: str = "") -> str: + """Link readers to the gated PDF download page.""" + class_attr = f' class="{esc(css_class)}"' if css_class else "" + return ( + f'{esc(BOOK_DOWNLOAD_LABEL)}' + ) + + def version_meta() -> str: """Keep prose and framework versions distinct in every edition's HTML metadata.""" return ( @@ -558,7 +566,7 @@ def render_index(grouped: list[dict[str, Any]]) -> str: aw gh-aw \u00b7 the book