Marin Release Cycle: Daily Development Builds, Stable Releases, and Canary Testing

Marin employs a hybrid release cycle that combines automated daily development builds at 06:00 UTC, manually triggered stable releases via Git tags or workflow dispatch, and scheduled canary smoke tests to validate artifacts before PyPI publication.

The marin-community/marin repository orchestrates its release process through GitHub Actions workflows and Python automation scripts. This release cycle supports multiple Python library families with distinct versioning strategies, balancing continuous integration for rapid iteration with explicit gates for production stability.

Automated Daily Development Builds

Marin produces daily development builds automatically through the .github/workflows/marin-release-libs-wheels.yaml workflow. This workflow triggers on a cron schedule defined at line 10 of the workflow file:

on:
  schedule:
    - cron: "0 6 * * *"   # runs every day at 06:00 UTC

When this schedule fires, the workflow executes in development mode, building all Python library families and bumping development versions. The system calculates the next development version using the next_development_version function in scripts/ci/package_release.py (lines 99–110). This function generates versions following the X.Y.Z.devN pattern based on the declared version in each package's pyproject.toml and the latest published version on PyPI. The resulting wheels publish to an internal artifact store rather than PyPI.

Stable Release Triggers

Stable releases require explicit human intervention or version tags. The release workflow supports two primary triggers:

  • Workflow dispatch: A maintainer navigates to the Actions tab, selects "Marin – Release Packages," and configures the package family, mode (stable), and target version.
  • Tag push: Pushing a Git tag matching a package's tag_prefix (for example, marin-libs-v1.2.3) automatically triggers the stable release pipeline.

In stable mode, the workflow demands an explicit version supplied via the --version parameter. The resolve_version function in scripts/ci/package_release.py validates and canonicalizes this version string before the build matrix executes. After successful verification, artifacts publish directly to PyPI.

Version Resolution Logic

The scripts/ci/package_release.py script implements three distinct versioning strategies depending on the release mode:

  • Development mode: The next_development_version function computes the next X.Y.Z.devN suffix by incrementing the patch component of the declared version and appending the build serial number.

  • Stable mode: The version passes through unchanged after canonicalization, requiring the user to explicitly define the semantic version.

  • Manual mode: The version string formats as declared_version+<short_rev>, where short_rev represents the first eight characters of the commit SHA. This produces versions like 1.2.3+abc123de, enabling quick internal testing without incrementing the public version number.

Canary Testing and Quality Assurance

Before artifacts reach the main release channel, Marin runs canary smoke tests through dedicated workflows such as .github/workflows/marin-canary-grug-multislice.yaml. These workflows trigger on two cadences:

  1. Weekly scheduled runs to catch environment drift and dependency issues
  2. Pull request validation for the corresponding package changes

These canary workflows execute quick sanity checks on newly built wheels, verifying that critical import paths and basic functionality remain intact. This layer of automated testing prevents regressions from reaching either the internal artifact store or PyPI.

On-Demand and Patch Release Modes

Beyond scheduled automation, Marin supports two manual workflow dispatch modes for specialized scenarios:

Manual development releases occur when a maintainer triggers the workflow with mode=development through the GitHub UI. This bypasses the daily schedule to produce an immediate development build for a specific package family, useful for testing emergency fixes.

Patch-only manual releases activate with mode=manual, typically following a PR merge. This mode uses the repository revision (first eight characters of the commit SHA) to construct a version string like X.Y.Z+<rev>. This approach facilitates rapid internal deployment and integration testing without publishing a new semantic version to public repositories.


# Trigger a one-off manual development build for the 'iris' package

gh workflow run marin-release-libs-wheels.yaml \
  -f package=iris \
  -f mode=development

# Trigger a stable release by pushing a version tag

git tag -a marin-libs-v1.2.3 -m "Marin stable release 1.2.3"
git push origin marin-libs-v1.2.3

Summary

  • Daily automation: The marin-release-libs-wheels.yaml workflow triggers at 06:00 UTC daily to produce development builds with auto-incremented X.Y.Z.devN versions.
  • Stable gates: Production releases require either manual workflow dispatch with explicit versioning or pushing a tag matching the package's tag_prefix pattern.
  • Version strategies: Development mode auto-calculates versions, stable mode uses explicit inputs, and manual mode appends commit SHAs for internal testing.
  • Quality safeguards: Weekly canary workflows and PR-triggered smoke tests validate wheels before publication to PyPI.
  • Flexible triggers: Repository maintainers can bypass schedules using mode=development for urgent builds or mode=manual for patch testing.

Frequently Asked Questions

How often does Marin publish development builds?

Marin publishes development builds every day at 06:00 UTC through an automated GitHub Actions cron schedule defined in .github/workflows/marin-release-libs-wheels.yaml. Additionally, maintainers can trigger on-demand development builds manually through the workflow dispatch interface when immediate testing is required outside the normal schedule.

What triggers a stable release in the Marin repository?

Stable releases trigger through two mechanisms: pushing a Git tag that matches a package's designated tag_prefix (such as marin-libs-v1.2.3), or manually dispatching the release workflow via the GitHub Actions UI with mode=stable. Both methods require an explicit version number and execute the full build verification matrix before publishing to PyPI.

How does Marin determine version numbers for development releases?

The next_development_version function in scripts/ci/package_release.py (lines 99–110) determines development versions by reading the declared version from pyproject.toml, comparing it against the latest PyPI release, and appending a .devN suffix where N represents the build serial number. This ensures chronological ordering of daily snapshots while maintaining semantic versioning compatibility.

What is the difference between manual and stable release modes?

Stable mode publishes canonical semantic versions (like 1.2.3) to PyPI and requires explicit version input. Manual mode (activated with mode=manual) creates versions formatted as X.Y.Z+<short_rev> using the commit SHA, publishing to internal artifact stores for rapid integration testing without incrementing the public version number or triggering PyPI uploads.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →