Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
218 commits
Select commit Hold shift + click to select a range
71352bf
Updating dependencies
jorgemoralespou Apr 15, 2026
06a2cb2
docs: add the educates.dev glossary
jorgemoralespou Oct 7, 2026
06a41b3
docs: record ADRs 0001 and 0002 and keep docs/adr off the site
jorgemoralespou Oct 7, 2026
81a8892
docs: add Educates Hub and rename the Content hub to the Learn page
jorgemoralespou Oct 7, 2026
9ad3a3c
docs: update ADR 0001 for the diagram enlarge script and the Learn page
jorgemoralespou Oct 7, 2026
2437543
build: replace Docusaurus with a plain Astro 7 project
jorgemoralespou Oct 7, 2026
9f889c5
feat: add the site check and the must-resolve list
jorgemoralespou Oct 7, 2026
82bdbc4
feat: fail the site check on a missing or malformed canonical URL
jorgemoralespou Oct 7, 2026
49b6b14
feat: serve one /sitemap.xml and check that it lists pages only
jorgemoralespou Oct 7, 2026
7708fdd
feat: add the design tokens, the theme toggle and global styles
jorgemoralespou Oct 7, 2026
e0b2c58
feat: add the base layout, a placeholder homepage and the 404 page
jorgemoralespou Oct 7, 2026
dd53332
chore: move the workflows, Dockerfile and dev container to npm
jorgemoralespou Oct 7, 2026
e5da532
feat: fail the site check on anything built under /hub
jorgemoralespou Oct 7, 2026
7ec0110
feat: add a site-check rule for redirect pages
jorgemoralespou Oct 7, 2026
bf0f57b
feat: report stub pages in the site check
jorgemoralespou Oct 7, 2026
43ec2ee
feat: add the 4.0 and GitHub Sponsors settings, both off
jorgemoralespou Oct 7, 2026
ba2dc89
build: preview the site in Docker the way GitHub Pages serves it
jorgemoralespou Oct 7, 2026
fa4da9d
ci: check every pull request against the built site
jorgemoralespou Oct 7, 2026
e819c0b
ci: deploy with withastro/action and deploy-pages v5
jorgemoralespou Oct 7, 2026
f3215b4
ci: list dead external links weekly in one issue
jorgemoralespou Oct 7, 2026
5981baf
ci: update npm and GitHub Actions dependencies weekly
jorgemoralespou Oct 7, 2026
9c1a26a
docs: describe the CI, the link check and the Docker targets
jorgemoralespou Oct 7, 2026
fec478e
feat: add the use case and Feature collections
jorgemoralespou Oct 7, 2026
d95e793
feat: add the header menus, the phone sheet and the footer
jorgemoralespou Oct 7, 2026
061a782
feat: show breadcrumbs on section pages
jorgemoralespou Oct 7, 2026
8aa5bdf
feat: stub every page of the inventory not yet built
jorgemoralespou Oct 7, 2026
5f45fd2
feat: redirect /team, /resources and /docs, checked by the site check
jorgemoralespou Oct 7, 2026
1b5eddf
Merge branch 'update-site' into worktree-agent-a26115ecea333e266
jorgemoralespou Oct 7, 2026
2f33573
feat: build the CLI download links from the release asset names
jorgemoralespou Oct 7, 2026
5601e03
feat: show Support the project only while the Sponsors listing is public
jorgemoralespou Oct 7, 2026
a9dfed8
build: render Markdown code blocks with expressive-code, and add MDX
jorgemoralespou Oct 7, 2026
7a7bc0d
feat: arrange the Getting Started Guides as one numbered path
jorgemoralespou Oct 7, 2026
a9a8ed7
feat: add a Tabs component for alternative instructions
jorgemoralespou Oct 7, 2026
9a38d2e
feat: add the project page layout, cards, arrow links and command blocks
jorgemoralespou Oct 7, 2026
36024da
feat: build the Get started page
jorgemoralespou Oct 7, 2026
b9a31fa
feat: build the Get help page
jorgemoralespou Oct 7, 2026
40c0922
feat: build the Community page
jorgemoralespou Oct 7, 2026
4a1e169
feat: build the Downloads page
jorgemoralespou Oct 7, 2026
5ebc7ef
feat: add the docs layout for the guides and About Educates
jorgemoralespou Oct 7, 2026
a1a2028
Merge branch 'update-site' into worktree-agent-aaef6557cfd6fd192
jorgemoralespou Oct 7, 2026
b2c8640
test: keep the guide path tests with the other src/lib tests
jorgemoralespou Oct 7, 2026
900820a
feat: add Feature helpers for jobs, 4.0 gating and homepage selection
jorgemoralespou Oct 7, 2026
f529459
feat: give Features a docs link, a visual, 4.0 fields and a homepage …
jorgemoralespou Oct 7, 2026
36888ec
fix: describe the AI authoring skills as their READMEs do
jorgemoralespou Oct 7, 2026
b122a43
feat: add the other 17 Features to the Feature collection
jorgemoralespou Oct 7, 2026
d112466
feat: build the Features overview at /features
jorgemoralespou Oct 7, 2026
5e7c1ae
Merge branch 'update-site' into worktree-agent-af7ea04f60793e707
jorgemoralespou Oct 7, 2026
b6226b2
feat: serve the Getting Started Guides from a content collection
jorgemoralespou Oct 7, 2026
34bbb89
feat: merge Components and CRDs into "What you just installed"
jorgemoralespou Oct 7, 2026
9dc56f4
feat: add Next steps as the guides' fourth part
jorgemoralespou Oct 7, 2026
14efb73
docs: correct the guides' commands and claims
jorgemoralespou Oct 7, 2026
f3ea78b
fix: align the docs sidebar's heading with its items
jorgemoralespou Oct 7, 2026
2375bd9
chore: drop the old guides folder from the Prettier ignore list
jorgemoralespou Oct 7, 2026
38dc53f
build: add MDX, React, Expressive Code and the Asciinema player
jorgemoralespou Oct 7, 2026
2170182
feat: render admonitions and code blocks in Markdown and MDX
jorgemoralespou Oct 7, 2026
320a17c
Merge branch 'update-site' into worktree-agent-aaef6557cfd6fd192
jorgemoralespou Oct 7, 2026
9d44a21
feat: move blog posts, authors and tags into content collections
jorgemoralespou Oct 7, 2026
aeed7be
fix: correct links, a fence and stale comments in blog posts
jorgemoralespou Oct 7, 2026
dc3c2e3
feat: serve each blog post at /blog/<slug>
jorgemoralespou Oct 7, 2026
9b688e3
feat: list blog posts at /blog, by tag, by author and by year
jorgemoralespou Oct 7, 2026
f8a29c6
feat: play Asciinema casts in posts through a React island
jorgemoralespou Oct 7, 2026
0c7e554
feat: redirect /posts/ and /posts/installation-kind/ to the blog
jorgemoralespou Oct 7, 2026
6d512ff
docs: write copied posts to the posts collection
jorgemoralespou Oct 7, 2026
3030038
Merge branch 'update-site' into worktree-agent-a43b71554dc17d4c8
jorgemoralespou Oct 7, 2026
d532baa
style: format the blog index pages with Prettier
jorgemoralespou Oct 7, 2026
84542fd
feat: script the Session demo's loop and fixed states
jorgemoralespou Oct 7, 2026
28dd4cb
feat: add the Session demo component
jorgemoralespou Oct 7, 2026
8c1e793
feat: show the Session demo in the homepage hero
jorgemoralespou Oct 7, 2026
e4a7aa8
Merge branch 'update-site' into worktree-agent-a33a4280dd76b8e33
jorgemoralespou Oct 7, 2026
4a27725
Merge branch 'update-site' into worktree-agent-a43b71554dc17d4c8
jorgemoralespou Oct 7, 2026
6556045
refactor: keep the blog's unit tests in test folders
jorgemoralespou Oct 7, 2026
54e7b6a
Merge branch 'update-site' into worktree-agent-a43b71554dc17d4c8
jorgemoralespou Oct 7, 2026
f1b0980
build: render Mermaid diagrams in the browser with astro-mermaid
jorgemoralespou Oct 7, 2026
0d76b61
feat: name the theme in use in data-theme, so diagrams follow the system
jorgemoralespou Oct 7, 2026
967109e
Merge branch 'update-site' into worktree-agent-a1b04829952e8f51e
jorgemoralespou Oct 7, 2026
b216ed8
feat: fail the site check when a feed item's identity changes
jorgemoralespou Oct 7, 2026
819c0de
feat: fail the site check on a feed link a reader cannot follow
jorgemoralespou Oct 7, 2026
dae6ccf
feat: count page views with GoatCounter unless the visitor opted out
jorgemoralespou Oct 7, 2026
be64134
feat: fail the site check on a page that uses a frozen feed image
jorgemoralespou Oct 7, 2026
6002abc
feat: arrange About Educates' pages into the section's sidebar
jorgemoralespou Oct 7, 2026
17e5f1c
feat: write About Educates as three pages: Architecture, Workflows an…
jorgemoralespou Oct 7, 2026
4e40fdb
feat: redirect the old About pages to where their content went
jorgemoralespou Oct 7, 2026
e5263e6
feat: keep Hub workshop links in one file and look them up by id
jorgemoralespou Oct 7, 2026
a192551
feat: link Features by id from other pages
jorgemoralespou Oct 7, 2026
7639c89
feat: add the outside Content collection with its poster guard
jorgemoralespou Oct 7, 2026
1d7e074
feat: download video posters with npm run posters
jorgemoralespou Oct 7, 2026
0ec29b9
feat: add the two Google Cloud videos as outside Content
jorgemoralespou Oct 7, 2026
a5a99c2
feat: serve the blog's RSS and Atom feeds
jorgemoralespou Oct 7, 2026
1423ffa
feat: keep the images the old feeds embedded at their URLs
jorgemoralespou Oct 7, 2026
30a60ff
feat: add the use case template
jorgemoralespou Oct 7, 2026
91d28ae
feat: write the Hands-on events page
jorgemoralespou Oct 7, 2026
2ca042d
feat: write the Build your own Demo Platform page
jorgemoralespou Oct 7, 2026
3edfa17
feat: add a YouTube facade that loads nothing from Google before play
jorgemoralespou Oct 7, 2026
a745b62
feat: play the posts' YouTube videos through the facade
jorgemoralespou Oct 7, 2026
9a47b09
feat: show the blog feeds as a styled page in the browser
jorgemoralespou Oct 7, 2026
ce392f7
fix: name the gap in each use case docs link for screen readers
jorgemoralespou Oct 7, 2026
fbbe334
feat: enlarge a Mermaid diagram in a dialog, by click or keyboard
jorgemoralespou Oct 7, 2026
fb85b23
docs: name the About diagrams and redraw the architecture diagram
jorgemoralespou Oct 7, 2026
9cf4cab
feat: let browsers and readers discover the blog feeds from every page
jorgemoralespou Oct 7, 2026
e64e5f6
refactor: keep the feed size private to the feed module
jorgemoralespou Oct 7, 2026
9a54e40
docs: say the per-Session image registry needs Sessions served over H…
jorgemoralespou Oct 7, 2026
bef9d9d
Merge branch 'update-site' into worktree-agent-a1b04829952e8f51e
jorgemoralespou Oct 7, 2026
015070f
build: add satori 0.35.1 and sharp to draw Open Graph images
jorgemoralespou Oct 7, 2026
3942798
feat: draw Content covers in the Product window look
jorgemoralespou Oct 7, 2026
99da9e3
feat: give every page its own Open Graph image
jorgemoralespou Oct 7, 2026
ffb9290
feat: fail the site check when a page's og:image is missing
jorgemoralespou Oct 7, 2026
cec17c6
Merge the RSS and Atom feeds
jorgemoralespou Oct 7, 2026
ecec15f
docs: drop the timeline's accessible title, which Mermaid ignores
jorgemoralespou Oct 7, 2026
34e319a
Merge branch 'update-site' into worktree-agent-a1b04829952e8f51e
jorgemoralespou Oct 7, 2026
d3eee17
test: give the site-check command's fixture pages their Open Graph im…
jorgemoralespou Oct 7, 2026
6c7faba
feat: add the Content card
jorgemoralespou Oct 7, 2026
66f4baf
feat: list blog posts as Content cards
jorgemoralespou Oct 7, 2026
8d278be
Merge branch 'update-site' into worktree-agent-a638954adc88f26a0
jorgemoralespou Oct 7, 2026
4b013c6
style: draw the facade's play button in white over the poster
jorgemoralespou Oct 7, 2026
76cdd3b
feat: build the privacy page with a switch to turn counting off
jorgemoralespou Oct 7, 2026
139a2d1
Merge branch 'update-site' into worktree-agent-a1d25401ee81cd55a
jorgemoralespou Oct 7, 2026
fe43862
feat: let a use case capability switch its text and Features when Edu…
jorgemoralespou Oct 7, 2026
1f23cc1
feat: list the use cases that rely on a Feature
jorgemoralespou Oct 7, 2026
569ec70
refactor: look up a YouTube video's outside Content entry in one place
jorgemoralespou Oct 7, 2026
c849b43
feat: show the posts' YouTube videos as links in the blog feeds
jorgemoralespou Oct 7, 2026
fd9bf89
feat: fail the site check when a use case page says air-gapped before…
jorgemoralespou Oct 7, 2026
b577cfc
Merge the analytics, privacy page and YouTube facade
jorgemoralespou Oct 7, 2026
10cfa18
feat: add the Spring, virtual cluster and Git repository workshops to…
jorgemoralespou Oct 7, 2026
fd0070a
feat: let a use case page cite the Features overview as proof
jorgemoralespou Oct 7, 2026
b1246c4
feat: write the Customer and partner enablement page
jorgemoralespou Oct 7, 2026
bc9d7d3
feat: write the Team training page
jorgemoralespou Oct 7, 2026
c0fcffc
Merge branch 'update-site' into worktree-agent-a635886a5aee20585
jorgemoralespou Oct 7, 2026
7f8ce06
feat: add a muted video loop that loads behind its poster
jorgemoralespou Oct 7, 2026
c4d0014
feat: render a flagship Feature with a page on the deep page template
jorgemoralespou Oct 7, 2026
5174c65
feat: link the Hub's editor, examiner, namespace and vcluster showcases
jorgemoralespou Oct 7, 2026
9345d30
feat: write the clickable actions deep page
jorgemoralespou Oct 7, 2026
e4eb72d
feat: write the examiner checks deep page
jorgemoralespou Oct 7, 2026
206391c
feat: write the isolated Sessions deep page
jorgemoralespou Oct 7, 2026
0872299
feat: name clickable actions and examiner checks on Hands-on events
jorgemoralespou Oct 7, 2026
93c696e
feat: filter a list by facet groups kept in the query string
jorgemoralespou Oct 7, 2026
bb2d385
Merge branch 'update-site' into worktree-agent-a5a625c3a4eb1c770
jorgemoralespou Oct 7, 2026
2d2d754
feat: list the use cases that rely on a Feature for the release descr…
jorgemoralespou Oct 7, 2026
bc38437
feat: give an outside article the author its cover names
jorgemoralespou Oct 7, 2026
a68f917
feat: define the six Topics and tag the guides' parts
jorgemoralespou Oct 7, 2026
f5ceac0
feat: build every kind of Content as one entry with its Topics
jorgemoralespou Oct 7, 2026
77af4b3
feat: add the filter chips island
jorgemoralespou Oct 7, 2026
f610fff
feat: build the Learn page
jorgemoralespou Oct 7, 2026
36e6196
feat: list the launch talks and videos about Educates
jorgemoralespou Oct 7, 2026
9bf24b2
Merge branch 'update-site' into worktree-agent-ad53c3ce5a0f87d63
jorgemoralespou Oct 7, 2026
79926b9
feat: let a deep page cover other Features
jorgemoralespou Oct 7, 2026
9bec63f
feat: try a deep page's tool from its repositories
jorgemoralespou Oct 7, 2026
594b596
feat: write the lookup service deep page
jorgemoralespou Oct 7, 2026
8dcd176
feat: write the local authoring deep page
jorgemoralespou Oct 7, 2026
4b0ce83
feat: write the AI authoring skills deep page
jorgemoralespou Oct 7, 2026
8c7fbd3
Merge branch 'update-site' into worktree-agent-a5fe9bf0f9614d51f
jorgemoralespou Oct 7, 2026
79cabb4
refactor: draw the docs table of contents from a shared component
jorgemoralespou Oct 7, 2026
632f41f
feat: show a table of contents beside long blog posts
jorgemoralespou Oct 7, 2026
c70a0e0
feat: list a series' parts in a box on each of its posts
jorgemoralespou Oct 7, 2026
b5618ab
feat: put the cloud install posts and the installer post in series
jorgemoralespou Oct 7, 2026
51cc112
feat: add a script that forwards the old homepage #team anchor
jorgemoralespou Oct 7, 2026
5ce9692
feat: add the homepage's Used by section, left out while empty
jorgemoralespou Oct 7, 2026
f6b0a9b
feat: give each use case a line icon for its homepage tile
jorgemoralespou Oct 7, 2026
bae17e2
refactor: share where a link to a Feature leads
jorgemoralespou Oct 7, 2026
6883a37
feat: build the homepage
jorgemoralespou Oct 7, 2026
5308bb1
feat: check that the old homepage anchors still land
jorgemoralespou Oct 7, 2026
dd6200b
Merge branch 'update-site' into worktree-agent-a8498a5f1eecf8a2e
jorgemoralespou Oct 7, 2026
815f3e6
feat: show Related Content at the end of each blog post
jorgemoralespou Oct 7, 2026
cc6432b
Merge branch 'update-site' into worktree-agent-a0b52842375aaa96c
jorgemoralespou Oct 7, 2026
a3abfca
Merge the post page extras
jorgemoralespou Oct 7, 2026
b050c19
feat: make the site check strict and compare it with the live sitemap
jorgemoralespou Oct 7, 2026
d34342f
feat: fail a link on the site that ends in a slash
jorgemoralespou Oct 7, 2026
ebb1b56
feat: list the pages that still show a visual placeholder
jorgemoralespou Oct 7, 2026
b6a22f0
feat: add a rerunnable URL check against a served site
jorgemoralespou Oct 7, 2026
cab9806
fix: switch the Session demo's panels without a cross-fade
jorgemoralespou Oct 7, 2026
13d7ca4
fix: keep Mermaid edge labels above AA contrast in the dark theme
jorgemoralespou Oct 7, 2026
1a80369
docs: record the contrast each token pair is chosen for
jorgemoralespou Oct 7, 2026
1eea45c
docs: say what the reserved /hub path rule checks
jorgemoralespou Oct 7, 2026
c6ee17d
docs: list the posters and format commands in the README
jorgemoralespou Oct 7, 2026
a0c593f
refactor: load the must-resolve list and the redirects in one place
jorgemoralespou Oct 7, 2026
4db9b0d
refactor: make missing must-resolve entries and stub pages always errors
jorgemoralespou Oct 7, 2026
c7cc461
refactor: drop the empty stub page list and its route
jorgemoralespou Oct 7, 2026
320d346
feat: keep 4.0-only terms off the homepage, Features, About and the g…
jorgemoralespou Oct 7, 2026
011c1ec
feat: list the pages that still hold the cutover date placeholder
jorgemoralespou Oct 7, 2026
609ba44
fix: name each task list checkbox by its item's text
jorgemoralespou Oct 7, 2026
ff9f063
fix: serve author pictures from the site instead of GitHub
jorgemoralespou Oct 7, 2026
f229a28
feat: fail a page or feed that loads anything from another site
jorgemoralespou Oct 7, 2026
408bc03
fix: drop the unsourced SpringOne figure from the Hands-on events proof
jorgemoralespou Oct 7, 2026
f8c3653
test: keep only the Session demo behavior the spec states
jorgemoralespou Oct 7, 2026
7276bc2
test: keep the Features module's tests together in the test folder
jorgemoralespou Oct 7, 2026
16b0ffa
refactor: pick a field's 4.0 value in one helper
jorgemoralespou Oct 7, 2026
b8e8df1
refactor: name the Feature job and the 4.0 setting types for what the…
jorgemoralespou Oct 7, 2026
c9d1794
refactor: name one page of a paginated list PaginatedListPage
jorgemoralespou Oct 7, 2026
9a210ea
refactor: name a clickable action's state ClickableActionState
jorgemoralespou Oct 7, 2026
9d6c8c4
refactor: share the use case and Feature pages' section styles
jorgemoralespou Oct 7, 2026
ca43a92
fix: use contact@educates.dev as the site's contact email
jorgemoralespou Oct 7, 2026
d11e812
feat: show the step bar under the Session demo's instructions
jorgemoralespou Oct 7, 2026
fca6b1b
docs: pin the kubectl guide to Kubernetes 1.36, the version Educates …
jorgemoralespou Oct 7, 2026
89584b5
docs: show Educates 3.8.0 in the CLI install guide's version output
jorgemoralespou Oct 7, 2026
5bf2935
docs: show the Kind node image Educates 3.8.0 creates its cluster from
jorgemoralespou Oct 7, 2026
ac51fd9
docs: match What you just installed to the Educates 3.8.0 install
jorgemoralespou Oct 7, 2026
b4d3b1a
docs: show the workshop.yaml that Educates 3.8.0's new-workshop gener…
jorgemoralespou Oct 7, 2026
e0b1954
docs: document how to refresh the guides' release-specific outputs
jorgemoralespou Oct 7, 2026
299e9e5
feat: list outside examples among the Demo Platform's proof
jorgemoralespou Oct 7, 2026
ca2f040
docs: show Graham Dumpleton's labs as an academy running on Educates
jorgemoralespou Oct 7, 2026
0453f30
feat: link an example to start from in What you bring
jorgemoralespou Oct 7, 2026
38710ba
docs: link the OAuth front end from the enablement and team sign-in gaps
jorgemoralespou Oct 7, 2026
a2c9d04
feat: add the capture workshop and the Example Academy site
jorgemoralespou Oct 7, 2026
755cc24
feat: show captures of a running Educates on the Features pages
jorgemoralespou Oct 7, 2026
14dfe4f
feat: add npm run captures, which takes the Features captures
jorgemoralespou Oct 7, 2026
8f2e47f
docs: document taking the Features captures
jorgemoralespou Oct 7, 2026
b6f0dff
Merge branch 'update-site' into worktree-agent-a3b2847898f10664d
jorgemoralespou Oct 7, 2026
34ee309
fix: remove the capture portal's workshop definitions on teardown
jorgemoralespou Oct 7, 2026
1e0178a
feat: add a Project menu to the header
jorgemoralespou Oct 8, 2026
7819996
fix: apply the copy and visual review
jorgemoralespou Oct 8, 2026
4a6dfc5
fix: drop the XSLT styling from the blog feeds
jorgemoralespou Oct 8, 2026
cb15e5b
feat: capture the air-gapped install visual from the real image list
jorgemoralespou Oct 8, 2026
7c4bd1e
fix: label links to GitHub READMEs as the README
jorgemoralespou Oct 8, 2026
ed81871
fix: keep an ArrowLink's icon beside its last word
jorgemoralespou Oct 8, 2026
44e74ab
feat: mark the language of an outside Content entry's title
jorgemoralespou Oct 8, 2026
809359a
fix: rank a post's Related Content by shared Topics
jorgemoralespou Oct 8, 2026
840cf35
feat: show a front end and two customers in the Lookup service visuals
jorgemoralespou Oct 8, 2026
ec927ba
fix: date the switch from Google Analytics on the privacy page
jorgemoralespou Oct 8, 2026
0518a9b
Merge pull request #54 from educates/update-site
jorgemoralespou Oct 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
64 changes: 35 additions & 29 deletions .claude/skills/copy-graham-blog-post/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ description: Copies blog posts from Graham Dumpleton's blog (grahamdumpleton.me

