Skip to content

Repository files navigation

Signpost

A static site that answers "what is the platform team doing, and what is about to change?" — built from Markdown files in a Git repository, deployed to GitHub Pages, with no database and no server.

License: MIT


This repository is the live sample

The product lives at Anonycoders/signpost and ships empty, ready to adopt. This repository is a copy of it with the demo content left in, kept running so that anyone deciding whether to adopt Signpost can read a populated site instead of an empty one.

Everything under content/ here is fictional — four invented platform teams, thirteen streamlines — and Example Organization is not a real company. Nothing here is a statement about anybody's roadmap.

If you want to run Signpost, start at the template, not here. Forking this repository means inheriting a demo you will have to delete.

Keeping this in step with the template

The product's own history is upstream, so improvements are merged in rather than reimplemented. Every sync is the same four commands:

# once:  git remote add template https://github.com/Anonycoders/signpost.git
git fetch template
git merge template/main
git checkout ORIG_HEAD -- content/ README.md .github/CODEOWNERS
git commit -m "Restore the sample's own files after syncing"   # if that changed anything

ORIG_HEAD is the pre-merge tip, set by git merge itself.

This repository owns exactly three paths — content/, README.md and .github/CODEOWNERS. Everything else belongs to the product, and the merge is welcome to overwrite it.

content/ is the obvious one. The template deletes its own demo in order to ship empty, and merging that deletion here would take the entire point of this repository with it.

The other two are not obvious, and they caused real damage the first time this was done. The template's README and CODEOWNERS describe the template: a repository that ships empty, with placeholder team handles that deliberately resolve to nobody. This repository has files at those same paths saying the opposite. When only the template edits them, Git sees no conflict — it merges cleanly and leaves this README announcing that it is an empty template, which it is not. A clean merge is not the same as a correct one, and the files where the product describes its own emptiness are exactly where the two diverge silently.

So the restore step is not a one-time fix; it is part of the recipe. Run it on every sync, whether or not anything came through — git checkout on an unchanged path is a no-op, and the commit simply refuses when there is nothing to commit. That leaves nothing to remember and no judgment to exercise.

A template change that genuinely belongs here — a better sentence in the README, a real improvement to the ownership pattern — is ported across by hand, deliberately, as its own commit.


Platform teams ship things that land on everyone else: a cluster upgrade, a CI migration, a deprecated gateway. The work is usually visible somewhere — a wiki page, a Slack thread, a Jira epic nobody outside the team can read — and the result is the same either way. Other teams find out when something breaks.

Signpost gives every team one file per effort. They edit it when the plan changes, open a pull request, and the site rebuilds. Anyone can see which stage each effort is in, when it lands, and who owns it — and subscribe to a feed so they do not have to check.


What it looks like

The screenshots below are of this repository's own site, published at anonycoders.github.io/signpost-sample — the four invented teams and thirteen streamlines that live in content/ here. The empty product they were taken from is Anonycoders/signpost.

Roadmap — every effort as a lane across six quarters, filterable by team, stage and category.

Light Dark
The roadmap page in the light theme The roadmap page in the dark theme

Changes — a reverse-chronological log of what teams have announced, with breaking changes marked and dated.

Light Dark
The changes page in the light theme The changes page in the dark theme

Home — what landed recently and what lands soon, above everything else.

The home page in the dark theme

Plus a filterable catalog of every streamline, a page per team, a page per streamline with its full timeline and update history, and an /about/ page explaining the whole thing to a first-time visitor.

docs/using.md is the guide for the people who only ever read the site: what a hatched bar with a diamond on it means, which window the attention strip covers, and how to point a feed reader or a Slack channel at one team's work.


Quickstart

git clone https://github.com/Anonycoders/signpost-sample.git
cd signpost-sample
nvm use          # Node 26, per .nvmrc — the repo sets engine-strict
npm install
npm run dev      # http://localhost:4321

That comes up populated: content/ here holds four teams and thirteen streamlines, so you get the whole site — roadmap, changes, feeds — with something in it to click. All of it is fictional, and it is here to show the shape of a real instance rather than to be one. To start a real one, begin at Anonycoders/signpost, which ships empty, and follow docs/adopting.md.

Other scripts:

Command What it does
npm run dev Dev server with hot reload
npm run validate Content validator — the same one CI runs
npm run check TypeScript and Astro diagnostics
npm run test Unit tests
npm run build Validate, then build the static site into dist/
npm run preview Serve dist/ as it will be deployed

