halyard

A CLI that builds, signs and ships a release, runs a set of preflight checks against it before any traffic moves, and keeps the previous release warm so a rollback is one command instead of a rebuild.

Node ≥ 18 Zero-config default CI-friendly

Installation

bash# with npm
npm install --save-dev halyard

# with pnpm
pnpm add -D halyard

# or run without installing
npx halyard deploy

Quick Start

bash# 1. Generate a config file
npx halyard init

# 2. Build, sign and run preflight against staging
npx halyard deploy --env staging

# 3. Move traffic once preflight is green
npx halyard promote --env staging

Commands

halyard deploy [path]

Builds and signs the artifact at the given path (defaults to .), uploads it, and runs the preflight checks. Traffic is not moved.

FlagDescriptionDefault
--formatOutput format: pretty, json, junitpretty
--envTarget environment: staging, productionstaging
--configPath to a config file.halyardrc.json
--quietSuppress info-level outputfalse
--skipSkip a named preflight check (repeatable)- (none)
bashnpx halyard deploy ./ --format json --env production > release.json

halyard init

Interactively creates a .halyardrc.json config file in the current directory.

FlagDescriptionDefault
--yesSkip prompts, use defaultsfalse
--presetStarting preset: strict, balanced, lenientbalanced

halyard promote [build]

Moves traffic to a build that already passed preflight, and keeps the outgoing release warm for rollback.

FlagDescriptionDefault
--dry-runShow what would change without moving trafficfalse
--keep-warmHow many superseded releases stay running1
Note: The four signing checks can never be skipped — a build that failed them cannot be promoted at all.

halyard rollback

Sends traffic back to the warm release. No rebuild and no registry round trip, because the previous build is still running.

bashnpx halyard rollback --env production
npx halyard rollback --to 4f21c9e

Config Options

Configuration lives in .halyardrc.json at your project root.

.halyardrc.json{
  "extends": "halyard:balanced",
  "environments": ["staging", "production"],
  "artifacts": ["dist/**", "public/**"],
  "preflight": {
    "healthcheck": "/readyz",
    "env-drift": "error",
    "bundle-size": ["warn", { "maxKb": [180, 240, 320] }],
    "cold-start": ["warn", { "p95": 1.2 }]
  },
  "failOn": "error",
  "keepWarm": true
}
KeyTypeDescription
extendsstringBase preset to inherit check settings from
environmentsstring[]Environments this project is allowed to deploy to
preflightobjectPer-check severity and options
failOnstringSeverity level that triggers a non-zero exit code
keepWarmbooleanKeep the superseded release running for rollback

CI Integration

Use the junit format to surface failed checks in your CI test report, or just fail the job on error-level checks:

.github/workflows/halyard.yml- name: Halyard deploy
  run: npx halyard deploy --env production --format junit

Exit Codes

CodeMeaning
0Preflight passed, nothing at or above the failOn level
1Checks failed at or above the configured fail level; traffic unchanged
2Configuration error (invalid .halyardrc.json, unknown environment)
3Runtime error (artifact not found, signing key unreadable, upload failure)