hc-preflight

star 0

Site-wide pre-publish health check — frontmatter, share images, metatags, sitemap, build, and draft leakage

hungovercoders By hungovercoders schedule Updated 5/26/2026

name: hc-preflight description: Site-wide pre-publish health check — frontmatter, share images, metatags, sitemap, build, and draft leakage allowed-tools: Read, Glob, Grep, Bash, Write argument-hint: <optional — pass --strict to fail on any warning, or a path to limit scope to one post>

Pre-flight check for the hungovercoders site before publish. Run from ~/dev/hungovercoders/site/. Walks the site's content, build output, and config to surface anything that would degrade a published post or break a metatags preview. Produces a punch list, not pass/fail per file.

If $ARGUMENTS contains a path or slug, scope checks to that file plus the site-wide checks (build, sitemap). Otherwise run the full audit. --strict flag exits non-zero if any P0/P1 issue is found.

Step 1 — Establish the working state

cd ~/dev/hungovercoders/site
git status --short
git branch --show-current

Capture: branch name, untracked files, modifications.

Branch expectations:

  • Preflight is intended to run on a feature branch (series/<slug> or blog/<slug>) before merging to main. The Cloudflare preview for that branch is what you're validating; merge-to-main is what publishes.
  • If on main: flag as P1 with the note "preflight is normally run on the publish branch before merge — if you've already merged, the work below is post-mortem rather than gating; if you haven't branched yet, you're about to publish straight to live".
  • If on a feature branch with uncommitted changes: that's expected mid-flow. Note it informationally. If --strict, flag as P2 — the merge-to-main step needs a committed tree.
  • If on a feature branch with a clean tree: ideal state. Note the branch in the report so the user knows what they're about to merge.

Step 2 — Build the site

npm run build 2>&1 | tee /tmp/hc-preflight-build.log

Capture exit code. If non-zero, build failed — stop the audit here and report the build error as the only finding. Everything else is moot until it compiles.

If the build succeeds, note any warnings in the log (Astro deprecation warnings, missing image dimensions, etc.) as P2 findings.

Step 3 — Blog post frontmatter sweep

For every .md file in src/content/blog/ (excluding _drafts/), check:

Check Severity
title present and non-empty P0
date present and parses as a date P0
author present (typically dataGriff) P1
description present, non-empty, and no trailing period P1
tags is an array containing hungovercoders P1
image.path present and starts with /assets/<slug>/ P0
image.path file exists at public/<image.path> (i.e. public/assets/<slug>/link.png) P0
Filename matches YYYY-MM-DD-<slug>.md P1
Slug in filename matches the slug component of image.path P1

Report each violation with the exact file path and the offending line.

Step 4 — Training lesson frontmatter sweep

If training-repos/ contains any linked repos, walk every training-repos/*/docs/*/README.md and check:

Check Severity
title, series, order, description, canonical_url all present P0
description non-empty and no trailing period P1
order value matches the directory's leading number (e.g. 02-foo/order: 2) P1
canonical_url starts with https://hungovercoders.com/training/<series>/ P1
Directory has no duplicate order value across the series P0

If training-repos/ is empty (because of an exclude list), report this as informational, not a failure.

Step 5 — Built output spot checks

For each blog post that built into dist/client/blog/<slug>/index.html, grep the HTML for:

grep -oE '(og:image|og:type|og:url|twitter:image|<link rel="canonical")[^>]*' dist/client/blog/<slug>/index.html

