Skip to content

CI/CD & Releases

Maintainer reference for GitHub Actions, secrets, and how to ship a version of leash-secrets.

Not Fork Shepherd. Fork Shepherd is a Marketplace action for forks syncing with an upstream. This page is about leash-secrets’s own pipelines. The Release Draft workflow only reuses the same release idea (manual patch/minor/major → draft → publish).

Mental model

You open a PR
    → CI (+ Validate Patterns if patterns change)
    → merge when green

Push lands on main
    → CI again
    → Deploy Docs (if docs/** changed)
    → Validate Patterns (if patterns/** changed)
    → Release (release-please)  ← legacy; usually ignore

When you want to ship a version
    → Actions → Release Draft (patch/minor/major)
    → workflow bumps version files + pushes commit (if needed)
    → draft GitHub Release appears
    → you Publish the draft in the UI
    → Publish npm runs (skips if that version is already on npm)
Stage Tool Output
Validate code CI Pass/fail on PR
Update docs site Deploy Docs GitHub Pages
Cut a version Release Draft Version bump commit (if needed) + draft GitHub Release + assets
Make it live You click Publish Public GitHub Release
Package registry Publish npm leash-secrets on npm (no-op if already published)
Release Draft (auto-bump)  →  draft tag/assets  →  Publish draft  →  npm

Workflow table

Workflow When it runs Purpose
CI Every PR + every push to main (+ manual) Quality gate: Node 18/20/22 tests, shell syntax, hygiene (incl. install.shpackage.json version), dogfood scan
Validate Patterns PRs/pushes that touch patterns/ (or related tests/scripts) Pattern JSON / fixture validation
Deploy Docs Push to main that touches docs/** (or MkDocs config) (+ manual) MkDocs → GitHub Pages
Release (release-please) Push to main (+ manual) Legacy. Tries to manage release PRs/tags. Org often blocks Actions from opening PRs — prefer Release Draft
Release Draft Manual (workflow_dispatch) You pick patch/minor/major → bumps version files if needed → draft leash-secrets-vX.Y.Z + assets
Publish npm Manual, or when a draft release is published npm publish --provenance (succeeds as no-op if version already on npm)

Workflow files live under .github/workflows/.

After a merge to main — what runs, in order

Merging a PR (or landing a commit on main) does not publish npm. These workflows fire automatically from the push:

Order Workflow Runs when? What it does You should…
1 CI Always on push to main Re-runs the full test matrix on main Wait for green. Required status check for future PRs.
2 Validate Patterns Only if the merge touched patterns/**, tests/**, or scripts/check-patterns.js Extra pattern/fixture checks Confirm green if it ran; otherwise ignore.
3 Deploy Docs Only if the merge touched docs/**, mkdocs.yml, requirements.txt, or the docs workflow Builds MkDocs and deploys GitHub Pages Confirm the site updated if you changed docs.
4 Release (release-please) Always on push to main Legacy release-please attempt Ignore unless debugging. Prefer Release Draft to ship.

Nothing else is required for a normal feature/fix merge.

When you want to ship a version (manual, after main is green)

Do these in order — they are not automatic on merge:

Order Action Workflow / UI Purpose
1 Run Release Draft Actions → Release Draft → patch/minor/major Bumps version on main (needs org GitHub App; see below), creates draft leash-secrets-vX.Y.Z
2 Review & Publish the draft Releases → open draft → Publish Makes the GitHub Release public; fires the next step
3 Publish npm Runs automatically on publish (or Actions → Publish npm) Publishes leash-secrets@X.Y.Z (skips if already on npm)

Optional: Publish npm alone if the GitHub release/tag already exists and you only need the registry.

Secrets needed

Prefer org-level secrets (FasterApiWeb → Settings → Secrets and variables → Actions → Organization secrets) so nothing is tied to a personal account. Grant them to leash-secrets (and any other repos that release the same way).

Secret Required? Used by How to create
NPM_TOKEN Yes (to publish) Publish npm npmjs.com → Access Tokens → Granular token with Read and Write + Bypass 2FA for publish
RELEASE_APP_ID / RELEASE_APP_PRIVATE_KEY / RELEASE_APP_INSTALLATION_ID Recommended Release Draft Org GitHub App (see below). Preferred over a personal PAT.
RELEASE_TOKEN Avoid Release Draft Personal PAT — not needed if the App is configured
VSCE_PAT Deferred VS Code extension publish Azure DevOps PAT with Marketplace → Manage

GITHUB_TOKEN cannot push to protected main. A personal RELEASE_TOKEN works but is tied to one human. Use an org-owned GitHub App instead. No workflow file changes are requiredrelease-draft.yml already reads these secrets.

1. Create the App (org owner)

  1. Open github.com/organizations/FasterApiWeb/settings/apps/new
  2. Fill in:
  3. GitHub App name: e.g. FasterApiWeb Release (must be unique on GitHub)
  4. Homepage URL: https://github.com/FasterApiWeb (or this repo’s URL)
  5. Webhook: uncheck Active
  6. Repository permissions:
  7. ContentsRead and write
  8. MetadataRead-only (usually already set)
  9. Leave Account permissions at No access
  10. Where can this GitHub App be installed?Only on this account
  11. Click Create GitHub App

2. Generate the private key

  1. On the App settings page → Private keysGenerate a private key
  2. Download the .pem (paste into a secret once; never commit it)
  3. Note the App ID under About (digits only)

3. Install the App on the org

  1. App settings → Install App (or open the App’s install URL)
  2. Choose FasterApiWeb
  3. Only select repositoriesleash-secrets (or all repos if you reuse it)
  4. Install

4. Copy the Installation ID

  1. Org → Settings → GitHub Apps → Installed GitHub AppsConfigure next to the App
  2. URL looks like:
    https://github.com/organizations/FasterApiWeb/settings/installations/XXXXXXXX
    XXXXXXXX = RELEASE_APP_INSTALLATION_ID

5. Add org Actions secrets

  1. Organization secretsNew organization secret for each:
Name Value
RELEASE_APP_ID App ID (number)
RELEASE_APP_PRIVATE_KEY Full .pem contents (including BEGIN / END lines)
RELEASE_APP_INSTALLATION_ID Installation ID (number)
  1. Repository accessSelected repositories → add leash-secrets

Do not add a personal RELEASE_TOKEN if the App is configured.

6. Bypass rulesets for the App (required)

Secrets alone are not enough — branch rules still block pushes unless the App is on the bypass list.

  1. Repo Rules (or org rulesets) → open the ruleset that targets main
  2. Bypass listAdd bypassGitHub Apps → select your Release App
  3. Bypass mode: Always allow (or Exempt)
  4. Save

Also check classic Settings → Branches protection if it still applies.

7. Actions policy

Org or repo: Settings → Actions → GeneralAllow all actions and reusable workflows
(needed for actions/create-github-app-token@v2)

8. Verify

  1. Actions → Release Draft → Run workflow (main, patch; optional dry_run first)
  2. Log step Resolve release token should say: Using GitHub App installation token
  3. On a real run, the bump commit should land on main (not release/v*)

Release Draft token preference: App → RELEASE_TOKENGITHUB_TOKEN.

Day-to-day (features / fixes)

  1. Open a PR → wait for CI (and Validate Patterns if you changed patterns).
  2. Merge when green (squash).
  3. On main: CI always; Deploy Docs / Validate Patterns only if paths match; ignore Release.
  4. No npm publish on normal merges.

How to ship a version

1. Create a draft release

  1. Actions → Release Draft → Run workflow
  2. Branch: main
  3. Bump: patch / minor / major
  4. Optional: dry_run = true to preview the next tag

The workflow:

  • Computes the next version from the latest leash-secrets-v* tag
  • If package.json is behind, bumps package.json, install.sh, CITATION.cff, vscode-extension/package.json, manifest, and CHANGELOG.md, then pushes chore: release X.Y.Z to main
  • Creates a draft release leash-secrets-vX.Y.Z + assets

If the push fails (branch protection), finish the org GitHub App + ruleset bypass steps above, then re-run. Without that, the workflow falls back to a release/vX.Y.Z branch (merge that to main manually, then delete the branch).

2. Publish the draft

  1. Releases → open the draft
  2. Review notes/assets
  3. Publish release

Result: Publish npm runs and publishes leash-secrets@X.Y.Z (or no-ops if that version is already on npm).

3. If you only need npm

Actions → Publish npm → Run workflow — publishes whatever version is on the checked-out ref; skips cleanly if already published.

Optional local prep (still supported): bash scripts/prepare-release.sh if you prefer a version-bump PR before Release Draft.

Branch protection (maintainer note)

main requires PRs and the CI status checks. Required approving reviews are set to 0 so the sole maintainer can merge their own PRs (GitHub never counts self-approvals). CI must still be green. Revisit if more maintainers join.

See also: CONTRIBUTING.md (repo root) and Development Setup.