If npm install refuses to run, it is engine-strict doing its job: this needs Node 22.12 or newer, and .nvmrc pins the version the project is built against.


Publishing your team's work

One YAML file per streamline, in content/streamlines/<team>/<slug>.yaml. It holds the structured part — stage, owners, timeline dates, links — a body: with the long explanation, and updates:, the running log of announcements, newest first:

updates:
  - date: 2026-09-10       # when you posted it
    status: rolling-out
    effective: 2026-10-01  # when it actually lands on people
    impact: breaking
    title: Production clusters upgrade from 1 October — Ingress v1beta1 is removed
    body: |
      Production upgrades run in three waves starting **1 October**. Any workload
      still declaring `networking.k8s.io/v1beta1` Ingress objects will fail to
      deploy once its cluster is upgraded.

Edit, open a pull request, CODEOWNERS routes it to your team, CI validates it, merge deploys it. The validator blocks the mistakes that make a roadmap untrustworthy — a deprecation with no retirement date, a breaking change with no notice period, a timeline that runs backwards — and it explains what to fix rather than which schema rule failed.

CONTRIBUTING.md is the five-minute version: templates to copy, every field explained, and what CI will and will not let through.


Running it for your own organization

Fork the template rather than this repository, edit one config file, add your content. docs/adopting.md walks through it: naming and branding, defining your own lifecycle stages and categories, wiring CODEOWNERS to your teams, deploying to GitHub Pages (including GitHub Enterprise), and what to do if your instance has Pages turned off.

Everything an organization needs to change lives in site.config.ts — the stages, the categories, the impact levels, the colours, the attention windows. The rules follow the config: rename deprecated to sunsetting and the validator's messages, the filters and the roadmap legend all rename with it.


How it works

Git is the database. There is no CMS, no admin login, no runtime. content/ is the source of truth; the site is a pure function of it. Reviewing a roadmap change is reviewing a diff, and the history of what a team promised is git log.

The build is the gatekeeper. scripts/content-rules.ts holds the rules, shared between the CLI validator and the Astro build via one set of Zod schemas, so CI and your editor cannot disagree. Errors block the merge; softer things (a streamline nobody has updated in a long time) warn. The same schemas generate the JSON Schema in schemas/, so an editor offers the field names — and your stage names, not ours — while somebody is still typing.

Feeds, so nobody has to remember to look. A site-wide Atom feed at /feed.xml and one per team, hand-built to Atom 1.0 (RFC 4287) with stable entry IDs — so a feed reader, a Slack integration or a Teams connector can subscribe once and get every announcement.

A nightly rebuild. "Landing in 60 days" is only true on the day it is built, so the deploy workflow also runs on a schedule. The rationale is in docs/adopting.md.

It prints. The roadmap and the changes log have print stylesheets, for the people who bring a roadmap to a planning meeting on paper. One known limitation: a roadmap that spans more than one printed page does not repeat the quarter headers on the second page.

Layout

content/
  teams/<slug>.yaml              one file per team
  streamlines/<team>/<slug>.yaml one file per effort
site.config.ts                   everything an organization changes
schemas/                         generated from site.config.ts, for editors
src/
  pages/                         routes
  lib/                           roadmap, changes, timeline, feeds — unit-tested
  components/                    Astro components
scripts/
  content-rules.ts               the validation rules
  validate-content.ts            the CLI wrapper CI runs
  json-schema.ts                 regenerates schemas/ from the Zod schemas
.github/
  workflows/ci.yml               validate + check + test on every PR
  workflows/deploy.yml           build + publish to Pages on main and nightly
  CODEOWNERS                     which team reviews which directory

Built with Astro and Tailwind CSS. No client-side framework: the filters are under a hundred lines of vanilla JavaScript over server-rendered cards, and every page still renders its content without them.


Contributing to Signpost itself

Bug reports, ideas and pull requests are welcome, and they belong on the product rather than here — see CONTRIBUTING.md and the Code of Conduct. docs/developing.md is the tour of the code: the data flow file by file, where the two validation layers live, and what must never be hardcoded. If you have adopted this somewhere, we would genuinely like to hear what you had to change.

License

MIT — see LICENSE. Fork it, rebrand it, sell services around it. No attribution required, though a link back is appreciated.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages