Automated release management tool for MoonBit
Without these settings, moon-release cannot create release PRs.
mkdir -p .github/workflows
curl -fsSL -o .github/workflows/release.yml \
https://raw.githubusercontent.com/dijdzv/moon-release/main/templates/release.yml| Job | Trigger | Description |
|---|---|---|
| release-pr | Push to main (non-release commits) | Creates/updates a release PR with version bump |
| build | Release PR merged | Builds binaries for Linux, macOS, Windows |
| release | After build completes | Creates Git tag + GitHub Release + uploads binaries + publishes to mooncakes.io |
# Authenticate with mooncakes.io (creates ~/.moon/credentials.json)
moon login#!/usr/bin/env bash
set -euo pipefail
CREDS="$HOME/.moon/credentials.json"
if [ ! -f "$CREDS" ]; then
echo "Error: $CREDS not found. Run 'moon login' first."
exit 1
fi
TOKEN=$(jq -r '.token' "$CREDS")
USERNAME=$(jq -r '.username' "$CREDS")
if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ]; then
echo "Error: token not found in $CREDS"
exit 1
fi
if [ -z "$USERNAME" ] || [ "$USERNAME" = "null" ]; then
echo "Error: username not found in $CREDS"
exit 1
fi
echo "Setting MOONCAKES_TOKEN..."
echo "$TOKEN" | gh secret set MOONCAKES_TOKEN
echo "Setting MOONCAKES_USERNAME..."
echo "$USERNAME" | gh secret set MOONCAKES_USERNAME
echo "Done! Mooncakes credentials registered as GitHub Secrets."| Secret Name | Value |
|---|---|
| MOONCAKES_TOKEN | The token value from ~/.moon/credentials.json |
| MOONCAKES_USERNAME | The username value from ~/.moon/credentials.json |
Warning: mooncakes.io does not currently provide limited-scope tokens for CI use. The token in ~/.moon/credentials.json may have full account permissions. Use at your own risk with this understanding.
If this is a new package, you need to publish it once manually first:npm publish --access public
{
"npm_publish": true,
"npm_build_command": "moon build --target js"
} release:
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write # Required for npm Trusted Publishing
# ...
steps:
# ... (after Checkout, before Create Release)
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '24'Trusted Publishing is more secure than access tokens:
- No secrets to store or rotate
- Short-lived tokens generated per-workflow
- Scoped to specific repository and workflow
| Setting | Required | Where to Configure |
|---|---|---|
| Repository write permissions | Yes | Settings → Actions → General |
| Allow PR creation | Yes | Settings → Actions → General |
| GITHUB_TOKEN | Yes (auto) | Automatically provided |
| MOONCAKES_TOKEN | For mooncakes publish | Settings → Secrets |
| MOONCAKES_USERNAME | For mooncakes publish | Settings → Secrets |
| id-token: write | For npm publish | Workflow permissions |
| Trusted Publishing | For npm publish | npmjs.com package settings |
Recommended: Pin the moon-release version in your workflow to avoid unexpected breaking changes. The template uses minor version pinning (bash -s -- 0.2) which auto-updates patch releases. Check Releases for the latest version.To always use the latest version instead, remove the version argument:curl -fsSL https://raw.githubusercontent.com/dijdzv/moon-release/main/install.sh | bash
{
"pr_title": "chore: release v{{ version }}",
"pr_draft": false,
"pr_labels": ["release"],
"pr_body": "## Release v{{ version }}",
"pr_branch_prefix": "release/",
"base_branch": "main",
"allow_prerelease": false,
"git_tag_enable": true,
"git_tag_name": "v{{ version }}",
"git_release_enable": true,
"git_release_draft": false,
"git_release_name": "Release v{{ version }}",
"git_release_body": "{{ changelog }}",
"git_release_latest": true,
"moon_publish": true,
"moon_publish_frozen": false,
"moon_publish_timeout": 300,
"npm_publish": false,
"npm_build_command": null,
"npm_publish_provenance": true,
"npm_publish_timeout": 300,
"semver_check": false,
"registry_check": false,
"allow_dirty": false,
"custom_major_increment_regex": null,
"custom_minor_increment_regex": null,
"max_analyze_commits": null,
"bump_all_packages": false,
"bootstrap_sha": null,
"packages": []
}| Option | Default | Description |
|---|---|---|
| pr_title | "chore: release v{{ version }}" | PR title template |
| pr_draft | false | Create as draft PR |
| pr_labels | [] | Labels to add to PR |
| pr_body | - | PR body template |
| pr_branch_prefix | "release/" | Release branch prefix |
| base_branch | "main" | PR base branch |
| allow_prerelease | false | Allow prerelease versions (e.g., --prerelease alpha) |
| git_tag_enable | true | Whether to create Git tag |
| git_tag_name | "v{{ version }}" | Tag name template |
| git_release_enable | true | Whether to create GitHub Release |
| git_release_draft | false | Create as draft release |
| git_release_name | "Release v{{ version }}" | Release name template |
| git_release_body | null | Release body template (null for auto-generate) |
| git_release_latest | true | Mark GitHub Release as latest |
| moon_publish | true | Whether to publish to mooncakes.io |
| moon_publish_frozen | false | Use moon publish --frozen |
| moon_publish_timeout | 300 | Publish timeout in seconds |
| npm_publish | false | Whether to publish to npm registry |
| npm_build_command | null | Custom build command before npm publish (default: moon build --target js). Note: split by spaces, paths with spaces are not supported. |
| npm_publish_provenance | true | Use --provenance flag for npm publish. Set to false for local or non-GitHub CI publishing. |
| npm_publish_timeout | 300 | npm publish timeout in seconds |
| semver_check | false | Run API compatibility check |
| registry_check | false | Check registry version before publish |
| allow_dirty | false | Allow uncommitted changes |
| custom_major_increment_regex | null | Custom substring pattern for major bump (matched against commit description) |
| custom_minor_increment_regex | null | Custom substring pattern for minor bump (matched against commit description) |
| max_analyze_commits | null | Maximum number of commits to analyze |
| bump_all_packages | false | Bump all packages uniformly in monorepo mode (fixed versioning) |
| bootstrap_sha | null | Starting commit SHA for commit analysis (skips earlier history). Useful when migrating from another release tool. Once the first release is created, this setting is automatically ignored. |
| Variable | Description |
|---|---|
| {{ version }} | New version number |
| {{ changelog }} | Auto-generated release notes (git_release_body only) |
| Commit Type | Bump | Example |
|---|---|---|
| feat | Minor | feat: add new feature |
| fix | Patch | fix: resolve bug |
| feat! / fix! | Major | feat!: breaking change |
| BREAKING CHANGE: | Major | In footer |
{
"semver_check": true
}| Change | Impact |
|---|---|
| Removal of pub type/function/method | Breaking (Major) |
| Signature change | Breaking (Major) |
| Struct field removal/change | Breaking (Major) |
| Addition of new pub type/function | Addition (Minor) |
{
"packages": [
{
"name": "core",
"path": "packages/core",
"moon_publish": true,
"npm_publish": true,
"version_group": "main"
},
{
"name": "utils",
"path": "packages/utils",
"moon_publish": true,
"npm_publish": false,
"version_group": "main"
},
{
"name": "internal",
"path": "packages/internal",
"moon_publish": false,
"npm_publish": false
}
]
}# Only changed packages are bumped
moon-release update
# Force major bump on changed packages only
moon-release update --bump major{
"bump_all_packages": true
}# Bump all packages (uses max bump type from changed packages)
moon-release update --bump-all
# Force major bump on ALL packages
moon-release update --bump major --bump-all| Config bump_all_packages | CLI | Behavior |
|---|---|---|
| false | (none) | Changed packages only, auto bump type |
| false | --bump major | Changed packages only, forced major |
| false | --bump-all | All packages, max bump type from changes |
| false | --bump major --bump-all | All packages, forced major |
| true | (none) | All packages, max bump type from changes |
| true | --bump major | All packages, forced major |
Note: --bump controls the bump type (major/minor/patch), while --bump-all controls the bump scope (changed-only vs all packages).
moon install dijdzv/moon-releasecurl -fsSL https://raw.githubusercontent.com/dijdzv/moon-release/main/install.sh | bash# Pin to minor version (recommended: auto-updates patch releases)
curl -fsSL https://raw.githubusercontent.com/dijdzv/moon-release/main/install.sh | bash -s -- 0.2
# Pin to exact version
curl -fsSL https://raw.githubusercontent.com/dijdzv/moon-release/main/install.sh | bash -s -- 0.2.8INSTALL_DIR=/usr/local/bin curl -fsSL https://raw.githubusercontent.com/dijdzv/moon-release/main/install.sh | bash# Linux (x86_64)
curl -fsSL -o moon-release https://github.com/dijdzv/moon-release/releases/latest/download/moon-release-linux-x86_64
chmod +x moon-release
# macOS (Apple Silicon)
curl -fsSL -o moon-release https://github.com/dijdzv/moon-release/releases/latest/download/moon-release-macos-arm64
chmod +x moon-releasegit clone https://github.com/dijdzv/moon-release
cd moon-release
moon build --target native --release
cp _build/native/release/build/moon-release.exe ~/.local/bin/moon-release# Tag the commit that represents your latest release
git tag v0.1.0
git push origin --tagsgit tag v0.1.0 <commit-hash>
git push origin --tagsRecommended: Always create an initial tag. Without one, moon-release analyzes the entire commit history, which may produce unexpectedly large version bumps on repositories with a long history.
{
"bootstrap_sha": "<commit-hash>"
}# Check current state
moon-release check
# Preview version update
moon-release update --dry-run
# Update version
moon-release update
# Create release PR
moon-release release-pr
# Create release (tag + GitHub Release + publish)
moon-release releasemoon-release check
moon-release check --verbose # Show commit details
moon-release check -o json # Output in JSON formatmoon-release update # Auto-determine
moon-release update --bump major # Force major bump (changed packages only)
moon-release update --bump-all # Bump all packages (monorepo)
moon-release update --bump major --bump-all # Force major bump on all packages
moon-release update --dry-run # Preview only
moon-release update -o json # Output in JSON formatmoon-release release-pr
moon-release release-pr --bump major # Force major bump
moon-release release-pr --bump-all # Include all packages
moon-release release-pr --bump major --bump-all # Force major on all packages
moon-release release-pr --dry-runmoon-release release
moon-release release --bump major # Force major bump
moon-release release --bump-all # Include all packages
moon-release release --bump major --bump-all # Force major on all packages
moon-release release --prerelease alpha # Prerelease
moon-release release --dry-runmoon-release set-version 1.0.0moon-release init
moon-release init --force # Overwritemoon-release generate-completions bash > ~/.local/share/bash-completion/completions/moon-release
moon-release generate-completions zsh > ~/.zfunc/_moon-release
moon-release generate-completions fish > ~/.config/fish/completions/moon-release.fishmoon-release generate-schema > release-schema.json| Feature | release-plz | moon-release |
|---|---|---|
| Platform | GitHub, GitLab, Gitea | GitHub only |
| CHANGELOG | Auto-generated with git-cliff | None (use GitHub Release instead) |
| Dependency Update | cargo update | None (MoonBit uses minimal version selection) |
| API Compatibility Check | cargo-semver-checks | Built-in (uses moon doc) |
| Config Format | TOML | JSON |
| Registry | crates.io | mooncakes.io |
Install
Download zipAutomated release management tool for MoonBit