# Copy Graham blog post to Educates site

Copy a post (and its images) from [Graham Dumpleton's blog repo](https://github.com/GrahamDumpleton/grahamdumpleton.me) into this repo's `blog/` folder, and rewrite the text from first person singular (I, my) to first person plural (we, our) as the Educates team.
Copy a post (and its images) from [Graham Dumpleton's blog repo](https://github.com/GrahamDumpleton/grahamdumpleton.me) into this repo's posts collection, `src/content/posts/`, and rewrite the text from first person singular (I, my) to first person plural (we, our) as the Educates team.

## Source and target

- **Source**: GitHub repo `GrahamDumpleton/grahamdumpleton.me`, path like `src/posts/YYYY/MM/post-slug/` (e.g. `src/posts/2026/02/deploying-educates-yourself`).
- **Target**: This repo's `blog/` folder. Create a folder named `YYYY-MM-DD-<slug>/` (e.g. `2026-02-26-deploying-educates-yourself`) containing `index.md` and any image files. Use the post's `date` from frontmatter for the folder date, or the path date if needed. Add `<!--truncate -->` after first paragraph. If first paragraph is too short, do it after the second. Also, review the tags to align with those in `blog/tags.yaml` and the topic in the blog.
- **Target**: a folder `src/content/posts/YYYY-MM-DD-<slug>/` (e.g. `src/content/posts/2026-02-26-deploying-educates-yourself/`) holding `index.md` and the post's image files. The folder date is the post's `date` from its front matter, or the date in the source path if it has none.
- **Format**: `index.md`. Only a post that uses a component, such as `<AsciinemaPlayer>`, is `index.mdx`.

## Workflow

Expand Down Expand Up @@ -49,59 +50,64 @@ In the **body** (not code blocks or image alt text unless they are first-person

Preserve "you" when addressing the reader. Do not change technical wording, code blocks, or link URLs except internal post links.

### 4. Adapt frontmatter
### 4. Write the front matter

- Keep: `title`, `description`, `date`, `tags`, `image`, `draft`.
- Add: `slug: <post-slug>` (e.g. `deploying-educates-yourself`).
- Add: `authors: [graham]`.
- Remove any frontmatter fields this site does not use (check existing posts in `blog/` for the schema).
- Remove `daft` and `date` frontmatter fields.
The posts collection's schema is in `src/content.config.ts`; the build fails on a post that breaks it. Write these keys:

- `title`: from the source.
- `slug`: the post's slug (e.g. `deploying-educates-yourself`). The post is served at `/blog/<slug>`, and the slug never changes once published.
- `description`: required. Take the source's description; if it has none, write one or two sentences saying what the reader gets from the post.
- `date`: the source's date, as `YYYY-MM-DD`.
- `tags`: keys defined in `src/content/tags.yml` that fit the post's topic (see step 6). A key missing from that file fails the build.
- `authors: [graham]`. Authors are keys of `src/content/authors.yml`.
- `draft: true` only for a post that must not publish yet; it then shows in the dev server only.

Leave out every other key of the source, such as `image`. A post gets a generated cover; a picture of its own goes in `cover`, as the path of an image file next to the post.

The post body carries no truncate marker: lists show the `description`.

### 5. Fix internal links

Replace Graham's post paths with this site's blog paths:
Replace Graham's post paths with this site's post paths, `/blog/<slug>`, with no trailing slash:

- `/posts/YYYY/MM/slug/` or `/posts/2026/02/teaching-an-ai-about-educates/` → `/blog/<slug>` (e.g. `/blog/teaching-an-ai-about-educates`).
- Use `/blog/<slug>` consistently (no trailing slash required; add one if the site expects it).
- `/posts/YYYY/MM/slug/` (e.g. `/posts/2026/02/teaching-an-ai-about-educates/`) → `/blog/<slug>` (e.g. `/blog/teaching-an-ai-about-educates`).

GitHub Pages answers `/blog/<slug>/` with a 404, so every internal link ends without a slash.

### 6. Adjust tags

- Review tags in frontmatter section to align with the contents of the blog post and tags already defined in `blog/tags.yaml`
Review the tags against the post's content and the tags defined in `src/content/tags.yml`, and keep only keys from that file.

### 6. Create target folder and files
### 7. Create target folder and files

- Create `blog/YYYY-MM-DD-<slug>/` (e.g. `blog/2026-02-26-deploying-educates-yourself/`).
- Write the rewritten content to `blog/YYYY-MM-DD-<slug>/index.md`.
- Create `src/content/posts/YYYY-MM-DD-<slug>/` (e.g. `src/content/posts/2026-02-26-deploying-educates-yourself/`).
- Write the rewritten content to `index.md` in that folder.
- Download each image from `https://raw.githubusercontent.com/GrahamDumpleton/grahamdumpleton.me/main/src/posts/YYYY/MM/<post-slug>/<filename>` into the same folder. Image references in the markdown are relative (e.g. `training-portal.png`), so they resolve correctly.

### 7. Verify
### 8. Verify

- Confirm all images are present and paths in markdown match filenames.
- Spot-check that first-person singular in the body has been converted to plural and internal links use `/blog/...`.
- Spot-check that first-person singular in the body has been converted to plural, and that internal links are `/blog/<slug>` without a trailing slash.
- Run `npm run build`: it validates the front matter, renders the post at `/blog/<slug>`, and runs the site check.

## Example

User provides: `https://github.com/GrahamDumpleton/grahamdumpleton.me/tree/main/src/posts/2026/02/deploying-educates-yourself`

- Post slug: `deploying-educates-yourself`.
- List contents → get `index.md`, `training-portal.png`, `workshop-dashboard.png`.
- Fetch `index.md`, rewrite I/my → we/our, add `slug` and `authors: [graham]`, change link to previous post to `/blog/teaching-an-ai-about-educates`.
- Create `blog/2026-02-26-deploying-educates-yourself/index.md` and download the two PNGs into that folder.
- Fetch `index.md`, rewrite I/my → we/our, write the front matter, change the link to the previous post to `/blog/teaching-an-ai-about-educates`.
- Create `src/content/posts/2026-02-26-deploying-educates-yourself/index.md` and download the two PNGs into that folder.

## Reference: existing Educates post frontmatter
## Reference: Educates post front matter

```yaml
---
title: "..."
slug: post-slug
description: "..."
date: YYYY-MM-DD
tags: ["educates", "ai"]
title: "Deploying Educates yourself"
slug: deploying-educates-yourself
description: "Educates is open source, not a SaaS. Deploy it yourself, wherever you want."
date: 2026-02-26
tags: ["educates", "installation", "local"]
authors: [graham]
image: https://opengraph.githubassets.com/1/educates/educates-training-platform
draft: false
---
```

Authors are defined in `blog/authors.yml`; `graham` exists. Use the same structure for new posts.
9 changes: 4 additions & 5 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,19 @@
}
},
"extensions": [
"dbaeumer.vscode-eslint",
"orta.vscode-jest",
"astro-build.astro-vscode",
"esbenp.prettier-vscode",
"streetsidesoftware.code-spell-checker"
]
}
},
// "forwardPorts": [3000],
// "containerUser": "vscode",
"postCreateCommand": "yarn install",
"waitFor": "postCreateCommand", // otherwise automated jest tests fail
"postCreateCommand": "npm install",
"waitFor": "postCreateCommand",
"features": {
"node": {
"version": "18"
"version": "26"
},
"github-cli": "latest"
}
Expand Down
17 changes: 17 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# The build installs its own dependencies and writes its own output.
node_modules/
dist/
.astro/

