Putnami
DocsGitHub

Licensed under FSL-1.1-MIT

Getting Started
Concepts
How To
Build A Web App
Build An Api Service
Share Code Between Projects
Configure Your App
Add Persistence
Add Authentication
Add Background Jobs
Principles
Tooling & Workspace
Workspace Overview
Cli
Jobs & Commands
SDK
Error Handling
Extensions
Typescript
Go
Python
Docker
Ci
Frameworks
Typescript
OverviewWebReact RoutingForms And ActionsStatic FilesApiErrors And ResponsesConfigurationLoggingHttp And MiddlewareDependency InjectionPlugins And LifecycleSessionsAuthPersistenceEventsStorageCachingWebsocketsTestingHealth ChecksTelemetryProto GrpcSmart Client
Go
OverviewHttpDependency InjectionPlugins And LifecycleConfigurationSecurityPersistenceErrorsEventsStorageCachingLoggingTelemetryGrpcService ClientsValidationOpenapiTesting
Platform
  1. DocsSeparator
  2. Tooling & WorkspaceSeparator
  3. Ci

CI Extension

The @putnami/ci package provides CI/CD automation for Putnami workspaces. It includes git hooks, release orchestration, and provider integrations.

Scope: Git hooks are installed automatically. The release command is workspace-scoped.

External tools

  • Git
  • Conventional Commits
  • GitHub CLI (for releases and PR labelling)

Enable the extension

Install the extension at the workspace root:

bun add @putnami/ci

The extension is auto-discovered from workspace dependencies.

Commands

release

Finalize a workspace release with changelog, git tag, and version bump.

Behavior:

  1. Waits for all project publish jobs to complete (npm, docker, assets)
  2. Generates changelog from conventional commits
  3. Creates git tag for the release version
  4. Creates GitHub Release with release notes
  5. Bumps version for next development cycle

Options:

  • --promote — Perform stable release (required for changelog/tag/bump)
  • --skip-changelog — Skip changelog generation
  • --skip-tag — Skip git tag creation
  • --skip-bump — Skip version bump
  • --dry-run — Preview what would happen

Example:

# Dry run (preview what will happen)
bunx putnami release --dry-run

# Stable release
bunx putnami release --promote

# Skip specific steps
bunx putnami release --promote --skip-changelog

Command Naming Scheme

Command Scope Target Description
build project artifacts Compile, bundle
test project - Run tests
lint project - Lint code
publish project registry/assets npm, docker registry, binary assets
deploy project environment server, cloud, k8s
release workspace git Changelog, tag, version bump

Note: publish always pushes versioned artifacts. --stable additionally promotes mutable tags (latest for npm/docker) and updates binary tag manifests (tag.latest.json).

Installed Git Hooks

On dependency installation, @putnami/ci runs a postinstall script that sets up git hooks in .git/hooks/ (skipped in CI):

  • pre-commit — blocks commits on main, runs bunx putnami lint --impacted
  • pre-push — blocks pushes on main
  • commit-msg — validates Conventional Commits via commitlint

Conventional Commits

Expected format:

<type>(<scope>): <subject>

Common types: feat, fix, docs, style, refactor, test, chore, perf, ci, build, revert.

Automatic version bump detection:

Commit type Version bump
fix: patch (0.0.x)
feat: minor (0.x.0)
feat!: or BREAKING CHANGE: major (x.0.0)

Git Utilities

Provider detection

Detect the Git provider from a repository URL:

import { git } from '@putnami/ci';

const provider = git.detectProvider('git+https://github.com/user/repo.git');
// => 'github'

Supported providers: github, gitlab, bitbucket.

Changelog generation

import { git } from '@putnami/ci';

const changelog = await git.generateChangelog('1.0.0');

Git tag creation

import { git } from '@putnami/ci';

await git.createGitTag('1.0.0');
await git.pushTags();

Release Utilities

import { release } from '@putnami/ci';

// Get workspace version
const version = release.getWorkspaceVersion();

// Bump version
const nextVersion = release.bumpVersion('1.0.0', 'minor');
// => '1.1.0'

// Detect bump type from commits
const bumpType = await release.detectBumpFromCommits();
// => 'patch' | 'minor' | 'major'

GitHub Utilities

PR Labeller

The PR labeller adds/removes feat:* labels based on command arguments:

bun run node_modules/@putnami/ci/src/git/github/pr-labeller.ts 123 auth api

This ensures the PR has feat:auth and feat:api labels.

GitHub Release

Automatically creates a GitHub Release with the generated changelog:

import { git } from '@putnami/ci';

await git.github.createGitHubRelease('1.0.0', changelog);

Configuration

commitlint

To extend the default commitlint rules, add commitlint.config.js at the repository root:

module.exports = {
  extends: ['@putnami/ci/commitlint.config.js'],
  rules: {
    // custom rules
  },
};

Manual hook installation

If hooks need to be reinstalled:

bun run node_modules/@putnami/ci/src/git/install-hooks.ts

Examples

# CI workflow: build and publish pre-release (impacted packages only)
bunx putnami build --impacted
bunx putnami publish --impacted
# → npm: @putnami/pkg@1.0.0-abc1234 (canary tag on main, dev on branches)
# → Docker: registry/app:canary (or dev on branches)
# → Assets: gs://<bucket>/<prefix>/v1.0.0-abc1234
# → Manifests: gs://<bucket>/<prefix>/tag.1.0.0-abc1234.json + gs://<bucket>/<prefix>/tag.canary.json (or tag.dev.json)

# Stable release workflow (all packages with same version)
bunx putnami build --all
bunx putnami publish --all --stable
bunx putnami release --promote
# → npm: @putnami/pkg@1.0.0 (latest tag)
# → Docker: registry/app:latest
# → Assets: gs://<bucket>/<prefix>/v1.0.0
# → Manifests: gs://<bucket>/<prefix>/tag.1.0.0.json + gs://<bucket>/<prefix>/tag.latest.json
# → Changelog generated, git tag v1.0.0 created
# → .putnamirc.json version bumped to 1.0.1

Next steps

  • Previous: Docker

On this page

  • CI Extension
  • External tools
  • Enable the extension
  • Commands
  • release
  • Command Naming Scheme
  • Installed Git Hooks
  • Conventional Commits
  • Git Utilities
  • Provider detection
  • Changelog generation
  • Git tag creation
  • Release Utilities
  • GitHub Utilities
  • PR Labeller
  • GitHub Release
  • Configuration
  • commitlint
  • Manual hook installation
  • Examples
  • Next steps