Releasing and Docs Deploy
Build docs locally
npm run docs:build
npm run docs:serve
Local development mode
npm run docs:start
Deployment variables
Docusaurus configuration supports:
- DOCS_URL (default https://docs.telepat.io)
- DOCS_BASE_URL (default /otto/)
- GITHUB_OWNER (default telepat-io)
- GITHUB_REPO (default otto)
- GH_PAGES_BRANCH (default gh-pages)
Use DOCS_LOCAL=true for localhost base path.
Release Please package versioning
Release management is handled by .github/workflows/release-please.yml using
release-please-config.json and .release-please-manifest.json.
- Managed components include CLI, relay, protocol, and extension.
- All component versions are kept in sync via a single
.(root) package entry in the release-please config withinclude-component-in-tag: false, so all packages share onev<version>tag (for examplev0.8.5). - The
extra-fileslist in the release-please config ensurespackage.jsonversion fields and.versionfiles for CLI, relay, protocol, and extension are all bumped together, along with internal@telepat/*dependency pins.
When a release PR is opened, expect version bumps and internal @telepat/*
dependency updates to be included together.
Workflow trigger and job flow
The release-please.yml workflow triggers on every push to main. Not
every push produces a publish — the workflow uses job-level guards to ensure
publish and extension upload only run when a new release is created.
Job 1: release-please
Runs the googleapis/release-please-action@v4. This job either:
- Creates or updates a release PR (no new release yet — no downstream publish).
- Creates a GitHub release when a release PR is merged (sets
releases_created: trueand.--release_created: true).
When release-please does not create a release, a reconcile step checks
for merged PRs that still carry the autorelease: pending label. If a merged
release PR was missed by release-please (for example, due to a race or v4 tag
skipping), the reconcile step creates the missing tag and GitHub release
manually, then relabels the PR autorelease: tagged.
Job 2: determine-release-tag
Acts as a gate for downstream jobs. It checks three conditions in order:
- release-please created a release (
cli_release_created == 'true'): outputs the new tag from release-please. - reconcile recovered a stuck PR (
reconciled_tagis non-empty): outputs the reconciled tag. - Neither (ordinary push with no new release): outputs an empty string, which causes all downstream jobs to skip.
This gate is what prevents publish-packages and upload-extension-assets
from running on every push to main. Only a genuine new release or a
successfully reconciled stuck release produces a non-empty release_tag.
Job 3: publish-packages
Runs only when release_tag != ''. Checks out the release tag, runs full
package quality gates (typecheck, lint, build, test) for protocol, relay, and
CLI, then publishes all three packages to npm with provenance.
Publishing validates that each package version matches the release tag version before proceeding.
Job 4: upload-extension-assets
Runs only when release_tag != ''. Checks out the release tag, builds the
extension, runs extension quality gates (typecheck, lint, build, test), zips
the extension, and uploads the .zip and .sha256 checksum to the
v<version> GitHub release.
Flow diagram
push to main
│
▼
release-please job
├── release PR created/updated → no downstream publish
├── release created (merge!) → cli_release_created=true
└── no release, reconcile step → reconciled_tag=vX.Y.Z (or empty)
│
▼
determine-release-tag job
├── release_created=true → tag=vX.Y.Z ──► publish-packages
│ └─► upload-extension-assets
├── reconciled tag → tag=vX.Y.Z ──► publish-packages
│ └─► upload-extension-assets
└── neither → tag= ✔ (skips publish & upload)
Why not on: release or on: push: tags?
The workflow intentionally avoids on: release or on: push: tags triggers to
avoid cross-workflow chaining. Using a single workflow triggered by
on: push: branches: [main] with internal job gates means:
- All release steps (tag creation, npm publish, extension upload) happen in one
workflow run with one
GITHUB_TOKEN. No PAT is needed. - The
determine-release-taggate ensures only actual release events trigger publish, while ordinary pushes to main exit early at the gate. - The reconcile step catches cases where release-please v4 skips tag creation for merged PRs, without requiring a separate recovery workflow.