# Not part of the site.
.git
.github/
.devcontainer/
.claude/
.scratch
Dockerfile
.dockerignore
npm-debug.log*
.DS_Store
.env
.env.*
30 changes: 30 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Weekly dependency updates. Minor and patch updates arrive as one pull
# request per ecosystem; each major update gets a pull request of its own, so
# a new Astro major is never missed.
version: 2
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
commit-message:
prefix: build
include: scope
groups:
npm-minor-and-patch:
update-types:
- minor
- patch

- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
commit-message:
prefix: ci
include: scope
groups:
actions-minor-and-patch:
update-types:
- minor
- patch
70 changes: 70 additions & 0 deletions .github/workflows/checks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Checks

on:
pull_request:
branches:
- develop
- main
workflow_dispatch:

permissions:
contents: read

concurrency:
group: checks-${{ github.ref }}
cancel-in-progress: true

jobs:
checks:
name: Checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

# Node.js at the Volta pin in package.json.
- uses: actions/setup-node@v7
with:
node-version-file: package.json
cache: npm

- name: Install dependencies
id: install
run: npm ci

# Each check runs even when an earlier one fails, so a pull request
# sees every failure at once.
- name: Type-check
if: ${{ !cancelled() && steps.install.outcome == 'success' }}
run: npm run check

