Skip to content

Release Process

This page describes the CI/CD pipeline and automated release workflow for the mcp-automem package. The release process is fully automated using Release Please with conventional commits, requiring no manual version bumping or changelog updates.

For build and test procedures, see Testing.

The pipeline operates in three stages:

  1. Development Stage: Local git hooks enforce commit message conventions via Husky and commitlint
  2. Validation Stage: Automated workflows verify code quality, security, and functionality on every change
  3. Release Stage: Automated versioning, publishing to npm, and building distribution artifacts
graph TB
    PR["Pull Request\nor Push to main"]

    PR --> CI_WF["ci.yml\nWorkflow"]
    PR --> SEC_WF["security.yml\nWorkflow"]
    PR --> SEM_WF["semantic-pr-title.yml\nWorkflow"]

    CI_WF --> LINKS["lychee-action\nCheck links in docs"]
    CI_WF --> LINT["npm run lint\nESLint"]
    CI_WF --> BUILD["npm run build\nTypeScript compile"]
    CI_WF --> TEST["npm test\nUnit tests"]
    CI_WF --> COV["npm run test:coverage\nCoverage report"]

    SEC_WF --> CODEQL["CodeQL Analysis\nStatic security scan"]
    SEC_WF --> AUDIT["npm audit\nDependency vulnerabilities"]
    SEC_WF --> BETTER["better-npm-audit\nEnhanced vulnerability check"]

    SEM_WF --> TITLE_CHECK["amannn/action-semantic-pull-request\nValidate PR title format"]

    MERGE["Merge to main"]

    MERGE --> REL_WF["release-please.yml\nWorkflow"]

    REL_WF --> RP_PR["Release Please\nCreate/update PR"]

    RP_PR --> RP_MERGE["Merge Release PR"]

    RP_MERGE --> PUBLISH["npm-publish Job"]
    RP_MERGE --> MCPB["build-extension Job"]

    PUBLISH --> NPM["npm publish\nTrusted Publishing (OIDC)"]
    MCPB --> GH_REL["Upload .mcpb to\nGitHub Release"]

All commits must follow the Conventional Commits specification. The commit type determines version bump behavior.

Commit TypeVersion BumpExample
feat:Minor (0.x.0)feat: add cursor setup command
fix:Patch (0.0.x)fix: prevent stdout corruption in stdio mode
feat!: or BREAKING CHANGE:Major (x.0.0)feat!: remove search_by_tag tool
chore:, docs:, test:, ci:Nonechore: update dependencies

Accepted types: fix, feat, chore, docs, refactor, test, ci, build, perf, revert

The repository enforces conventional commits at two levels:

  1. Local enforcement: .husky/commit-msg runs commitlint on every commit using configuration from .commitlintrc.cjs. This provides immediate feedback during development.

  2. CI enforcement: semantic-pr-title.yml validates PR titles on opened, edited, synchronize, and reopened events. Since the repository uses squash-merge, the PR title becomes the merge commit message.

Runs on every pull request and push to main.

Validates all URLs in documentation files to prevent broken links.

ConfigurationValue
Runnerubuntu-latest
Actionlycheeverse/lychee-action@v2
Target FilesREADME.md, INSTALLATION.md, CHANGELOG.md
Accepted Status Codes200, 204, 301, 302, 403
Exclusionslocalhost, 127.0.0.1, x.com/i/communities, GitHub compare URLs

Comprehensive quality checks:

StepCommandFail Behavior
Lintnpm run lintFails build
Buildnpm run buildFails build
Testnpm testFails build
Coveragenpm run test:coverageContinue on error

The coverage step uses continue-on-error: true to prevent flaky coverage thresholds from blocking merges.

Runs weekly, on PRs, on pushes to main, and on manual dispatch.

Static analysis security testing using GitHub’s CodeQL engine for TypeScript. Results are uploaded to the GitHub Security tab under Code Scanning alerts.

Scans npm dependencies using two tools:

ToolCommandAudit LevelFail Behavior
npm auditnpm audit --audit-level=highHigh severity onlyContinue on error for PRs
better-npm-auditnpx better-npm-audit audit --level highHigh severity onlyContinue on error for PRs

Conditional error handling: On pull requests, errors are reported but don’t fail the build. On pushes to main, errors fail the build. This allows developers to see security issues in PRs without blocking development while enforcing fixes on the main branch.

Release Please Workflow (release-please.yml)

Section titled “Release Please Workflow (release-please.yml)”
sequenceDiagram
    participant Dev as Developer
    participant PR as Pull Request
    participant Main as main Branch
    participant RP as Release Please
    participant NPM as npm Registry
    participant GH as GitHub Releases

    Dev->>PR: Commit with conventional format\n(feat:, fix:, etc.)
    PR->>Main: Merge to main
    Main->>RP: Trigger release-please.yml

    RP->>RP: Analyze commits since last release
    RP->>RP: Calculate version bump\n(major/minor/patch)
    RP->>Main: Create/update Release PR\n(version, CHANGELOG.md)

    Note over Main,RP: Release PR stays open until\nmaintainer is ready to release

    Dev->>RP: Merge Release PR
    RP->>RP: Detect release_created=true

    par Parallel Publishing
        RP->>NPM: Job: npm-publish\nnpm ci, build, test, publish
        RP->>GH: Job: build-extension\nnpm ci, build, mcpb pack
    end

    NPM-->>RP: Package published with provenance
    GH-->>RP: .mcpb file uploaded to release
