
Oma Dev Workflow
- 124 installs
- 41 repo stars
- Updated August 4, 2026
- gracefullight/stock-checker
Coordinate day-to-day stock-checker development—branch strategy, task breakdown, review handoffs, and oma rituals so humans and agents stay aligned on priorities.
About
oma-dev-workflow defines how stock-checker work flows from ticket to merge: pick a branch, delegate subtasks to specialized oma skills, run local checks, open PRs, and close loops with reviewers. It reduces context switching and duplicate effort across commit, db, infra, and orchestrator skills.
- Branch and PR lifecycle
- Task slicing for agents
- Review and merge gates
- Daily oma rituals
- Cross-skill execution order
Oma Dev Workflow by the numbers
- 124 all-time installs (skills.sh)
- Ranked #1,279 of 3,282 Productivity & Planning skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/gracefullight/stock-checker --skill oma-dev-workflowAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 124 |
|---|---|
| repo stars | ★ 41 |
| Last updated | August 4, 2026 |
| Repository | gracefullight/stock-checker ↗ |
What it does
Coordinate day-to-day stock-checker development—branch strategy, task breakdown, review handoffs, and oma rituals so humans and agents stay aligned on priorities.
Files
Dev Workflow - Monorepo Task Automation Specialist
Scheduling
Goal
Set up, run, optimize, and troubleshoot reproducible development workflows in monorepos using mise, task automation, validation pipelines, CI/CD, migrations, i18n builds, and release coordination.
Intent signature
- User asks about dev servers, mise tasks, lint/format/typecheck/test/build, git hooks, CI/CD, migrations, generated clients, i18n builds, or release automation.
- User needs workflow execution or developer environment setup rather than product feature implementation.
When to use
- Running development servers for monorepo with multiple applications
- Executing lint, format, typecheck across multiple apps in parallel
- Managing database migrations and schema changes
- Generating API clients or code from schemas
- Building internationalization (i18n) files
- Executing production builds and deployment preparation
- Running parallel tasks in monorepo context
- Setting up pre-commit validation workflows
- Troubleshooting mise task failures or configuration issues
- Optimizing CI/CD pipelines with mise
When NOT to use
- Database schema design or query tuning -> use DB Agent
- Backend API implementation -> use Backend Agent
- Frontend UI implementation -> use Frontend Agent
- Mobile development -> use Mobile Agent
Expected inputs
- Requested workflow operation, affected apps/packages, and current monorepo structure
mise.toml, task definitions, CI files, migration/i18n/build configs, and failure logs when relevant- Desired validation, setup, or release outcome
Expected outputs
- Executed or documented mise task workflow
- Updated workflow config, CI/CD pipeline, hooks, env template, or release guidance when requested
- Status report with commands, outputs, failures, and next actions
Dependencies
mise, project task definitions, runtime versions, package managers behind mise tasks- Resource guides for validation, database patterns, API workflows, i18n, release coordination, and troubleshooting
Control-flow features
- Branches by affected apps, task dependency graph, port availability, task failure, and CI/release context
- Calls local process commands; may write workflow/config files
- Must avoid destructive tasks and secrets in workflow configs
Structural Flow
Entry
1. Identify affected apps/packages and requested workflow outcome. 2. Read mise.toml files and available tasks. 3. Determine whether tasks can run in parallel or must be sequential.
Scenes
1. PREPARE: Analyze requirements, task graph, runtime prerequisites, and ports. 2. ACQUIRE: Inspect mise config, task definitions, CI hooks, env patterns, and logs. 3. ACT: Run or modify mise tasks, workflow configs, or validation pipelines. 4. VERIFY: Check exit codes, generated artifacts, logs, and CI compatibility. 5. FINALIZE: Report command status, duration, failures, and next steps.
Transitions
- If runtime versions changed, run
mise install. - If changed-file tasks exist, prefer changed-scope validation.
- If port is occupied, resolve or select another port before starting dev server.
- If a task is unfamiliar, read its definition before running.
Failure and recovery
- If task is missing, run
mise tasks --all. - If runtime is missing, run or recommend
mise install. - If task hangs, check for prompts or long-running dev-server behavior.
- If destructive task is requested, require confirmation.
Exit
- Success: workflow runs or config changes are verified.
- Partial success: task failures, missing runtime, or CI/environment blockers are explicit.
Logical Operations
Actions
| Action | SSL primitive | Evidence |
|---|---|---|
| Read task definitions | READ | mise.toml, CI config |
| Select task strategy | SELECT | Parallel/sequential/changed-scope |
| Run workflow commands | CALL_TOOL | mise run, mise install, mise tasks |
| Write workflow config | WRITE | Hooks, CI, env templates |
| Validate outputs | VALIDATE | Exit codes, logs, artifacts |
| Report status | NOTIFY | Final workflow summary |
Tools and instruments
mise, shell, CI/CD tooling, project package manager tasks behind mise- Resource guides for validation, database, API, i18n, release, and troubleshooting
Canonical command path
mise tasks --all
mise install
mise run lint
mise run testFor app-specific tasks:
mise run //{path}:{task}Resource scope
| Scope | Resource target |
|---|---|
CODEBASE | mise.toml, CI configs, scripts, generated clients |
LOCAL_FS | Env templates, build outputs, logs |
PROCESS | mise, build, test, lint, dev-server commands |
CREDENTIALS | Secrets must not be hardcoded in workflow configs |
Preconditions
- Target workflow and affected project area are identifiable.
- Task definitions can be discovered or missing-task state is reported.
Effects and side effects
- May start dev servers, run tests/builds, generate clients, run migrations, or edit workflow configs.
- May consume CPU/time or occupy ports.
Guardrails
1. Always use mise run tasks instead of direct package manager commands 2. Run mise install after pulling changes that might update runtime versions 3. Use parallel tasks (mise run lint, mise run test) for independent operations 4. Run lint/test only on apps with changed files (lint:changed, test:changed) 5. Validate commit messages with commitlint before committing 6. Run pre-commit validation pipeline for staged files only 7. Configure CI to skip unchanged apps for faster builds 8. Check mise tasks --all to discover available tasks before running 9. Verify task output and exit codes for CI/CD integration 10. Document task dependencies in mise.toml comments 11. Use consistent task naming conventions across apps 12. Enable mise in CI/CD pipelines for reproducible builds 13. Pin runtime versions in mise.toml for consistency 14. Test tasks locally before committing CI/CD changes 15. Never use direct package manager commands when mise tasks exist 16. Never modify mise.toml without understanding task dependencies 17. Never skip mise install after toolchain version updates 18. Never run dev servers without checking port availability first 19. Never commit without running validation on affected apps 20. Never ignore task failures - always investigate root cause 21. Never hardcode secrets in mise.toml files 22. Never assume task availability - always verify with mise tasks 23. Never run destructive tasks (clean, reset) without confirmation 24. Never skip reading task definitions before running unfamiliar tasks
Technical Guidelines
Prerequisites
# Install mise
curl https://mise.run | sh
# Activate in shell
echo 'eval "$(~/.local/bin/mise activate)"' >> ~/.zshrc
# Install all runtimes defined in mise.toml
mise install
# Verify installation
mise listProject Structure (Monorepo)
project-root/
├── mise.toml # Root task definitions
├── apps/
│ ├── api/ # Backend application
│ │ └── mise.toml # App-specific tasks
│ ├── web/ # Frontend application
│ │ └── mise.toml
│ └── mobile/ # Mobile application
│ └── mise.toml
├── packages/
│ ├── shared/ # Shared libraries
│ └── config/ # Shared configuration
└── scripts/ # Utility scriptsTask Syntax
Root-level tasks:
mise run lint # Lint all apps (parallel)
mise run test # Test all apps (parallel)
mise run dev # Start all dev servers
mise run build # Production buildsApp-specific tasks:
# Syntax: mise run //{path}:{task}
mise run //apps/api:dev
mise run //apps/api:test
mise run //apps/web:buildCommon Task Patterns
| Task Type | Purpose | Example |
|---|---|---|
dev | Start development server | mise run //apps/api:dev |
build | Production build | mise run //apps/web:build |
test | Run test suite | mise run //apps/api:test |
lint | Run linter | mise run lint |
format | Format code | mise run format |
typecheck | Type checking | mise run typecheck |
migrate | Database migrations | mise run //apps/api:migrate |
Reference Guide
| Topic | Resource File | When to Load |
|---|---|---|
| Validation Pipeline | resources/validation-pipeline.md | Git hooks, CI/CD, change-based testing |
| Database & Infrastructure | resources/database-patterns.md | Migrations, local Docker infra |
| API Generation | resources/api-workflows.md | Generating API clients |
| i18n Patterns | resources/i18n-patterns.md | Internationalization |
| Release Coordination | resources/release-coordination.md | Versioning, changelog, releases |
| Troubleshooting | resources/troubleshooting.md | Debugging issues |
Task Dependencies
Define dependencies in mise.toml:
[tasks.build]
depends = ["lint", "test"]
run = "echo 'Building after lint and test pass'"
[tasks.dev]
depends = ["//apps/api:dev", "//apps/web:dev"]Parallel vs Sequential Execution
Parallel (independent tasks):
# Runs all lint tasks simultaneously
mise run lintSequential (dependent tasks):
# Runs in order: lint → test → build
mise run lint && mise run test && mise run buildMixed approach:
# Start dev servers in background
mise run //apps/api:dev &
mise run //apps/web:dev &
waitEnvironment Variables
Common patterns for monorepo env vars:
# Database
DATABASE_URL=postgresql://user:pass@localhost:5432/db
# Cache
REDIS_URL=redis://localhost:6379/0
# API
API_URL=http://localhost:8000
# Frontend
PUBLIC_API_URL=http://localhost:8000Output Templates
When setting up development environment: 1. Runtime installation verification (mise list) 2. Dependency installation commands per app 3. Environment variable template (.env.example) 4. Development server startup commands 5. Common task quick reference
When running tasks: 1. Command executed with full path 2. Expected output summary 3. Duration and success/failure status 4. Next recommended actions
When troubleshooting: 1. Diagnostic commands (mise config, mise doctor) 2. Common issue solutions 3. Port/process conflict resolution 4. Cleanup commands if needed
Troubleshooting Guide
| Issue | Solution |
|---|---|
| Task not found | Run mise tasks --all to list available tasks |
| Runtime not found | Run mise install to install missing runtime |
| Task hangs | Check for interactive prompts, use --yes if available |
| Port already in use | Find process: lsof -ti:PORT then kill |
| Permission denied | Check file permissions, try with proper user |
| Missing dependencies | Run mise run install or app-specific install |
How to Execute
Follow the core workflow step by step: 1. Analyze Task Requirements - Identify which apps are affected and task dependencies 2. Check mise Configuration - Verify mise.toml structure and available tasks 3. Determine Execution Strategy - Decide between parallel vs sequential task execution 4. Run Prerequisites - Install runtimes, dependencies if needed 5. Execute Tasks - Run mise tasks with proper error handling 6. Verify Results - Check output, logs, and generated artifacts 7. Report Status - Summarize success/failure with actionable next steps
Execution Protocol (CLI Mode)
Vendor-specific execution protocols are injected automatically by oma agent:spawn. Source files live under ../_shared/runtime/execution-protocols/{vendor}.md.
References
- Clarification:
../_shared/core/clarification-protocol.md - Difficulty assessment:
../_shared/core/difficulty-guide.md
Knowledge Reference
mise, task runner, monorepo, dev server, lint, format, test, typecheck, build, deployment, ci/cd, parallel execution, workflow, automation, tooling
API Generation Workflows
Generate API clients from OpenAPI schemas.
OpenAPI to Client Pipeline
# 1. Generate OpenAPI schema from backend
mise run //apps/api:gen:openapi
# 2. Generate TypeScript client for web
mise run //apps/web:gen:api
# 3. Generate Dart client for mobile
mise run //apps/mobile:gen:apiBackend Tasks
# apps/api/mise.toml
[tasks.gen:openapi]
description = "Generate OpenAPI schema"
run = "uv run python -c 'from src.main import app; import json; print(json.dumps(app.openapi()))' > openapi.json"Web Tasks
# apps/web/mise.toml
[tasks.gen:api]
description = "Generate API client from OpenAPI"
depends = ["//apps/api:gen:openapi"]
run = "bunx orval"Mobile Tasks
# apps/mobile/mise.toml
[tasks.gen:api]
description = "Generate API client from OpenAPI"
depends = ["//apps/api:gen:openapi"]
run = "flutter pub run swagger_parser"Root-Level API Generation
# Root mise.toml
[tasks.gen:api]
description = "Generate API clients for all apps"
depends = [
"//apps/api:gen:openapi",
"//apps/web:gen:api",
"//apps/mobile:gen:api"
]Database & Local Infrastructure
Database migration workflows and local development infrastructure.
Migration Tasks
# apps/api/mise.toml
[tasks.migrate]
description = "Run Alembic migrations"
run = "uv run alembic upgrade head"
[tasks.migrate:create]
description = "Create new migration"
run = "uv run alembic revision --autogenerate -m '{{arg(name)}}'"
[tasks.migrate:check]
description = "Check migration status"
run = "uv run alembic current"
[tasks.migrate:history]
description = "Show migration history"
run = "uv run alembic history --verbose"
[tasks.migrate:rollback]
description = "Rollback one migration"
run = "uv run alembic downgrade -1"
[tasks.migrate:reset]
description = "Reset database (all down then up)"
run = "uv run alembic downgrade base && uv run alembic upgrade head"Creating Migrations
# Create new migration
mise run //apps/api:migrate:create "add users table"
# Review generated migration
# Edit: apps/api/alembic/versions/xxx_add_users_table.py
# Apply migration
mise run //apps/api:migrate
# Check current version
mise run //apps/api:migrate:check
# View history
mise run //apps/api:migrate:history
# Rollback (if needed)
mise run //apps/api:migrate:rollbackRoot-Level Database Tasks
# Root mise.toml
[tasks.db:migrate]
description = "Run all database migrations"
depends = ["//apps/api:migrate"]
[tasks.db:reset]
description = "Reset all databases"
depends = ["//apps/api:migrate:reset"]Local Infrastructure (Docker)
# apps/api/mise.toml
[tasks.infra:up]
description = "Start local infrastructure (PostgreSQL, Redis, etc.)"
run = "docker compose -f docker-compose.infra.yml up -d"
[tasks.infra:down]
description = "Stop local infrastructure"
run = "docker compose -f docker-compose.infra.yml down"
[tasks.infra:logs]
description = "View infrastructure logs"
run = "docker compose -f docker-compose.infra.yml logs -f"
[tasks.infra:reset]
description = "Reset infrastructure (remove volumes)"
run = "docker compose -f docker-compose.infra.yml down -v"Root-Level Infrastructure Tasks
# Root mise.toml
[tasks.infra:up]
description = "Start all local infrastructure"
depends = ["//apps/api:infra:up"]
[tasks.infra:down]
description = "Stop all local infrastructure"
depends = ["//apps/api:infra:down"]i18n Build Patterns
Internationalization workflows for monorepos.
Shared i18n Package
# packages/i18n/mise.toml
[tasks.build]
description = "Build i18n files for all platforms"
depends = ["build:web", "build:mobile"]
[tasks.build:web]
description = "Build for web (next-intl JSON)"
run = "bun scripts/build-web.js"
[tasks.build:mobile]
description = "Build for mobile (Flutter ARB)"
run = "bun scripts/build-mobile.js"
[tasks.watch]
description = "Watch for changes and rebuild"
run = "bun scripts/watch.js"Usage in Apps
# Build i18n for all apps
mise run //packages/i18n:build
# Watch for changes during development
mise run //packages/i18n:watchWeb Integration
# apps/web/mise.toml
[tasks.dev]
description = "Start Next.js dev server"
depends = ["//packages/i18n:build"]
run = "bun dev"
[tasks.build]
description = "Production build"
depends = ["//packages/i18n:build"]
run = "bun run build"Mobile Integration
# apps/mobile/mise.toml
[tasks.gen:l10n]
description = "Generate Flutter localizations"
run = "flutter gen-l10n"
[tasks.dev]
description = "Run Flutter on device"
depends = ["gen:l10n"]
run = "flutter run"Release Coordination
Release Please workflow for automated versioning and releases.
Overview
This project uses Google's Release Please for automated versioning and releases based on conventional commits.
How It Works
1. Release PR Creation: When conventional commits are merged to main, Release Please creates a release PR 2. CHANGELOG Generation: Automatically generates CHANGELOG.md from commits 3. Version Bumping: Updates version in package.json and other files 4. Release on Merge: When the release PR is merged, a GitHub release is created
GitHub Actions Workflow
# .github/workflows/release-please.yml
name: Release Please
on:
push:
branches: [main]
permissions:
contents: write
pull-requests: write
jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
release-type: nodeMise Tasks for Release Management
# Root mise.toml
[tools]
node = "24"
bun = "latest"
[tasks.release:check]
description = "Check release-please status"
run = '''
#!/usr/bin/env bash
echo "Checking release status..."
echo ""
echo "Open release PRs:"
gh pr list --label "autorelease: pending" --state open
echo ""
echo "Latest releases:"
gh release list --limit 5
'''
[tasks.release:manifest]
description = "Show current release manifest"
run = "cat .release-please-manifest.json"
[tasks.release:changelog]
description = "Preview changelog (local dry-run)"
run = '''
#!/usr/bin/env bash
echo "Recent conventional commits:"
git log --pretty=format:"%s" $(git describe --tags --abbrev=0)..HEAD | grep -E "^(feat|fix|docs|style|refactor|test|chore|ci)(\(.+\))?:"
'''Conventional Commit Format
Release Please recognizes these commit types:
| Type | Version Bump | Description |
|---|---|---|
feat: | minor | New feature |
fix: | patch | Bug fix |
docs: | patch | Documentation |
style: | patch | Code style (no logic) |
refactor: | patch | Code refactoring |
test: | patch | Tests |
chore: | patch | Maintenance |
feat!: | major | Breaking change |
fix!: | major | Breaking bug fix |
Release Configuration
// .release-please-config.json
{
"packages": {
".": {
"release-type": "node",
"draft": false,
"prerelease": false
}
}
}// .release-please-manifest.json
{
".": "1.0.0"
}Release Flow
1. Develop Features
# Make changes with conventional commits
git commit -m "feat(cli): add infrastructure skills category"
git commit -m "fix(cli): correct skill installation path"
git commit -m "docs: update installation guide"2. Merge to Main
git push origin main3. Release Please Creates PR
Automatically creates a PR like:
- Title:
chore(main): release 1.1.0 - Includes updated CHANGELOG.md
- Includes version bump in package.json
4. Review and Merge
# Check the release PR
gh pr list --label "autorelease: pending"
# Review changes
git fetch origin
git diff origin/main...release-please--branches--main
# Merge via GitHub (creates release)5. Verify Release
[tasks.release:verify]
description = "Verify latest release"
run = '''
#!/usr/bin/env bash
echo "Latest release:"
gh release view --json tagName,name,createdAt
echo ""
echo "Assets:"
gh release view --json assets
'''Manual Release Trigger
If needed, manually trigger release-please:
[tasks.release:trigger]
description = "Manually trigger release-please (CI will handle)"
run = '''
#!/usr/bin/env bash
echo "Triggering release-please..."
echo "Push to main will trigger the workflow automatically"
echo ""
echo "Current status:"
mise run release:check
'''Post-Release Tasks
[tasks.release:cleanup]
description = "Cleanup after release"
run = '''
#!/usr/bin/env bash
echo "Post-release cleanup..."
# Pull latest changes with tags
git pull origin main --tags
# Verify local state
echo ""
echo "Local version:"
cat package.json | grep '"version"' | cut -d'"' -f4
echo ""
echo "Latest tag:"
git describe --tags --abbrev=0
echo ""
echo "Release cleanup complete"
'''Troubleshooting
[tasks.release:debug]
description = "Debug release issues"
run = '''
#!/usr/bin/env bash
echo "Release Debugging"
echo ""
echo "1. Conventional commits since last tag:"
git log --pretty=format:"%s" $(git describe --tags --abbrev=0 2>/dev/null || echo "HEAD~10")..HEAD | grep -E "^(feat|fix|docs|style|refactor|test|chore|ci)(\(.+\))?:" || echo " No conventional commits found"
echo ""
echo "2. Release Please config files:"
ls -la .release-please*.json 2>/dev/null || echo " Config files not found"
echo ""
echo "3. GitHub Actions status:"
gh run list --workflow=release-please.yml --limit 5 2>/dev/null || echo " No runs found"
echo ""
echo "4. Open release PRs:"
gh pr list --label "autorelease: pending" 2>/dev/null || echo " No release PRs"
'''Setup Requirements
1. GitHub Actions workflow (.github/workflows/release-please.yml) 2. Release Please config (.release-please-config.json) 3. Release Please manifest (.release-please-manifest.json) 4. Conventional commits (already configured via commitlint) 5. GitHub CLI (gh) installed for the release tasks — brew install gh or mise use gh (it is a Go binary, not an npm package; bunx gh resolves an unrelated deprecated package)
Benefits
- Automated versioning based on commits
- Auto-generated CHANGELOG.md
- GitHub releases with notes
- No manual version bumping
- Integrated with GitHub PR workflow
Troubleshooting
Common issues and solutions.
Task Not Found
# List all available tasks
mise tasks --all
# Show task details
mise tasks <task-name>Runtime Not Found
# Install all runtimes
mise install
# Install specific runtime
mise install node@24
# List installed runtimes
mise listPort Already in Use
# Check ports
lsof -ti:8000 # API port
lsof -ti:3000 # Web port
lsof -ti:8080 # Mobile port
# Kill processes
lsof -ti:8000 | xargs kill -9Task Hangs
# Run with verbose output
mise run dev --verbose
# Debug mode
MISE_DEBUG=1 mise run dev
# Check for interactive prompts (use --yes if available)
mise run install --yesClean State
# Stop all dev servers
pkill -f "mise run"
# Clean mise cache
mise cache clear
# Reinstall everything
mise uninstall --all
mise installDebug Configuration
# Show mise config
mise config
# Show environment
mise env
# Doctor - check for issues
mise doctorValidation Pipeline
Complete validation pipeline with local git hooks and CI/CD integration.
Commitlint Configuration
// commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
['feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore', 'ci', 'infra']
],
'scope-enum': [
2,
'always',
['web', 'api', 'mobile', 'worker', 'shared', 'infra', 'deps']
]
}
};Local Validation (Git Hooks)
Mise Hooks Setup
# mise.toml
[hooks]
postinstall = '''
mkdir -p .git/hooks
# commit-msg hook
cat > .git/hooks/commit-msg <<'EOF'
#!/bin/sh
exec mise run git:commit-msg -- "$1"
EOF
chmod +x .git/hooks/commit-msg
# pre-commit hook
cat > .git/hooks/pre-commit <<'EOF'
#!/bin/sh
exec mise run git:pre-commit
EOF
chmod +x .git/hooks/pre-commit
# pre-push hook
cat > .git/hooks/pre-push <<'EOF'
#!/bin/sh
exec mise run git:pre-push
EOF
chmod +x .git/hooks/pre-push
'''Git Hook Tasks
[tasks."git:commit-msg"]
description = "Validate commit message using commitlint"
run = "bunx @commitlint/cli@20 --edit $1"
[tasks."git:pre-commit"]
description = "Run lint on changed files"
run = '''
#!/usr/bin/env bash
changed=$(git diff --cached --name-only)
if echo "$changed" | grep -q "^apps/api/"; then
echo "[pre-commit] apps/api detected, running lint..."
mise //apps/api:lint || exit 1
fi
if echo "$changed" | grep -q "^apps/web/"; then
echo "[pre-commit] apps/web detected, running lint..."
mise //apps/web:lint || exit 1
fi
if echo "$changed" | grep -q "^apps/mobile/"; then
echo "[pre-commit] apps/mobile detected, running lint..."
mise //apps/mobile:lint || exit 1
fi
'''
[tasks."git:pre-push"]
description = "Validate branch name and run tests"
run = '''
#!/usr/bin/env bash
# Validate branch name
bunx @gracefullight/validate-branch || exit 1
# Get changed files
changed=$(git diff --name-only origin/main...HEAD 2>/dev/null || git diff --name-only HEAD~1)
if echo "$changed" | grep -q "^apps/api/"; then
echo "[pre-push] apps/api detected, running test..."
mise //apps/api:test || exit 1
fi
if echo "$changed" | grep -q "^apps/web/"; then
echo "[pre-push] apps/web detected, running test..."
mise //apps/web:test || exit 1
fi
if echo "$changed" | grep -q "^apps/mobile/"; then
echo "[pre-push] apps/mobile detected, running test..."
mise //apps/mobile:test || exit 1
fi
'''CI/CD Validation (GitHub Actions)
Full Workflow
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: jdx/mise-action@v2
- run: mise run install
- run: mise run lint
- run: mise run typecheck
- run: mise run testChange-Based Workflow
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
detect-changes:
runs-on: ubuntu-latest
outputs:
web: ${{ steps.changes.outputs.web }}
api: ${{ steps.changes.outputs.api }}
mobile: ${{ steps.changes.outputs.mobile }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: changes
with:
filters: |
web:
- 'apps/web/**'
api:
- 'apps/api/**'
mobile:
- 'apps/mobile/**'
lint-web:
needs: detect-changes
if: ${{ needs.detect-changes.outputs.web == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: jdx/mise-action@v2
- run: mise run //apps/web:lint
lint-api:
needs: detect-changes
if: ${{ needs.detect-changes.outputs.api == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: jdx/mise-action@v2
- run: mise run //apps/api:lint
test-web:
needs: [detect-changes, lint-web]
if: ${{ needs.detect-changes.outputs.web == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: jdx/mise-action@v2
- run: mise run //apps/web:testReusable Tasks
# Root mise.toml
[tasks.lint:changed]
description = "Lint only changed apps"
run = '''
#!/usr/bin/env bash
changed_files=$(git diff --name-only HEAD~1)
if echo "$changed_files" | grep -q "^apps/web/"; then
echo "→ Linting web..."
mise run //apps/web:lint || exit 1
fi
if echo "$changed_files" | grep -q "^apps/api/"; then
echo "→ Linting api..."
mise run //apps/api:lint || exit 1
fi
if echo "$changed_files" | grep -q "^apps/mobile/"; then
echo "→ Linting mobile..."
mise run //apps/mobile:lint || exit 1
fi
'''
[tasks.test:changed]
description = "Test only changed apps"
run = '''
#!/usr/bin/env bash
changed_files=$(git diff --name-only HEAD~1)
if echo "$changed_files" | grep -q "^apps/web/"; then
echo "→ Testing web..."
mise run //apps/web:test || exit 1
fi
if echo "$changed_files" | grep -q "^apps/api/"; then
echo "→ Testing api..."
mise run //apps/api:test || exit 1
fi
if echo "$changed_files" | grep -q "^apps/mobile/"; then
echo "→ Testing mobile..."
mise run //apps/mobile:test || exit 1
fi
'''
[tasks.validate:changed]
description = "Validate only changed apps"
depends = ["lint:changed", "test:changed"]Complete Root mise.toml Example
[tools]
node = "24"
python = "3.12"
flutter = "3"
bun = "latest"
[hooks]
postinstall = '''
mkdir -p .git/hooks
cat > .git/hooks/commit-msg <<'EOF'
#!/bin/sh
exec mise run git:commit-msg -- "$1"
EOF
chmod +x .git/hooks/commit-msg
cat > .git/hooks/pre-commit <<'EOF'
#!/bin/sh
exec mise run git:pre-commit
EOF
chmod +x .git/hooks/pre-commit
cat > .git/hooks/pre-push <<'EOF'
#!/bin/sh
exec mise run git:pre-push
EOF
chmod +x .git/hooks/pre-push
'''
[tasks.dev]
description = "Start all development services"
depends = ["//apps/api:dev", "//apps/web:dev"]
[tasks.lint]
description = "Lint all apps"
depends = ["//apps/api:lint", "//apps/web:lint", "//apps/mobile:lint"]
[tasks.test]
description = "Test all apps"
depends = ["//apps/api:test", "//apps/web:test", "//apps/mobile:test"]
[tasks."git:commit-msg"]
description = "Validate commit message"
run = "bunx @commitlint/cli@20 --edit $1"
[tasks."git:pre-commit"]
description = "Run lint on changed files"
run = '''
#!/usr/bin/env bash
changed=$(git diff --cached --name-only)
if echo "$changed" | grep -q "^apps/web/"; then
mise //apps/web:lint || exit 1
fi
if echo "$changed" | grep -q "^apps/api/"; then
mise //apps/api:lint || exit 1
fi
'''
[tasks."git:pre-push"]
description = "Run tests + branch validation"
run = '''
#!/usr/bin/env bash
bunx @gracefullight/validate-branch || exit 1
changed=$(git diff --name-only origin/main...HEAD 2>/dev/null || git diff --name-only HEAD~1)
if echo "$changed" | grep -q "^apps/web/"; then
mise //apps/web:test || exit 1
fi
if echo "$changed" | grep -q "^apps/api/"; then
mise //apps/api:test || exit 1
fi
'''
[tasks.lint:changed]
description = "Lint only changed apps"
run = '''
#!/usr/bin/env bash
changed_files=$(git diff --name-only HEAD~1)
if echo "$changed_files" | grep -q "^apps/web/"; then
mise run //apps/web:lint || exit 1
fi
if echo "$changed_files" | grep -q "^apps/api/"; then
mise run //apps/api:lint || exit 1
fi
'''
[tasks.test:changed]
description = "Test only changed apps"
run = '''
#!/usr/bin/env bash
changed_files=$(git diff --name-only HEAD~1)
if echo "$changed_files" | grep -q "^apps/web/"; then
mise run //apps/web:test || exit 1
fi
if echo "$changed_files" | grep -q "^apps/api/"; then
mise run //apps/api:test || exit 1
fi
'''