[tasks.install-cargo-binstall]
script = "echo 'Checking cargo-binstall availability...'"
[tasks.install-nextest]
dependencies = ["install-cargo-binstall"]
command = "cargo"
args = ["binstall", "cargo-nextest", "--no-confirm"]
[tasks.install-llvm-cov]
dependencies = ["install-cargo-binstall"]
command = "cargo"
args = ["binstall", "cargo-llvm-cov", "--no-confirm"]
[tasks.install-cargo-release]
dependencies = ["install-cargo-binstall"]
command = "cargo"
args = ["binstall", "cargo-release", "--no-confirm"]
[tasks.install-git-cliff]
dependencies = ["install-cargo-binstall"]
command = "cargo"
args = ["binstall", "git-cliff", "--no-confirm"]
[tasks.install-wkg]
dependencies = ["install-cargo-binstall"]
command = "cargo"
args = ["binstall", "wkg", "--no-confirm"]
[tasks.tools]
dependencies = ["install-nextest", "install-llvm-cov"]
[tasks.fmt]
cwd = "."
workspace = false
command = "cargo"
args = ["fmt"]
[tasks.fmt-check]
cwd = "."
workspace = false
command = "cargo"
args = ["fmt", "--check"]
[tasks.clippy]
cwd = "."
workspace = false
command = "cargo"
args = ["clippy", "--all-targets", "--all-features", "--", "-D", "warnings"]
[tasks.build]
cwd = "."
workspace = false
command = "cargo"
args = ["build"]
[tasks.build-release]
cwd = "."
workspace = false
command = "cargo"
args = ["build", "--release"]
[tasks.test]
cwd = "."
workspace = false
dependencies = ["install-nextest"]
command = "cargo"
args = ["nextest", "run"]
[tasks.test-cargo]
cwd = "."
workspace = false
command = "cargo"
args = ["test"]
[tasks.uat]
workspace = false
script_runner = "@shell"
script = '''
cargo make ci
if [ -n "${1:-}" ]; then
cargo nextest run "$1"
fi
'''
[tasks.mr-test]
cwd = "."
workspace = false
dependencies = ["test"]
[tasks.mr-uat]
cwd = "."
workspace = false
dependencies = ["test"]
[tasks.constitution_bootstrap]
workspace = false
dependencies = ["install-nextest"]
command = "cargo"
args = ["nextest", "run", "test_bootstrap_creates_constitution"]
[tasks.constitution_template]
workspace = false
dependencies = ["install-nextest"]
command = "cargo"
args = ["nextest", "run", "test_constitution_template_content"]
[tasks.constitution_prd_new]
workspace = false
dependencies = ["install-nextest"]
command = "cargo"
args = ["nextest", "run", "test_constitution_prd_new"]
[tasks.constitution_prd_finalize]
workspace = false
dependencies = ["install-nextest"]
command = "cargo"
args = ["nextest", "run", "test_constitution_prd_finalize"]
[tasks.constitution_edit]
workspace = false
dependencies = ["install-nextest"]
command = "cargo"
args = ["nextest", "run", "test_constitution_edit"]
[tasks.constitution_violation_logging]
workspace = false
dependencies = ["install-nextest"]
command = "cargo"
args = ["nextest", "run", "test_constitution_violation_logging"]
[tasks.ci]
workspace = false
dependencies = ["fmt-check", "clippy", "test"]
[tasks.check-all]
workspace = false
dependencies = ["fmt", "test"]
[tasks.codecov]
cwd = "."
workspace = false
clear = true
dependencies = ["tools"]
command = "cargo"
args = ["llvm-cov", "nextest", "--lcov", "--output-path", "coverage.lcov"]
[tasks.codecov-html]
cwd = "."
workspace = false
clear = true
dependencies = ["tools"]
command = "cargo"
args = ["llvm-cov", "nextest", "--html"]
[tasks.build-linux]
cwd = "."
workspace = false
command = "cargo"
args = ["build", "--target", "x86_64-unknown-linux-gnu", "--release"]
[tasks.build-windows]
cwd = "."
workspace = false
command = "cargo"
args = ["build", "--target", "x86_64-pc-windows-gnu", "--release"]
[tasks.build-macos]
cwd = "."
workspace = false
command = "cargo"
args = ["build", "--target", "aarch64-apple-darwin", "--release"]
[tasks.build-wasm]
cwd = "."
workspace = false
command = "cargo"
args = ["build", "--target", "wasm32-wasip2", "--release"]
[tasks.build-oci]
cwd = "."
workspace = false
dependencies = ["build-wasm"]
[tasks.publish-oci]
dependencies = ["build-oci", "install-wkg"]
cwd = "."
workspace = false
command = "wkg"
args = [
"oci",
"push",
"ghcr.io/twitchax/microralph:latest",
"--file",
"target/wasm32-wasip2/release/mr.wasm",
]
[tasks.release-bump]
cwd = "."
workspace = false
dependencies = ["install-cargo-release"]
command = "cargo"
args = ["release", "--workspace", "--no-publish", "--execute"]
[tasks.release-builds]
cwd = "."
workspace = false
run_task = { name = [
"changelog",
"build-linux",
"build-macos",
"build-windows",
"build-wasm",
], fork = false }
[tasks.release]
cwd = "."
workspace = false
dependencies = ["ci", "changelog", "install-cargo-release"]
script_runner = "@shell"
script = '''#!/bin/bash
set -e
echo ""
echo "🚀 Starting automated release pipeline..."
echo ""
# Step 1: Version bump (cargo-release determines version from commits)
echo "📦 Step 1/5: Bumping version..."
cargo release --workspace --no-publish --execute
# Step 2: Extract new version from Cargo.toml
VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
echo " → New version: v$VERSION"
# Step 3: Commit changes
echo ""
echo "📝 Step 2/5: Committing changes..."
git add .
git commit -m "chore: release v$VERSION" || echo " → No changes to commit (already committed by cargo-release)"
# Step 4: Push to trigger CI
echo ""
echo "🚀 Step 3/5: Pushing to remote..."
git push
git push --tags
# Step 5: Wait for CI and download artifacts
echo ""
echo "⏳ Step 4/5: Waiting for CI workflow to complete..."
echo " This may take a few minutes..."
# Get the latest workflow run ID for the build workflow
sleep 5 # Give GitHub a moment to register the push
RUN_ID=""
for i in {1..60}; do
RUN_ID=$(gh run list --branch main --workflow build.yml --limit 1 --json databaseId,status --jq '.[0] | select(.status != "completed") | .databaseId' 2>/dev/null || echo "")
if [ -n "$RUN_ID" ]; then
break
fi
sleep 2
done
if [ -z "$RUN_ID" ]; then
# Try to get the most recent completed run
RUN_ID=$(gh run list --branch main --workflow build.yml --limit 1 --json databaseId --jq '.[0].databaseId')
fi
if [ -n "$RUN_ID" ]; then
echo " → Workflow run ID: $RUN_ID"
gh run watch "$RUN_ID" --exit-status || {
echo "❌ CI failed! Check the workflow at:"
echo " https://github.com/twitchax/microralph/actions/runs/$RUN_ID"
exit 1
}
echo ""
echo "📥 Step 5/5: Downloading artifacts..."
rm -rf target/release-artifacts
gh run download "$RUN_ID" --dir target/release-artifacts
echo " → Artifacts downloaded to target/release-artifacts/"
else
echo "⚠️ Could not find workflow run. Download artifacts manually with:"
echo " gh run list --branch main --workflow build.yml --limit 1 --json databaseId --jq '.[0].databaseId' | xargs -I {} gh run download {} --dir target/release-artifacts"
fi
echo ""
echo "✅ Release pipeline complete!"
echo ""
echo "Next steps:"
echo " 1. Publish: cargo make publish-all v$VERSION"
'''
[tasks.publish-all]
cwd = "."
workspace = false
script_runner = "@shell"
script = '''#!/bin/bash
set -e
TAG=${1:-}
if [ -z "$TAG" ]; then
echo "❌ Error: Version tag required"
echo "Usage: cargo make publish-all <tag>"
echo "Example: cargo make publish-all v0.1.0"
exit 1
fi
shift # Remove TAG from args, remaining args passed to github-release
echo "🚀 Starting full release pipeline for $TAG..."
echo ""
# Step 1: Publish to crates.io
echo "📦 Step 1/2: Publishing to crates.io..."
cargo make publish-crates
# Step 2: Create GitHub release with artifacts
echo ""
echo "📦 Step 2/2: Creating GitHub release..."
cargo make github-release "$TAG" "$@"
echo ""
echo "✅ Full release pipeline complete!"
echo " Published to crates.io: https://crates.io/crates/microralph"
echo " GitHub release: https://github.com/twitchax/microralph/releases/tag/$TAG"
'''
[tasks.changelog]
cwd = "."
workspace = false
dependencies = ["install-git-cliff"]
command = "git-cliff"
args = ["--output", "CHANGELOG.md"]
[tasks.publish-crates]
cwd = "."
workspace = false
dependencies = ["ci"]
script_runner = "@shell"
script = '''
echo "Running pre-publish checks..."
cargo package --no-verify --list
echo ""
echo "Publishing microralph to crates.io..."
cargo publish --no-verify ${@}
if [ "${1:-}" != "--dry-run" ]; then
echo ""
echo "✅ Published successfully!"
fi
'''
[tasks.github-release]
cwd = "."
workspace = false
script_runner = "@shell"
script = '''#!/bin/bash
set -e
TAG=${1:-}
if [ -z "$TAG" ]; then
echo "❌ Error: Version tag required"
echo "Usage: cargo make github-release <tag> [--draft]"
echo "Example: cargo make github-release v0.1.0"
exit 1
fi
echo "📦 Creating GitHub release for $TAG..."
# Prepare release notes
TEMP_DIR=$(mktemp -d)
trap "rm -rf $TEMP_DIR" EXIT
NOTES_FILE="$TEMP_DIR/release_notes.md"
if [ -f "CHANGELOG.md" ]; then
echo "Using changelog for release notes..."
cp CHANGELOG.md "$NOTES_FILE"
else
echo "## Release $TAG" > "$NOTES_FILE"
echo "" >> "$NOTES_FILE"
echo "See the full changelog at https://github.com/twitchax/microralph/blob/main/CHANGELOG.md" >> "$NOTES_FILE"
fi
# Check for artifacts directory and rename files for unique asset names
ARTIFACTS=""
STAGING_DIR=$(mktemp -d)
if [ -d "target/release-artifacts" ]; then
echo "📎 Found target/release-artifacts directory"
# Find all files recursively and rename using parent dir name
for file in $(find target/release-artifacts -type f); do
# Extract parent dir name (e.g., mr_x86_64-unknown-linux-gnu)
parent_dir=$(basename "$(dirname "$file")")
filename=$(basename "$file")
# Get extension if any
if [[ "$filename" == *.* ]]; then
ext=".${filename##*.}"
base="${filename%.*}"
else
ext=""
base="$filename"
fi
# Create unique name: mr-x86_64-unknown-linux-gnu or mr-x86_64-pc-windows-gnu.exe
new_name="${parent_dir}${ext}"
staged_file="$STAGING_DIR/$new_name"
cp "$file" "$staged_file"
echo " → $new_name"
ARTIFACTS="$ARTIFACTS \"$staged_file\""
done
fi
# Build gh release create command
GH_CMD="gh release create \"$TAG\" --title \"$TAG\" --notes-file \"$NOTES_FILE\""
# Add draft flag if requested
shift
if echo "$@" | grep -q "\-\-draft"; then
GH_CMD="$GH_CMD --draft"
echo "📝 Creating as draft release"
fi
# Add artifacts
if [ -n "$ARTIFACTS" ]; then
GH_CMD="$GH_CMD $ARTIFACTS"
fi
# Execute the release creation
echo ""
echo "🚀 Creating GitHub release..."
eval $GH_CMD
echo ""
echo "✅ GitHub release created successfully!"
echo " View at: https://github.com/twitchax/microralph/releases/tag/$TAG"
echo ""
echo "💡 To download artifacts from CI, run:"
echo " gh run list --branch main --workflow build.yml --limit 1 --json databaseId --jq '.[0].databaseId' | xargs -I {} gh run download {} --dir target/release-artifacts"
'''
[tasks.run]
cwd = "."
workspace = false
command = "cargo"
args = ["run", "--", "${@}"]
[tasks.watch]
cwd = "."
workspace = false
script = '''
cargo watch -x "run -- status"
'''
[tasks.devcontainer]
cwd = "."
workspace = false
script_runner = "@duckscript"
script = '''
# Ensure @devcontainers/cli is installed
path = which devcontainer
if is_empty ${path}
echo "📦 Installing @devcontainers/cli..."
exec npm install -g @devcontainers/cli
end
# Generate config if it doesn't exist
config_exists = is_path_exists .devcontainer/devcontainer.json
if not ${config_exists}
echo "⚠️ No devcontainer config found. Run 'cargo run -- devcontainer generate' first."
exit 1
end
echo "🚀 Starting dev container..."
exec devcontainer up --workspace-folder . --remove-existing-container
echo "🔗 Connecting to dev container..."
exec devcontainer exec --workspace-folder . bash
'''
[tasks.clean]
cwd = "."
workspace = false
command = "cargo"
args = ["clean"]