Verify:

  • og:type = article
  • og:url is absolute (https://hungovercoders.com/blog/<slug>/)
  • og:image is absolute and points at /assets/<slug>/link.pngnot at the generic placeholder _astro/blog-placeholder-...jpg
  • canonical is absolute and matches og:url

Don't sample — check every post. This is the cheap version of running every URL through metatags.io.

Step 5b — Inline asset references resolve

For each blog post and training lesson, grep the markdown for site-absolute asset references (/assets/<slug>/<name>.<ext>) — typically inline screenshots embedded via hc-screenshot — and confirm each referenced file exists under public/<that-path>. Flag broken references as P2 (warning, not block): the build won't fail on a missing image, but the post renders with a broken <img> and the reader sees nothing.

# from inside src/content/blog/<slug>.md, find every /assets/<slug>/<file>.<ext>
grep -oE '/assets/[^)"'\'' ]+\.(png|jpg|jpeg|webp|svg|gif)' src/content/blog/<slug>.md \
  | sort -u \
  | while read ref; do
      [ -f "public${ref}" ] || echo "MISSING: $ref (referenced in $post)"
    done

Same logic for training lessons under training-repos/<series>/docs/<NN>-<lesson>/README.md, checking against public/assets/training/<series>/<lesson>/.

The existing image.path frontmatter check (Step 3) covers the social card (link.png) as P0 — that's the unmissable one. This step catches the broader case where a writer added ![diagram](/assets/<slug>/step-04.png) to the body but forgot to drop the file in. hc-screenshot's own emit step is meant to prevent it, but the check is the belt-and-braces.

Step 6 — Sitemap and feeds

  • dist/client/sitemap-index.xml exists
  • Sitemap references every published blog post URL
  • dist/client/rss.xml exists and the most recent published post appears in it
  • Spot-check the page count in the sitemap against the count of built dist/client/blog/*/index.html files

Step 7 — Draft leakage and exclude integrity

  • Confirm no src/content/blog/_drafts/*.md content appears in the build output (grep -r "_drafts" dist/client/ returns nothing for content paths — _drafts may legitimately appear in pagefind indexes; ignore those)
  • Read scripts/fetch-training-repos.sh and scripts/link-local-repos.sh. If either has an EXCLUDE list, list the excluded items as informational so the user remembers what's deliberately hidden

Step 8 — Nav and empty-state sanity

  • dist/client/training/index.html either lists series cards or shows the "coming soon" empty state — confirm one of those is rendered, not a broken middle ground
  • Every nav link in the header (/, /blog, /training, /about) resolves to a built index.html

Step 9 — Produce the punch list

Group findings by severity:

  • P0 — must fix before publish. Build failures, missing required frontmatter, missing OG images that would fall back to placeholder, duplicate training orders.
  • P1 — should fix before publish. Trailing periods on descriptions, mismatched order vs directory, missing tags, missing British spellings if egregious.
  • P2 — worth fixing soon. Build warnings, uncommitted changes, schema drift.

For each finding include:

  • Severity
  • Exact file path (and line number where relevant)
  • One-line description
  • One-line suggested fix (e.g. "drop trailing period from description:")

Step 10 — Report to the user

Print to chat:

hc-preflight — <date> <time>

Branch: <current branch>  (publish target: main)
Build: PASS / FAIL
P0 issues: N
P1 issues: M
P2 issues: K

P0:
  - <file>: <issue> → <fix>
  ...

P1:
  - <file>: <issue> → <fix>
  ...

Verdict: <ready to merge to main | fix P0 first | …>

If the verdict is "ready to merge to main", remind the user the actual publish step is the merge — git push on the branch only updates the preview URL.

Exit non-zero if --strict and any P0 or P1 issue exists.

Notes on running this

  • Run this on the publish branch immediately before merging to main. It's the publish gate — the merge is what goes live, git push on the branch only updates the Cloudflare preview.
  • Build is the first gate — everything else assumes the build passed.
  • This skill does not check voice or content quality. For that, run hc-review-blog or hc-review-series separately.
  • If training-repos/ is empty (deliberate exclusion of all series), the training half of the audit is skipped — that's fine, not a failure.
Install via CLI
npx skills add https://github.com/hungovercoders/library --skill hc-preflight
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator
hungovercoders
hungovercoders Explore all skills →