- name: Check formatting
if: ${{ !cancelled() && steps.install.outcome == 'success' }}
run: npm run format:check

- name: Build the site
id: build
if: ${{ !cancelled() && steps.install.outcome == 'success' }}
run: npx astro build

- name: Run the site check
if: ${{ !cancelled() && steps.build.outcome == 'success' }}
run: npm run site-check

- name: Run the unit tests
if: ${{ !cancelled() && steps.install.outcome == 'success' }}
run: npm test

# Offline, as `npm run link-check` runs it, with lychee.toml's settings.
- name: Check internal links
if: ${{ !cancelled() && steps.build.outcome == 'success' }}
uses: lycheeverse/lychee-action@v2
with:
args: --offline --root-dir "${{ github.workspace }}/dist" 'dist/**/*.html'

# The pages and thresholds are in lighthouserc.yml.
- name: Run Lighthouse
if: ${{ !cancelled() && steps.build.outcome == 'success' }}
uses: treosh/lighthouse-ci-action@v12
with:
configPath: ./lighthouserc.yml
uploadArtifacts: true
50 changes: 23 additions & 27 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
@@ -1,52 +1,48 @@
name: Deploy to GitHub Pages

on:
workflow_dispatch:
push:
branches:
- main
# Review gh actions docs if you want to further define triggers, paths, etc
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on
workflow_dispatch:

permissions:
contents: read

# One deployment at a time; a running deployment finishes before the next.
concurrency:
group: pages
cancel-in-progress: false

jobs:
build:
name: Build Docusaurus
name: Build the site
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 20
cache: yarn
- uses: actions/checkout@v7

- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Build website
run: yarn build
- name: Read the Node.js version from the Volta pin
id: node
run: echo "version=$(jq -r .volta.node package.json)" >> "$GITHUB_OUTPUT"

- name: Upload Build Artifact
uses: actions/upload-pages-artifact@v3
# Installs the dependencies, runs `npm run build` (the build and the
# site check) and uploads dist/ as the Pages artifact.
- name: Build the site and upload it
uses: withastro/action@v6
with:
path: build
node-version: ${{ steps.node.outputs.version }}

deploy:
name: Deploy to GitHub Pages
needs: build

# Grant GITHUB_TOKEN the permissions required to make a Pages deployment
runs-on: ubuntu-latest
permissions:
pages: write # to deploy to Pages
id-token: write # to verify the deployment originates from an appropriate source

# Deploy to the github-pages environment
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}

runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@v5
Loading
Loading