This document describes the complete release process for the LacyLights MCP server, including beta (prerelease) and stable release workflows.
- Overview
- Version Format
- Release Types
- Beta Release Process
- Stable Release Process
- Release Checklist
- Distribution Verification
- Troubleshooting
- Rollback Procedures
LacyLights MCP uses an automated release workflow that supports both beta (prerelease) and stable releases. The workflow handles version management, builds distribution archives, creates GitHub releases, and updates distribution infrastructure (S3 + DynamoDB).
Key Features:
- Automated semantic versioning
- Smart beta version incrementing
- Multi-channel distribution (GitHub, S3, DynamoDB)
- SHA256 checksums for security
- Automatic release notes generation
Format: X.Y.Z (e.g., 1.4.0, 2.0.0)
Follows Semantic Versioning 2.0.0:
- X (Major): Breaking changes, incompatible API changes
- Y (Minor): New features, backward-compatible
- Z (Patch): Bug fixes, backward-compatible
Format: X.Y.Zb[N] (e.g., 1.4.1b1, 1.5.0b3)
X.Y.Z: Base semantic versionb: Beta identifier (lowercase)[N]: Beta iteration number (1, 2, 3, ...)
Examples:
1.4.1b1- First beta for version 1.4.11.4.1b2- Second beta for version 1.4.12.0.0b1- First beta for version 2.0.0
The release workflow supports four versioning scenarios with smart detection:
When: Starting a new beta cycle from a stable release
Input:
- Current version:
1.4.0(stable) - Version bump:
patch,minor, ormajor - Is prerelease:
✓ true
Result:
patch→1.4.1b1minor→1.5.0b1major→2.0.0b1
Use cases:
- Testing new features before stable release
- Getting early user feedback
- Validating breaking changes
When: Iterating on an existing beta
Input:
- Current version:
1.4.1b1(beta) - Version bump: any (ignored)
- Is prerelease:
✓ true
Result: 1.4.1b2
Notes:
- Base version (
1.4.1) remains unchanged - Only beta counter increments
- Version bump selection is ignored
Use cases:
- Bug fixes in beta
- Incremental improvements
- Additional testing iterations
When: Promoting a beta to stable release
Input:
- Current version:
1.4.1b5(beta) - Version bump: any (ignored)
- Is prerelease:
☐ false
Result: 1.4.1 (stable)
Notes:
- Removes beta suffix
- Base version remains unchanged
- This is the only way to finalize a beta
Use cases:
- Beta testing complete
- Ready for production
- Promoting tested changes
When: Regular version bump (no beta testing)
Input:
- Current version:
1.4.0(stable) - Version bump:
patch,minor, ormajor - Is prerelease:
☐ false
Result:
patch→1.4.1minor→1.5.0major→2.0.0
Use cases:
- Hotfixes
- Standard releases
- Direct-to-stable deployments
Create beta releases when you want to:
- Test new features with early adopters
- Validate breaking changes before stable release
- Get feedback on experimental functionality
- Test integration with other LacyLights components
- Perform extended QA on significant changes
-
Navigate to GitHub Actions
- Go to: https://github.com/bbernstein/lacylights-mcp/actions
- Select: "Create Release" workflow
-
Configure Release Parameters
- Click: "Run workflow"
- Select branch:
main(or feature branch) - Version bump: Select
patch,minor, ormajor- First beta: Creates
X.Y.Zb1based on bump type - Subsequent betas: Selection ignored, increments beta number
- First beta: Creates
- Create as prerelease: ✓ Check this box
- Release name: (optional) Leave blank for auto-generated
-
Review and Run
- Click: "Run workflow"
- Workflow duration: ~3-5 minutes
-
Monitor Workflow Progress Watch for these steps:
- ✓ Version calculation
- ✓ Package.json update
- ✓ Git tag creation
- ✓ GitHub release creation
- ✓ Archive build
- ✓ S3 upload
- ✓ DynamoDB update
-
Verify Beta Release See Distribution Verification
What Happens:
- ✓ GitHub release marked as "Pre-release"
- ✓ Archive uploaded to S3:
s3://dist.lacylights.com/releases/mcp/lacylights-mcp-X.Y.Zb[N].tar.gz - ✓ DynamoDB entry created with
isPrerelease: true - ✗
latest.jsonNOT updated (stable releases only)
Notification Badge: Beta releases show an orange "Pre-release" badge on GitHub.
Create stable releases when:
- Finalizing a tested beta (beta → stable)
- Deploying production-ready changes
- Publishing hotfixes
- Releasing well-tested features
-
Navigate to GitHub Actions
- Go to: https://github.com/bbernstein/lacylights-mcp/actions
- Select: "Create Release" workflow
-
Configure Release Parameters
- Click: "Run workflow"
- Select branch:
main - Version bump: Select
patch,minor, ormajor- If current is beta: Selection ignored, removes beta suffix
- If current is stable: Normal semantic version bump
- Create as prerelease: ☐ Leave unchecked
- Release name: (optional) Leave blank for auto-generated
-
Review and Run
- Click: "Run workflow"
- Workflow duration: ~3-5 minutes
-
Monitor Workflow Progress Same steps as beta, plus:
- ✓
latest.jsonupdate
- ✓
-
Verify Stable Release See Distribution Verification
What Happens:
- ✓ GitHub release marked as "Latest release"
- ✓ Archive uploaded to S3
- ✓
latest.jsonupdated with new version - ✓ DynamoDB entry created with
isPrerelease: false
Use these checklists to ensure successful releases:
Before triggering the workflow:
- All tests passing locally (
npm test) - Linting passes (
npm run lint) - Coverage meets thresholds (70%+ lines, 65%+ functions)
- Code reviewed and approved
- CHANGELOG.md updated (if applicable)
- Breaking changes documented (for major versions)
- Integration tests pass with lacylights-go backend
- Current branch is
main(or approved feature branch)
After workflow completes:
- Git tag created:
v{version} - GitHub release published
- Prerelease flag correct (beta=true, stable=false)
- Release notes auto-generated
- Archive asset uploaded
- Archive exists at:
https://dist.lacylights.com/releases/mcp/lacylights-mcp-{version}.tar.gz - Archive downloadable (no 404)
- SHA256 checksum matches
- For stable:
latest.jsonupdated - For beta:
latest.jsonnot modified
- Item exists in
lacylights-releasestable - Component:
mcp - Version matches
-
isPrereleaseboolean correct -
releaseDatepopulated - SHA256 checksum stored
- Extract and verify archive structure:
tar -tzf lacylights-mcp-{version}.tar.gz | head -20 - Contains:
dist/,node_modules/,package.json - No test files included
- No dev dependencies included
- Archive size reasonable (~50-80MB)
#!/bin/bash
VERSION="1.4.1b1" # Replace with your version
echo "=== Verifying Release: $VERSION ==="
# 1. Check GitHub release
echo "1. GitHub Release:"
gh release view "v$VERSION" --json tagName,name,isPrerelease,publishedAt
# 2. Check S3 archive
echo ""
echo "2. S3 Archive:"
curl -I "https://dist.lacylights.com/releases/mcp/lacylights-mcp-$VERSION.tar.gz"
# 3. Check latest.json (stable only)
echo ""
echo "3. Latest JSON:"
curl -s "https://dist.lacylights.com/releases/mcp/latest.json" | jq
# 4. Verify SHA256
echo ""
echo "4. SHA256 Verification:"
curl -sL "https://dist.lacylights.com/releases/mcp/lacylights-mcp-$VERSION.tar.gz" | sha256sum# List recent releases
gh release list --limit 5
# View specific release
gh release view v1.4.1b1Expected output:
- Title:
v1.4.1b1(or custom name) - Tag:
v1.4.1b1 - Pre-release:
true(for beta) orfalse(for stable) - Assets:
lacylights-mcp-1.4.1b1.tar.gz
# Check if archive exists
curl -I https://dist.lacylights.com/releases/mcp/lacylights-mcp-1.4.1b1.tar.gz
# Download archive
curl -LO https://dist.lacylights.com/releases/mcp/lacylights-mcp-1.4.1b1.tar.gz
# Verify SHA256
sha256sum lacylights-mcp-1.4.1b1.tar.gz
# Compare with workflow output or DynamoDB recordExpected response:
- HTTP 200 OK
- Content-Type:
application/gzip - Content-Length: ~50-80MB
# Fetch latest.json
curl -s https://dist.lacylights.com/releases/mcp/latest.json | jqExpected for stable release:
{
"version": "1.4.1",
"url": "https://dist.lacylights.com/releases/mcp/lacylights-mcp-1.4.1.tar.gz",
"sha256": "abc123...",
"releaseDate": "2025-11-24T16:30:00Z",
"isPrerelease": false,
"fileSize": 52428800
}Expected for beta release:
- Previous stable version remains in
latest.json - Beta version NOT in
latest.json
# Query DynamoDB (requires AWS credentials)
aws dynamodb get-item \
--table-name lacylights-releases \
--key '{"component": {"S": "mcp"}, "version": {"S": "1.4.1b1"}}'Expected attributes:
component:"mcp"version:"1.4.1b1"url: Full S3 URLsha256: SHA256 checksumreleaseDate: ISO 8601 timestampisPrerelease:true(beta) orfalse(stable)fileSize: Number (bytes)
# Extract archive
tar -xzf lacylights-mcp-1.4.1b1.tar.gz
cd lacylights-mcp
# Verify version
node -p "require('./package.json').version"
# Expected: 1.4.1b1
# Test run
npm start
# Should start without errorsSymptoms:
- Workflow fails at "Create Git tag" step
- Error:
fatal: tag 'vX.Y.Z' already exists
Cause: Workflow previously ran but failed after creating tag.
Solution:
# Option 1: Delete tag and re-run
git push --delete origin v1.4.1b1
git tag -d v1.4.1b1
# Option 2: Skip to next beta
# If v1.4.1b1 exists, create v1.4.1b2 insteadSymptoms:
- Workflow logs: "Release vX.Y.Z already exists. Skipping creation."
Cause: GitHub release exists but workflow is re-running.
Behavior:
- Workflow continues (not an error)
- S3 and DynamoDB still update
- Archive overwrites existing
Action: No action needed. This is expected behavior for workflow reruns.
Symptoms:
- Workflow fails at "Upload to S3" step
- Error:
AccessDeniedorNoSuchBucket
Cause: AWS credentials invalid or expired.
Solution:
- Verify secrets in GitHub:
AWS_DIST_ACCESS_KEY_IDAWS_DIST_SECRET_ACCESS_KEYAWS_DIST_REGIONAWS_DIST_BUCKET
- Test credentials locally:
aws s3 ls s3://dist.lacylights.com/releases/mcp/
- Contact AWS administrator if credentials need rotation
Symptoms:
- Stable release created
latest.jsonshows old version
Diagnosis:
# Check workflow logs for "Skipping latest.json"
# If present, version incorrectly detected as prerelease
# Verify version format
echo "1.4.1b5" | grep -E 'b[0-9]+$' # Should match for beta
echo "1.4.1" | grep -E 'b[0-9]+$' # Should NOT match for stableSolution:
- Verify version in
package.jsonis stable (nobsuffix) - Check workflow logs for prerelease detection
- Re-run workflow if version is correct
Symptoms:
- Workflow fails at "Update DynamoDB" step
- Error:
ResourceNotFoundExceptionorAccessDeniedException
Cause: DynamoDB table doesn't exist or permissions incorrect.
Solution:
- Verify table exists:
aws dynamodb describe-table --table-name lacylights-releases
- Check IAM permissions for:
dynamodb:PutItemdynamodb:GetItem
- Verify table schema:
- Partition key:
component(String) - Sort key:
version(String)
- Partition key:
Symptoms:
- Archive > 100MB
- Slow uploads/downloads
Diagnosis:
# Extract and check size breakdown
tar -xzf lacylights-mcp-X.Y.Z.tar.gz
du -sh lacylights-mcp/*Common causes:
- Dev dependencies included (should be omitted)
.cachedirectories not excluded- Test files included
Solution: Check workflow "Create release archive" step excludes:
.git.githubnode_modules/.cache*.test.ts__tests__
# List recent workflow runs
gh run list --workflow=release.yml --limit 5
# View logs for specific run
gh run view <run-id> --log# Re-run failed workflow
gh run rerun <run-id>
# Re-run failed jobs only
gh run rerun <run-id> --failed# Simulate workflow version calculation
CURRENT_VERSION="1.4.0"
IS_PRERELEASE="true"
VERSION_BUMP="patch"
# Extract base and beta number
if [[ "$CURRENT_VERSION" =~ b[0-9]+$ ]]; then
BASE_VERSION=$(echo "$CURRENT_VERSION" | sed 's/b[0-9]*$//')
BETA_NUM=$(echo "$CURRENT_VERSION" | grep -oE 'b[0-9]+$' | sed 's/b//')
else
BASE_VERSION="$CURRENT_VERSION"
BETA_NUM=0
fi
echo "Base: $BASE_VERSION, Beta: $BETA_NUM"When:
- Beta has critical bugs
- Want to revert to previous beta
Steps:
-
Create new beta with fixes (recommended)
# If current: 1.4.1b2 (broken) # Create: 1.4.1b3 (with fixes)
-
OR: Unpublish beta release
# Delete GitHub release gh release delete v1.4.1b2 --yes # Delete git tag git push --delete origin v1.4.1b2
Note: Cannot rollback S3/DynamoDB entries. Mark version as deprecated instead.
When:
- Stable release has critical production bug
- Need to revert to previous stable
Steps:
-
Update latest.json to previous version
# Manually update latest.json in S3 aws s3 cp s3://dist.lacylights.com/releases/mcp/latest.json latest.json # Edit to point to previous version vim latest.json # Change version, url, sha256 # Upload updated file aws s3 cp latest.json s3://dist.lacylights.com/releases/mcp/latest.json \ --content-type "application/json"
-
Mark problematic release as deprecated
# Edit GitHub release gh release edit v1.4.1 --notes "⚠️ DEPRECATED: Critical bug found. Use v1.4.0 instead."
-
Create hotfix release
# After fixing, create new patch version # If current: 1.4.1 (broken) # Create: 1.4.2 (with fixes)
Important: Do not delete stable releases from S3/DynamoDB. Users may have pinned versions.
When:
- Critical security vulnerability
- Data corruption risk
Immediate Actions:
-
Unpublish GitHub release
gh release delete vX.Y.Z --yes gh release delete vX.Y.Z # Confirm -
Delete S3 archive
aws s3 rm s3://dist.lacylights.com/releases/mcp/lacylights-mcp-X.Y.Z.tar.gz
-
Update latest.json to previous safe version
# See Scenario 2 steps -
Add DynamoDB warning attribute (optional)
aws dynamodb update-item \ --table-name lacylights-releases \ --key '{"component": {"S": "mcp"}, "version": {"S": "X.Y.Z"}}' \ --update-expression "SET deprecated = :true, deprecationReason = :reason" \ --expression-attribute-values '{":true": {"BOOL": true}, ":reason": {"S": "Security vulnerability"}}'
-
Notify users
- Post GitHub issue
- Update README with warning
- Send notifications via appropriate channels
Best Practices:
-
Always test betas before stable
- Create
X.Y.Zb1first - Test with real workloads
- Gather user feedback
- Iterate with
b2,b3, etc. - Only finalize to stable when confident
- Create
-
Use staging environments
- Test against lacylights-go backend
- Run contract tests
- Validate with real fixtures
-
Review checklist
- Follow Release Checklist
- Don't skip pre-release validation
- Verify post-release validation
-
Monitor after release
- Watch for user reports
- Check error logs
- Monitor GitHub issues
Patch (X.Y.Z → X.Y.Z+1):
- Bug fixes
- Performance improvements
- Documentation updates
- Internal refactoring (no API changes)
Minor (X.Y.Z → X.Y+1.0):
- New features (backward-compatible)
- New MCP tools
- Enhanced existing functionality
- Deprecations (with backward compatibility)
Major (X.Y.Z → X+1.0.0):
- Breaking changes
- Removed deprecated features
- Changed tool interfaces
- GraphQL schema breaking changes
- Incompatible with previous versions
When to use betas:
- New major versions (
2.0.0b1,2.0.0b2, etc.) - Significant new features
- Breaking changes
- Changes requiring user testing
Beta lifecycle:
1.4.0 (stable)
↓
1.5.0b1 (first beta)
↓
1.5.0b2 (fixes)
↓
1.5.0b3 (more testing)
↓
1.5.0 (finalized stable)
- GitHub Actions Workflow:
.github/workflows/release.yml - Workflow Testing Guide:
.github/workflows/TESTING.md - Repository: https://github.com/bbernstein/lacylights-mcp
- Distribution: https://dist.lacylights.com/releases/mcp/
For issues with the release process:
- Check Troubleshooting section
- Review workflow logs in GitHub Actions
- Open an issue: https://github.com/bbernstein/lacylights-mcp/issues