Skip to content

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 14 Aug 17:40
· 468 commits to main since this release
v1.0.0
1e512ce

[1.0.0] - 2026-08-14

First tagged version of the site. The site itself was already live on
kbrdn.dev — what this version adds is everything that was
missing around it: a way to say which version is deployed, a way to go back to
a previous one, and a release that a tag actually performs rather than merely
records.

Versioning starts at 1.0.0 rather than 0.x: the product is in production,
and a 0. would misdescribe it.

Added

  • A release flow, where there was none
    (#18). Deployment worked, but
    nothing tied it to a version: images were tagged :main and :dev, both
    mutable, package.json carried no version field at all, and nobody could
    answer "which version is live on pre-prod right now".

    Tags now drive deployment. vX.Y.Z-rc.N builds an immutable
    ghcr.io/kbrdn1/kbrdn.dev:vX.Y.Z-rc.N, ships it to preprod and opens a
    GitHub pre-release; vX.Y.Z does the same for prod and publishes the
    release. Pushing to dev still redeploys preprod for day-to-day iteration —
    that path is untouched, and deploy.yml only ever wakes on branches while
    release.yml only wakes on tags.

    The routing lives in scripts/resolve-release-tag.sh rather than inline YAML,
    because getting it wrong ships an unvalidated candidate to production;
    scripts/resolve-release-tag.test.sh covers it, malformed tags included.

  • GET /api/health returning { status, version, sha, env }, all three
    baked in at build time. The container HEALTHCHECK now points at it instead
    of /: the old probe went green as soon as the home page rendered
    server-side, which stays true even when the API layer behind /api/github/*
    and /api/contact is dead. It uses a real GET, not wget --spider — that
    sends a HEAD, and h3 does not route HEAD to a .get handler.

  • Guardrails that hold the protocol up, rather than a document asking
    politely: a stable tag must be an ancestor of main and a candidate an
    ancestor of dev; package.json must match the tag; the notes file must
    exist. All four run before anything is built or deployed. The GitHub
    release is only published once /api/health has confirmed, from the outside,
    that the expected version and environment are serving traffic.

  • scripts/github-deploy.sh is versioned and hardened. The piece that
    reconciles the workflow — which configures over environment variables — with
    deploy.sh, which parses flags, turned out to be a ForceCommand wrapper
    living only on the VPS: the centre of the deployment pipeline was invisible
    from the repository. It now only exports an allowlist (ENV, IMAGE,
    GITHUB_TOKEN, RESEND_API_KEY, NUXT_STUDIO_TOKEN) and refuses anything
    else, PATH included — deploy.sh resolves docker, nginx and
    systemctl through it, as root.

  • A promo banner at the top of the README
    (#24), dark and light, built
    around the site's own monogram.

Changed

  • Rollback actually rolls back
    (#18). scripts/deploy.sh
    used to docker rm -f the outgoing colour at the end of every deploy, while
    --rollback required exactly that container — at steady state a single
    colour runs, so the option could only ever fail, and silently so until the
    day it was needed. The outgoing colour is now stopped and kept, and the
    immutable per-version images make
    --image ghcr.io/kbrdn1/kbrdn.dev:vX.Y.Z a real return to a known version
    rather than a colour flip.

  • Deployments to one environment are serialised. The protocol itself used
    to put two in flight: merging into main wakes deploy.yml, pushing the tag
    right after wakes release.yml, and their workflow-level concurrency groups
    differ. Two deploy.sh --env prod would then target the same container names
    and the same nginx upstream. Both jobs now share a vps-deploy-<env> key.

  • Containers carry a kbrdn.version label, so docker inspect answers the same
    question as /api/health from inside the VPS.

  • Re-running a released tag no longer rebuilds its image: registry tags are
    mutable and the build is not reproducible, so republishing could quietly make
    :vX.Y.Z stop meaning what it meant — the very property version rollback
    rests on.

Docs

  • docs/RELEASE.md — the protocol, the repo's knobs, the
    real deployment chain (ForceCommand → github-deploy.sh → deploy.sh), and
    the VPS synchronisation procedure.
  • Two traps found the hard way and written down: overwriting /srv/deploy.sh
    while it runs breaks the deploy in progress (bash reads a script by offset),
    and every PR into main must close an issue — the release PR included, so
    each version needs its own.