# Release Strategy for Openship Packages: Automated Semantic Versioning and Distribution

> Discover the Openship release strategy: automated semantic versioning, Git tagging, GitHub Releases, and cross-platform builds. Learn how Openship streamlines package distribution.

- Repository: [oblien/openship](https://github.com/oblien/openship)
- Tags: best-practices
- Published: 2026-07-23

---

**Openship employs a single-source-of-truth versioning model where [`scripts/release.ts`](https://github.com/oblien/openship/blob/main/scripts/release.ts) synchronizes semantic versions across all monorepo packages, commits changes, creates Git tags, and triggers a GitHub Actions workflow that builds cross-platform installers, publishes the CLI to npm via OIDC, and creates annotated GitHub Releases with SHA-256 checksums.**

The `oblien/openship` repository maintains a unified release pipeline for its CLI, desktop application, web dashboard, and email service. Understanding the **release strategy for openship packages** ensures that contributors can ship consistent, reproducible updates across all distribution channels while maintaining strict version alignment between components.

## Single-Source-of-Truth Versioning

Openship centralizes version authority in [`apps/api/package.json`](https://github.com/oblien/openship/blob/main/apps/api/package.json). The release script reads the current version from this file, detects drift against the root [`package.json`](https://github.com/oblien/openship/blob/main/package.json), and computes the next semantic version based on the specified bump type. This approach guarantees that the API package—which serves as the operative source—dictates the version for the entire ecosystem.

The `SYNCED_PKGS` array in [`scripts/release.ts`](https://github.com/oblien/openship/blob/main/scripts/release.ts) defines which manifests receive version updates: the root [`package.json`](https://github.com/oblien/openship/blob/main/package.json), [`apps/api/package.json`](https://github.com/oblien/openship/blob/main/apps/api/package.json), [`apps/desktop/package.json`](https://github.com/oblien/openship/blob/main/apps/desktop/package.json), [`apps/web/package.json`](https://github.com/oblien/openship/blob/main/apps/web/package.json), [`apps/email/package.json`](https://github.com/oblien/openship/blob/main/apps/email/package.json), and [`apps/cli/package.json`](https://github.com/oblien/openship/blob/main/apps/cli/package.json). When the script executes, it writes the new version to all listed manifests atomically.

## The Release Automation Script ([`scripts/release.ts`](https://github.com/oblien/openship/blob/main/scripts/release.ts))

Located at [`scripts/release.ts`](https://github.com/oblien/openship/blob/main/scripts/release.ts), the central release orchestrator handles version computation, manifest synchronization, advisory generation, and Git operations.

### Computing and Synchronizing Versions

The script accepts bump arguments (`patch`, `minor`, `major`, `rc`) or explicit semver strings (e.g., `1.2.0-beta.3`). It validates the current state by comparing [`apps/api/package.json`](https://github.com/oblien/openship/blob/main/apps/api/package.json) against the root manifest, then calculates the next version. Lines 46-53 of the script iterate through `SYNCED_PKGS` to update each [`package.json`](https://github.com/oblien/openship/blob/main/package.json) with the computed version, ensuring lock-step consistency across the monorepo.

### Advisory Integration and User Notifications

When the `publish` flag is provided, the script writes an entry to [`release-advisories.json`](https://github.com/oblien/openship/blob/main/release-advisories.json) at lines 62-71. This JSON file drives the in-app upgrade banner, supporting severity levels of `critical`, `recommended`, or `info`. Only stable releases (tags without a hyphen) trigger user-facing announcements; prerelease tags (`-rc.N`, `-beta.N`) bypass the advisory system to prevent notification fatigue.

### Git Tagging and Commit Operations

After staging modified files, the script creates a commit with the message `Bump to vX.Y.Z` (or `Announce vX.Y.Z` when publishing an advisory) and pushes the branch. It then generates an annotated Git tag matching the version (e.g., `v2.1.0`) and pushes the tag to origin. This tag push serves as the definitive trigger for the CI/CD pipeline.

## CI/CD Pipeline Execution ([`.github/workflows/release.yml`](https://github.com/oblien/openship/blob/main/.github/workflows/release.yml))

The file [`.github/workflows/release.yml`](https://github.com/oblien/openship/blob/main/.github/workflows/release.yml) defines the Release workflow, which triggers on `push.tags: 'v*.*.*'`.

### Build Matrix and Artifact Generation

The workflow executes a multi-stage build process:

- **Native installers**: Compiles distributables for macOS, Windows, and Linux
- **Server packages**: Creates tarballs for the API and email service
- **Dashboard bundle**: Builds the Next.js web dashboard for static deployment

Each artifact receives a SHA-256 checksum for integrity verification.

### NPM Publishing with OIDC Trusted Publishing

Lines 45-50 of the workflow configure npm publishing using **OIDC trusted publishing**, eliminating the need for long-lived authentication tokens. The `openship` CLI package uploads to the npm registry automatically upon successful build completion.

### GitHub Release Creation

The final stage assembles a GitHub Release containing all built assets, including desktop installers, API tarballs, and checksum files. The workflow automatically classifies the release as stable or prerelease based on the tag format—tags containing a hyphen (e.g., `v2.0.0-rc.1`) are marked as prereleases, while standard semver tags generate full releases.

## Running a Release: Practical Commands

Execute releases locally using `bun scripts/release.ts` with the following patterns:

**Basic patch release without announcement:**

```bash
bun scripts/release.ts patch

```

**Announced minor release with advisory:**

```bash
bun scripts/release.ts minor publish

```

**Critical security release with custom messaging:**

```bash
bun scripts/release.ts major publish --critical --message="⚡️ Critical security update – upgrade now!"

```

**Dry-run to preview changes:**

```bash
bun scripts/release.ts rc --dry-run

```

**Explicit prerelease version:**

```bash
bun scripts/release.ts 1.2.0-beta.3

```

## Key Configuration Files

The release strategy relies on several critical files:

- **[`scripts/release.ts`](https://github.com/oblien/openship/blob/main/scripts/release.ts)** — Central automation script handling version computation, manifest syncing, and Git operations
- **[`.github/workflows/release.yml`](https://github.com/oblien/openship/blob/main/.github/workflows/release.yml)** — CI workflow triggered by version tags; manages builds, publishing, and release creation
- **[`release-advisories.json`](https://github.com/oblien/openship/blob/main/release-advisories.json)** — Database of upgrade advisories controlling in-app notification banners
- **[`apps/api/package.json`](https://github.com/oblien/openship/blob/main/apps/api/package.json)** — Canonical version source used to determine the next release number
- **[`apps/cli/package.json`](https://github.com/oblien/openship/blob/main/apps/cli/package.json)** — Manifest for the npm-published CLI tool
- **[`apps/desktop/package.json`](https://github.com/oblien/openship/blob/main/apps/desktop/package.json)**, **[`apps/web/package.json`](https://github.com/oblien/openship/blob/main/apps/web/package.json)**, **[`apps/email/package.json`](https://github.com/oblien/openship/blob/main/apps/email/package.json)** — Synchronized manifests for platform-specific builds

## Summary

- Openship uses [`apps/api/package.json`](https://github.com/oblien/openship/blob/main/apps/api/package.json) as the single source of truth for version numbers across all packages.
- The [`scripts/release.ts`](https://github.com/oblien/openship/blob/main/scripts/release.ts) CLI tool automates version bumping, manifest synchronization, advisory creation, and Git tagging.
- Pushing a `v*.*.*` tag triggers [`.github/workflows/release.yml`](https://github.com/oblien/openship/blob/main/.github/workflows/release.yml) to build cross-platform installers and publish the CLI to npm via OIDC.
- Stable releases support in-app upgrade notifications through [`release-advisories.json`](https://github.com/oblien/openship/blob/main/release-advisories.json), while prereleases (`-rc`, `-beta`) bypass user announcements.
- The workflow generates SHA-256 checksums for all artifacts and creates fully annotated GitHub Releases automatically.

## Frequently Asked Questions

### How does Openship ensure all packages stay synchronized?

The `SYNCED_PKGS` array in [`scripts/release.ts`](https://github.com/oblien/openship/blob/main/scripts/release.ts) explicitly lists every package manifest that must share the same version. When the script runs, it writes the computed version to the root [`package.json`](https://github.com/oblien/openship/blob/main/package.json), [`apps/api/package.json`](https://github.com/oblien/openship/blob/main/apps/api/package.json), [`apps/desktop/package.json`](https://github.com/oblien/openship/blob/main/apps/desktop/package.json), [`apps/web/package.json`](https://github.com/oblien/openship/blob/main/apps/web/package.json), [`apps/email/package.json`](https://github.com/oblien/openship/blob/main/apps/email/package.json), and [`apps/cli/package.json`](https://github.com/oblien/openship/blob/main/apps/cli/package.json) in a single operation, preventing version drift between components.

### What distinguishes stable releases from prereleases in the Openship workflow?

The [`.github/workflows/release.yml`](https://github.com/oblien/openship/blob/main/.github/workflows/release.yml) workflow parses the Git tag format to classify releases. Tags matching `v*.*.*` without hyphens (e.g., `v2.1.0`) trigger stable release processes, including eligibility for [`release-advisories.json`](https://github.com/oblien/openship/blob/main/release-advisories.json) entries. Tags containing hyphens (e.g., `v2.1.0-rc.1` or `v2.1.0-beta.3`) are automatically marked as prereleases in GitHub and do not generate in-app upgrade banners.

### How is the `openship` CLI published to npm without storing authentication tokens?

The release workflow implements **OIDC trusted publishing** as configured in lines 45-50 of [`.github/workflows/release.yml`](https://github.com/oblien/openship/blob/main/.github/workflows/release.yml). This mechanism allows the GitHub Actions runner to exchange a short-lived OIDC token for temporary npm publish permissions, eliminating the need to store long-lived npm authentication tokens in repository secrets.

### Can I test the release process without creating an actual tag or commit?

Yes. Append the `--dry-run` flag to any release command (e.g., `bun scripts/release.ts minor --dry-run`). This executes the version computation and file modification logic without committing changes, creating tags, or pushing to the remote repository, allowing maintainers to preview the exact files and versions that would be affected.