Publishing and GitHub
How an approved idea actually becomes a live page - the pull request, the checks, and who presses merge.
On this page
DispatchSEO never touches your live site directly. Everything it ships goes through GitHub, as a pull request, checked before it merges. This page covers the mechanics: what opens the PR, what decides whether it merges itself, and what happens after.
The flow
- You (or auto mode) approve a suggestion in the queue.
- The builder picks up the oldest approved idea and opens a pull request
against your site's own repo, labeled
seo. - Automated checks run against it - your repo's own build, a preview deploy, a code review pass, and for tools a live functional test (below).
- You review it, or it merges itself. Either way, once it merges, the page goes live on your site's next deploy.
Never a direct push to your main branch. The label and the pull request are the review surface - even in fully automatic mode, "merged a green PR" is a different, safer claim than "committed straight to main," because it means every gate below actually ran and passed before anything shipped.
Publish modes
Whether that merge needs you is a per-project setting, not a fixed behavior:
- Semi-automatic (recommended to start): your agent researches and builds on its own, but a PR only ships once you press Merge on the dashboard.
- Automatic: PRs whose checks all pass merge themselves. You watch the activity feed and can still undo from the dashboard.
Change it any time on Automations and modes, or from the dashboard's Semi/Auto toggle in the top bar - see Step 5 of the setup wizard for what it means when you first pick it. It's never a final answer.
Auto-merge mechanics
The actual merging - even in automatic mode - is done by
seo-auto-merge.yml, a workflow the pipeline installs into your repo. It
runs on an hourly schedule plus whenever a check reports, so a PR usually
merges within a minute of its last check finishing, not on the hour.
Each pass, for every open PR labeled seo:
- It checks whether the project's
auto_mergeautomation flag is actually on right now (read live from the dashboard) -offmeans every eligible PR just waits, checks and all. - It classifies the PR by shape: a guide PR must touch only files under
your repo's declared publish directories (
.dispatchseo/publish-paths, or the reference-stack defaults); a tool PR must carry thetool-validatedlabel from the validation workflow below. Anything else - a structural change, an unvalidated tool - waits for you no matter what the checks say. - It reads every check on the PR (your build, the preview deploy, code review) into one verdict: any check still pending waits for the next pass, any failing check leaves the PR for you, and zero checks reported is never treated as green - no gate is the same as an unsafe gate.
- Only when every check has actually passed does it squash-merge and delete the branch.
Tool validation
Guide PRs merge on the checks above. Tool PRs get one more gate first, run by
seo-tool-validate.yml: a real production build, started for real, opened
in a headless browser, with every interactive element on the new tool's page
actually clicked and checked - inputs filled, outputs verified, edge cases
(empty input, garbage input) confirmed not to break it, zero console errors.
Pass, and the PR gets a tool-validated label; fail, and it gets
tool-validation-failed plus a comment naming exactly what broke.
That label is what seo-auto-merge.yml looks for before it will touch a
tool PR at all - a widget that merely builds is not the same claim as a
widget that was proven to work.
Why validation holds no secrets
The validate job checks out and runs the tool PR's own code - code an LLM
wrote, in a PR that could in principle contain anything. So it deliberately
carries no secrets at all, not even the project's own MCP key: it can only
read and label, never merge or report outcomes. A separate merge job, on a
fresh runner that never checks out the PR's code, does the actual
squash-merge and phones the result home to the dashboard. Untrusted code and
write credentials never share a job.
The one-tap Merge button
On the dashboard (and over MCP via merge_pr), an open, green PR gets a
one-click Merge button - useful in semi-automatic mode, where you're
approving the merge yourself instead of waiting on the workflow above.
It needs a GitHub token with write access to your repo (GH_MERGE_TOKEN on
a classic install, or the pasted token from the wizard's GitHub step on
Docker). Without one, the button degrades to a plain link to the PR on
GitHub - you can still merge it there, DispatchSEO just can't do it for you.
On a Docker install using the bundled builder, this same token is also how
the builder reaches your repo at all to open PRs in the first place - see
Step 6 of the setup wizard for
what happens if it's skipped there.
After a PR merges
Three things happen automatically, no button to press:
- The page is logged (
log_page) - it enters the dashboard's Guides list and the internal-linking picture your agent reads before writing the next one. - Indexing is requested - the page joins the "Get it on Google" queue for a Search Console indexing request, and DispatchSEO starts checking whether Google actually picked it up.
- Its keyword starts being tracked - it joins the daily rank-check rotation, so its position shows up on Rankings without you doing anything further.
A freshly logged page shows as "awaiting publish" until its URL actually serves HTTP 200 - the merge and the live deploy aren't the same moment, and DispatchSEO waits for the real one before calling a page live.
Cloud vs self-host: connecting GitHub
The mechanics above are identical either way; only how DispatchSEO authenticates to your repo differs:
- Cloud: one-click install of the DispatchSEO GitHub App on your repo. The platform commits the pipeline and manages PRs through the App - no tokens to create or paste.
- Self-host: you generate a personal access token once
(
GH_MERGE_TOKEN, or pasted through the wizard) and DispatchSEO uses it for merging, and on a Docker install, for the builder's own clone-and-push access.
See Cloud or self-hosted for the full comparison, and Step 6 of the setup wizard for exactly what that step asks for on a self-hosted install.
Publishing pace
However fast ideas get approved, guides ship at a flat rate: at most one guide per UTC calendar day, permanently - not "while the site is new," a fixed ceiling. It's the single biggest protection against DispatchSEO ever reading as scaled, templated content: a queue of ten approved guides still surfaces as one PR a day, every day, whether the project is one week old or two years old. Tools aren't rate-limited the same way - a validated tool PR can ship the moment it passes.
DispatchSEO