BLOG/BY COMPANY SIZE
THEME
BY COMPANY SIZE

OrchStep for open-source maintainers

Maintainers run the same release and triage steps over and over, usually from memory at 11pm. Here's how to put the project's rituals in one file contributors can run too.

Apr 1, 2026 OrchStep Team 6 minROLE: OSS MaintainerSCALE: Any

Maintaining an open-source project is mostly remembering things. The exact order to cut a release. Which checks have to pass before you merge. The five commands a new contributor needs before their first PR will even build. None of it is hard. All of it lives in your head, in a RELEASING.md that's three versions out of date, and in the muscle memory you don't have at 11pm when someone's blocking PR is finally green.

The fix isn't a bigger CI config. It's putting the project's rituals in one file that you, your co-maintainers, and your contributors all run the same way — locally and in CI.

What automation looks like for a maintainer

You don't have a platform team. You have you, maybe two co-maintainers, and a CI bill of zero dollars. Automation that fits that means:

  • One file in the repo that documents and runs the project's rituals.
  • The same commands a contributor runs locally and CI runs on a PR — so "works on my machine" stops being a category of bug.
  • Releases that are a single command, not a checklist you hope you didn't skip a step in.
  • No new service to maintain. You have enough to maintain.

Where OrchStep fits

OrchStep is a single binary that wraps your existing commands — go test, npm run build, git tag — in named tasks with retries, assertions, and rollback. A contributor downloads one binary and runs the exact gate CI runs. No more "why does CI fail when it passed for me."

Here's a maintainer kit: the PR gate and the release ritual in one file.

orchstep.yml
name: maintainer-kit
defaults:
  version: "1.4.0"
  branch: main

tasks:
  # orchstep run pr-gate — the same checks a contributor runs locally
  pr-gate:
    steps:
      - name: lint
        func: shell
        do: echo "linting changed files"
      - name: test
        func: shell
        do: echo "running unit + integration tests"
        retry:
          max_attempts: 2
          interval: "1s"
          backoff_rate: 2.0
      - name: verify
        func: assert
        args:
          condition: '{{ eq vars.branch "main" }}'
          message: "release checks only run against main"

  # orchstep run release --var version=1.5.0
  release:
    steps:
      - name: changelog
        func: shell
        do: echo "generating changelog for v{{ vars.version }}"
        outputs:
          tag: "v{{ vars.version }}"
      - name: tag
        func: shell
        do: echo "tagging {{ steps.changelog.tag }}"
      - name: publish
        func: shell
        do: echo "publishing {{ steps.changelog.tag }} to the registry"
        retry:
          max_attempts: 3
          interval: "2s"
          backoff_rate: 2.0
        catch:
          - name: announce-failure
            func: shell
            do: echo "release {{ steps.changelog.tag }} failed, opening issue"

The pr-gate task is the contract: if it passes locally, it passes in CI, because it is what CI runs. The release task turns "did I remember to tag before publishing?" into a single command where the order is the file.

Three workflows worth stealing

1. The one-command release. orchstep run release --var version=1.5.0 generates the changelog, captures the tag as an output, tags, and publishes — with a retry: around the flaky publish step and a catch: that opens a failure issue instead of leaving you with a half-published release. The version is a variable, so cutting 1.5.1 is a flag, not an edit. See Variables & Outputs.

2. The contributor-runnable gate. Put pr-gate in your CONTRIBUTING guide as the command. A first-time contributor runs orchstep run pr-gate, sees exactly what the bots will see, and submits a green PR. Your CI calls the same task — the workflow refuses to hang waiting on input in a pipeline, so it's safe there. See Running in CI.

3. The "preview the release" dry-run. Before you tag anything public, orchstep run release --var version=1.5.0 --dry-run prints the resolved plan — the tag it would cut, the steps in order — and executes nothing. Cheap insurance against a fat-fingered version. See Previewing with Dry Run.

What you gained

ConcernThe old wayOrchStep
Release stepsRELEASING.md, run by handorchstep run release
Version bumpedit several files--var version=1.5.0
Flaky publishre-run, hoperetry: + catch: opens an issue
"Works on my machine"CI-only checkscontributors run the same pr-gate
Onboarding a contributora wiki pageone binary, one command
Release safetycross fingers--dry-run first

OrchStep doesn't replace GitHub Actions — your release task runs inside it, identically to how it runs on your laptop. If your project is small enough that one Makefile target covers releases, keep the Makefile. Once the release ritual has more than a couple of ordered steps with retries and a rollback, a workflow file is the thing you'll actually keep up to date.

Where to go next

Tired of running your release from memory? Put the ritual in one file and let a contributor run the gate too.

#OPEN-SOURCE#RELEASE#CI#CONTRIBUTORS
Try it in two minutes — one binary, no signup.
curl -fsSL https://orchstep.dev/install.sh | sh

RELATED — BY COMPANY SIZE