JobTriggerPurposeOutputs
release-pleaseEvery push to mainAnalyze commits, manage Release PRrelease_created, tag_name
npm-publishrelease_created == truePublish to npm registryPackage on npm
build-extensionrelease_created == trueBuild and upload .mcpb fileAttachment on GitHub Release

Release Please automatically updates version numbers across five files using the extra-files configuration in release-please-config.json:

FileField UpdatedPurpose
package.jsonversionnpm package version
plugins/server/server.jsonversionMCP server metadata
plugins/.claude-plugin/manifest.jsonversionClaude Desktop extension manifest
plugins/.claude-plugin/plugin.jsonversionClaude Plugin marketplace metadata
plugins/.claude-plugin/marketplace.jsonversionMarketplace listing version

Release Please analyzes all commits since the last release tag and determines the version bump based on the highest-priority change:

  1. Major bump (x.0.0): Any commit with ! after type (e.g., feat!:) or BREAKING CHANGE: in footer
  2. Minor bump (0.x.0): Any feat: commit without breaking change marker
  3. Patch bump (0.0.x): Any fix: commit
  4. No release: Only chore:, docs:, test:, ci: commits

The npm-publish job uses OIDC-based authentication (Trusted Publishing), eliminating the need for stored NPM_TOKEN secrets.

Publishing command:

Terminal window
npm publish --access public --provenance
  • --access public: Required for scoped packages (@verygoodplugins/mcp-automem)
  • --provenance: Includes build provenance (commit SHA, workflow, attestations) in package metadata

The OIDC token proves the publish request originates from the authorized GitHub Actions workflow, without requiring long-lived credentials.

The build-extension job creates the Claude Desktop .mcpb extension file:

  1. Build phase: Check out code, install dependencies (npm ci), compile TypeScript (npm run build)
  2. Pack phase: Run npx @anthropic-ai/mcpb pack — bundles compiled server code from dist/, manifest.json, server.json, and dependencies
  3. Upload phase: Attach all *.mcpb files to the GitHub Release identified by the tag_name output from the release-please job

Local testing: Build the extension locally with npm run build:extension.

GateRequired ForEnforced By
Conventional commitsAll mergescommitlint (local), release-please (GitHub)
Link validityPR mergeCI workflow
ESLint passingPR mergeCI workflow
Build successPR mergeCI workflow
Tests passingPR mergeCI workflow
No high-severity vulnerabilitiesMain branchSecurity workflow (warnings on PRs)
CodeQL analysisMain branchSecurity workflow

Coverage reporting is informational only and does not block merges.

Each workflow uses the principle of least privilege:

WorkflowPermissions
CIDefault (read-only)
Securitycontents: read, security-events: write
Release Pleasecontents: write, pull-requests: write
npm-publishcontents: read, id-token: write
build-extensioncontents: write

No stored secrets (like NPM_TOKEN) are required due to Trusted Publishing.

Automated dependency updates via GitHub Dependabot run weekly and are grouped into two categories:

Production Dependencies Group: All dependencies excluding @types/*, typescript, vitest, eslint*, prettier

Dev Dependencies Group: @types/*, typescript, vitest, eslint*, prettier

This grouping prevents excessive PRs by batching related updates. All dependency updates use the chore(deps): conventional commit prefix, which does not trigger version bumps.

ChannelURL PatternFormatTarget Users
npm Registry@verygoodplugins/mcp-automem.tgz packageCLI users, programmatic integrations
GitHub Releasesgithub.com/verygoodplugins/mcp-automem/releases.mcpb fileClaude Desktop one-click install

npm install:

Terminal window
npx @verygoodplugins/mcp-automem setup
# or
npm install -g @verygoodplugins/mcp-automem

Claude Desktop extension install:

  1. Download .mcpb file from GitHub Release
  2. Double-click to install (macOS/Windows)
  3. Extension installed to Claude Desktop automatically
  • Day 1: First feat: commit to main → release-please creates Release PR with version bump
  • Days 2-7: Additional commits → release-please updates Release PR (version may change if higher-priority commits added)
  • Day 8: Maintainer merges Release PR → Parallel jobs publish to npm and GitHub Releases within ~5 minutes

Releases can be created as frequently as needed by merging the Release PR.

IssueSymptomResolution
Commit rejected locallycommitlint fails on commitFix commit message format: type: description
PR blocked in CIsemantic-pr-title failsEdit PR title to use conventional format
Release PR not createdNo PR after pushing to mainCheck commits — only feat:, fix:, feat!: trigger releases
npm publish failsAuthentication errorVerify Trusted Publishing configured in npm package settings
Extension build fails.mcpb file not createdCheck manifest.json and server.json exist and are valid JSON
Version out of syncDifferent versions across filesManually update .release-please-manifest.json, delete Release PR, push again

If automation fails, manual publishing is possible:

Terminal window
npm run build
npm test
npm publish --access public

However, this bypasses provenance attestation and version synchronization. Prefer fixing automation issues over manual releases.