Tutorials /
Publishingtutorial

From working notes to a published guide

A repeatable workflow for creating a Markdown article, checking the details, and publishing it to Wheeler Roadmap.

Jamal Wheeler

· 5 min read

A useful technical note captures more than the command that finally worked. It explains the problem, the assumptions behind the solution, and the checks that tell you whether it worked in your environment.

This guide walks through the publishing workflow for Wheeler Roadmap: create a draft, write and preview the article, then build and publish the finished site.

For readers: The publishing commands below are for this site’s maintainer. You can use the same approach for your own technical notebook, adapting the paths and deployment settings.

Before you start

The blog source lives in the wheeler-blog folder inside the Homelab workspace. On this workstation, open PowerShell and change to that directory:

Set-Location "$env:USERPROFILE\OneDrive\Documents\Homelab\wheeler-blog"

The blog.ps1 wrapper runs the tooling in Ubuntu-24.04 as the existing jamal user. It selects the project’s Node.js 24 runtime without changing the system-wide Node installation. Run the one-time dependency setup after obtaining the source or changing its lockfile:

.\blog.ps1 setup

Use any Markdown editor to write the article. You do not need a separate content-management service.

Create a draft

Start with the tutorial template:

.\blog.ps1 new --title "Building a small network lab" --kind tutorial --topic Networking

This creates src/content/posts/building-a-small-network-lab.md with draft: true. The title generates the URL slug; keep the filename stable after publication so links continue to work.

For a configuration note, use --kind configuration. That template focuses on the environment, annotated settings, validation, and rollback.

The metadata at the top of each article controls how it appears:

---
title: "Building a small network lab"
description: "A concise explanation of the outcome and who this guide is for."
published: 2026-10-22
kind: tutorial
topics:
  - Networking
  - Homelab
featured: false
draft: true
---

Topics are created automatically from published articles. You do not need to edit a navigation file to add one.

Write the reasoning, then the steps

Start with the outcome. Explain who the guide is for and what they will have when they finish. Then make the environment explicit: software versions, dependencies, permissions, and assumptions.

A useful outline is:

  1. Prerequisites and versions — what must already be in place.
  2. The approach — why this solution fits the problem.
  3. Setup — the actions and their expected effects.
  4. Verification — how to establish the intended result.
  5. Troubleshooting — symptoms, likely causes, and useful evidence.
  6. Rollback — what to save and how to return to the prior state.

Use fenced code blocks with a language label, such as yaml, bash, or powershell. The article layout provides syntax highlighting and a copy button. Keep long commands readable and explain values the reader must replace.

Before publishing: Use example domains and documentation IP ranges. Remove credentials, tokens, private hostnames, personal details, and environment exports that do not belong on a public site.

Add screenshots and diagrams

Place reviewed public images in a folder under public/images/, then reference them from Markdown:

![A diagram showing the lab's router and two connected hosts.](/images/network-lab/topology.svg)

Use descriptive alternative text. Screenshots should help explain a step or verify a result, and should be checked for secrets and private details before they are added to the public folder. Everything in public/ is deployed, even if an article is still a draft.

An optional cover image can be defined in the metadata:

cover:
  src: /images/network-lab/cover.svg
  alt: "A small network lab with one router and two hosts."

If there is no cover, the site generates a simple topic-based visual. A useful article does not need a decorative image.

Preview and check

Start a local preview that includes drafts:

.\blog.ps1 dev --drafts

Open http://localhost:4321. The draft preview banner makes the mode clear. Check heading links, code blocks, image descriptions, and the layout at a narrow window width. Stop the server with Ctrl+C.

When the article is ready, set draft: false and choose a publication date that is not in the future. Then run:

.\blog.ps1 check
.\blog.ps1 test
.\blog.ps1 build
.\blog.ps1 verify
.\blog.ps1 preview

The built preview includes search. Drafts and future-dated articles are excluded from production pages, topic collections, search, RSS, and the sitemap. A future date does not trigger an automatic deployment; rebuild and publish when it is time to release the article.

Publish deliberately

Once the built preview passes review, stop it and deploy:

.\blog.ps1 deploy:preview
.\blog.ps1 deploy

The preview command uploads the built site to a Cloudflare preview deployment. The production command runs the checks and rebuilds before publishing the site to the production branch. Deployment credentials are retrieved through the protected SSH workflow, rather than kept in article files or pasted into commands.

After publishing, open the article at https://wheelerroadmap.com/posts/your-slug/. Confirm that it appears in its archive and topic, that search finds it, and that the RSS feed includes it.

Connect a series

When several posts form an ordered guide, give them the same series name and a numeric order:

series: "Building a network lab"
order: 1

The site builds a series page from its published parts and adds previous/next links to the articles. Draft parts stay out of the public series.

Update or roll back

When revising an article, keep its filename and original publication date. Add or change updated to record a meaningful revision. Rebuild, verify, and publish using the same workflow.

If a release is faulty, return to the previous successful production deployment:

.\blog.ps1 rollback

The private operations README explains the separate recovery procedure for undoing the initial domain cutover. That procedure restores the old domain destination; it is not needed for an ordinary article correction.

Keep the useful parts

The goal is a guide you can return to later and still understand: enough context to make a decision, enough detail to reproduce the result, and enough verification to know what actually worked.

Start small, make the assumptions visible, and leave the next person a roadmap.

Keep the useful parts.
Follow the notebook with RSS ↗