← Back to SRDD entry page
This page describes how the SRDD documentation is structured, built, and published.
All documentation lives as Markdown files in the ./documentation directory of the GitHub repository. This is the single source of truth.
documentation/
├── index.md # Entry point / overview
├── pitches.md # Various length summaries
├── SRDD-part1-of-4.md # Article series
├── SRDD-part2-of-4.md
├── SRDD-part3-of-4.md
├── SRDD-part4-of-4.md
├── CONTRIBUTING.md # Contribution guide
├── about.md # This file
└── .sync-state.json # Dev.to sync state (auto-generated)
Each Markdown file uses YAML front matter for metadata (title, description, etc.) and standard GitHub-flavored Markdown for content.
Documents use a placeholder syntax for internal links:
See [Part 1](/srdd/SRDD-part1-of-4.html) for details.
The ./slug.md pattern gets transformed differently depending on the target platform:
| Platform | Transformation |
|---|---|
| GitHub Pages | ./slug.md → ./slug.md |
| Dev.to | ./slug.md → actual Dev.to URL (e.g., https://dev.to/bbos/...) |
This allows documents to link to each other without hard-coding URLs that differ across platforms.
A single workflow (.github/workflows/deploy-and-sync.yml) handles all publishing:
- name: Transform devto placeholders for GHP
run: |
find ./documentation -name "*.md" -exec sed -i -E \
's/\{\{devto:([^}]+)\}\}/.\/\1.md/g' {} \;
- name: Build with Jekyll
uses: actions/jekyll-build-pages@v1
with:
source: ./documentation
destination: ./_site
The pipeline:
./slug.md placeholders to relative .md linksAfter GitHub Pages deployment completes:
sync-to-devto:
needs: deploy # Run after deploy so canonical URLs are live
steps:
- name: Sync posts to Dev.to
env:
DEVTO_API_KEY: $
SITE_URL: $
The sync script (scripts/sync-to-devto/sync-to-devto.js) performs a two-pass sync:
For each Markdown file:
Dev.to generates URLs with unpredictable suffixes (e.g., my-post-4k2n). After Pass 1, we have a map of slug → actual URL. Pass 2:
./slug.md placeholders// URL map built during Pass 1
{
"index": "https://dev.to/bbos/srdd-is-the-best...-4k2n",
"SRDD-part1-of-4": "https://dev.to/bbos/why-srdd-exists-2j8m",
// ...
}
This two-pass approach ensures all cross-references resolve correctly despite Dev.to’s dynamic URL generation.
The sync script only uploads posts that have changed, reducing API calls and speeding up the pipeline.
How it works:
documentation/.sync-state.json// .sync-state.json
{
"index": { "hash": "a1b2c3d4e5f67890...", "syncedAt": "2026-01-07T10:00:00Z", "url": "https://dev.to/bbos/srdd-...-4k2n" },
"pitches": { "hash": "f0e1d2c3b4a59687...", "syncedAt": "2026-01-07T10:00:00Z", "url": "https://dev.to/bbos/pitches-...-2j8m" }
}
The url field caches each article’s Dev.to URL, enabling placeholder resolution even when API rate limits prevent fetching URLs.
Force full sync:
To sync all posts regardless of changes, set the FORCE_SYNC environment variable:
env:
FORCE_SYNC: 'true'
Or run locally with the --force flag:
node sync-to-devto.js --force
# Or with .env file (loads DEVTO_API_KEY, SITE_URL, etc.)
export $(grep -v '^#' .env | xargs) && node sync-to-devto.js --force
Refresh URL cache:
Dev.to URLs are cached in sync state. To refresh the cache (useful if articles were renamed or URLs changed):
env:
REFRESH_URLS: 'true'
Or run locally:
node sync-to-devto.js --refresh-urls
# Or with .env file
export $(grep -v '^#' .env | xargs) && node sync-to-devto.js --refresh-urls
Every article on Dev.to includes a canonical_url pointing to the GitHub Pages version:
canonical_url: https://docs-bbos.github.io/srdd/SRDD-part1-of-4/
This tells search engines that GitHub Pages is the authoritative source. Benefits:
To add a new page:
documentation/new-page.md with appropriate front matter./new-page.mdmainThe pipeline requires:
| Secret/Variable | Purpose |
|---|---|
DEVTO_API_KEY |
Dev.to API key from dev.to/settings/extensions |
SITE_URL |
GitHub Pages URL (e.g., https://docs-bbos.github.io/srdd) |
This infrastructure enables “write once, publish everywhere” for living documentation that evolves with the methodology.