MkDocs Material site that publishes four sections as one site at https://swe.springlee.dev, deployed on Cloudflare Pages.
Content sources live under content/:
| Section | Source | Tracked how |
|---|---|---|
| LeetCode Algorithms | content/leetcode-algorithms/ |
git submodule → leetcode-algorithms |
| SWE Interview | content/swe/ |
in this repo |
| System Design | content/system-design/ |
in this repo (vendored from liquidslr/system-design-notes) |
| Real Interview Questions | content/real-interview-questions/ |
in this repo |
Three of the four sections are edited here directly. Only LeetCode stays a separate repo, because it has its own GitBook publication, PR workflow and solution-generation tooling.
scripts/prepare.shcopiescontent/*intodocs/leetcode/,docs/swe/,docs/system-design/anddocs/real-interview-questions/, relocates GitBook assets to_assets/, and converts each source's GitBookSUMMARY.mdinto mkdocs-literate-nav format viascripts/convert_summary.py.docs/SUMMARY.mddefines the top-level tabs (Home / LeetCode Algorithms / SWE Interview / System Design / Real Interview Questions); each section's nav comes from its converted SUMMARY.sweandreal-interview-questionsare copied the same way — every*.mdexceptSUMMARY.mdand their ownCLAUDE.md— so maintenance docs stay out of the published site.system-designhas no SUMMARY.md, soscripts/gen_nav.pygenerates one from itsNN. Chapter Name/README.mdfolders, ordered by the numeric prefix and labelled with each chapter's H1. It also mixesReadme.mdandREADME.mdcasing;prepare.shnormalises it, because only an exactREADME.mdbecomes a directory index and the chapters' raw<img src="./images/...">tags resolve only from that index URL.- Math: content uses GitBook-style inline
$$O(...)$$; rendered client-side by KaTeX auto-render (docs/javascripts/katex.js).
git clone --recurse-submodules https://github.com/software-engineer-learning/swe-site.git
# already cloned without it:
git submodule update --init --recursive
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
bash scripts/prepare.sh
.venv/bin/mkdocs serve # http://127.0.0.1:8000Edit content/swe/, content/system-design/ and
content/real-interview-questions/ in place, then re-run prepare.sh. Never edit
under docs/ — prepare.sh wipes those four directories on every run.
To pull new LeetCode solutions into your checkout:
git submodule update --remote content/leetcode-algorithmsThe submodule pointer committed here is intentionally allowed to go stale — CI
always builds the submodule's latest main (see below), so bumping the pointer is
optional housekeeping rather than a release step.
Deploys are done by GitHub Actions (.github/workflows/deploy.yml), not by
Cloudflare's Git integration — do not also connect the repo in the Cloudflare
dashboard or every change would build twice. The workflow checks out submodules,
runs git submodule update --remote on the LeetCode submodule so the newest
solutions are published, builds the site, and uploads it with
wrangler pages deploy. It runs on:
- pushes to
mainof this repo — which now covers every edit to the SWE, System Design and Real Interview Questions sections, repository_dispatchevents of typecontent-updated, fired byleetcode-algorithms'gitbook.ymlworkflow on its content pushes,- manual runs (
workflow_dispatch).
content/system-design/ is a vendored copy of our fork of the third-party
liquidslr/system-design-notes.
Because it is vendored rather than cloned at build time, syncing the fork no longer
reaches the site on its own — pull upstream changes in by hand:
gh repo sync software-engineer-learning/system-design-notes --source liquidslr/system-design-notes
git clone --depth 1 https://github.com/software-engineer-learning/system-design-notes.git /tmp/sd
rsync -a --delete --exclude '.git/' --exclude '.github/' /tmp/sd/ content/system-design/
bash scripts/prepare.sh && .venv/bin/mkdocs build --strictReview the diff before committing — vendoring is what keeps third-party edits from landing on the site unreviewed.
-
Create the Pages project (Direct Upload):
npx wrangler pages project create swe-site --production-branch=main
(or Cloudflare dashboard → Workers & Pages → Create → Pages → Direct Upload.)
-
In this repo's GitHub settings → Secrets and variables → Actions, add:
CLOUDFLARE_ACCOUNT_ID— dashboard → Workers & Pages → right sidebar.CLOUDFLARE_API_TOKEN— dashboard → My Profile → API Tokens → Create Token → "Edit Cloudflare Workers"-style custom token with Account → Cloudflare Pages → Edit permission.
-
SITE_DISPATCH_TOKEN— a classic PAT with thereposcope on an account that can write tosoftware-engineer-learning/swe-site, held as an organization-level secret. Onlyleetcode-algorithmsstill needs it, since it is the one content repo left outside this one. Write access is what authorizesrepository_dispatch.Don't use a Cloudflare Pages deploy hook here. This project is Direct Upload, so a hook has no repo to clone and no build command to run — it re-serves the assets already uploaded and returns
success: truewhile the content stays stale. Deploy hooks only build on Git-connected Pages projects, and connecting this repo would make every change build twice. -
After the first deploy: Pages project → Custom domains → Add →
swe.springlee.dev. With thespringlee.devzone on Cloudflare, the CNAME and TLS are automatic.
- Put the markdown under
content/<section>/(or add a submodule there). - In
scripts/prepare.sh: add a<x>_srcvariable, an entry in the existence check, therm -rf/mkdir -pentries, a copy block, aconvert_summary.pycall writingdocs/<section>/SUMMARY.md, and the dir in the final page-countfindand thenormalize_fences.pycall. - Add the tab to
docs/SUMMARY.mdand a bullet todocs/index.md. - Add the section to the table above.