Mise Integration
Note: This is a user guide (informative). For normative requirements, see the Configuration Specification.
Structyl uses mise as its primary build platform. All command execution is delegated to mise tasks, making mise.toml the central configuration for toolchain management and task execution.
Overview
When you run structyl build go, structyl:
- Ensures mise is installed
- Generates/updates
mise.tomlfrom your config.json - Executes
mise run build:go
This approach provides:
- Consistent toolchain versions across all environments
- Native mise task execution
- Full compatibility with mise ecosystem tools
Installation
Mise must be installed to use structyl commands. If mise isn't found, structyl offers to install it:
# Manual installation
curl https://mise.run | sh
# macOS via Homebrew
brew install miseAfter installation, activate mise in your shell:
# Add to ~/.bashrc or ~/.zshrc
eval "$(mise activate bash)" # or zsh/fishConfiguration
Basic Setup
Mise integration is enabled by default. The mise.toml file is autogenerated and gitignored.
{
"project": {
"name": "my-project"
},
"targets": {
"go": {
"type": "language",
"title": "Go",
"toolchain": "go"
}
}
}Mise-Specific Options
Configure mise behavior in your config.json:
{
"mise": {
"enabled": true,
"auto_generate": true,
"extra_tools": {
"jq": "latest",
"yq": "4"
}
}
}| Field | Default | Description |
|---|---|---|
enabled | true | Enable mise integration |
auto_generate | true | Regenerate mise.toml before each run |
extra_tools | {} | Additional mise tools to install |
Toolchain Versions
Override default toolchain versions per-target:
{
"targets": {
"go": {
"type": "language",
"title": "Go",
"toolchain": "go",
"toolchain_version": "1.23"
}
}
}Or define version in a custom toolchain:
{
"toolchains": {
"go-legacy": {
"extends": "go",
"version": "1.21"
}
}
}Version priority:
- Target's
toolchain_version - Custom toolchain's
version - Built-in default for the toolchain
CLI Commands
Running Commands
All standard commands delegate to mise:
structyl build go # → mise run build:go
structyl test # → mise run test
structyl ci rs # → mise run ci:rsMise Sync
Manually regenerate mise.toml:
structyl mise sync # Regenerate mise.toml (always regenerates)Generation Commands
Generate Docker and CI configurations:
structyl dockerfile # Generate Dockerfiles with mise
structyl github # Generate GitHub Actions workflowGenerated mise.toml
Given this config.json:
{
"targets": {
"go": {
"type": "language",
"title": "Go",
"toolchain": "go",
"toolchain_version": "1.23",
"directory": "go"
},
"rs": {
"type": "language",
"title": "Rust",
"toolchain": "cargo",
"directory": "rs"
}
}
}Structyl generates:
[tools]
go = "1.23"
golangci-lint = "latest"
rust = "stable"
[tasks."clean:go"]
description = "Clean for go target"
dir = "go"
run = "go clean"
[tasks."restore:go"]
description = "Restore for go target"
dir = "go"
run = "go mod download"
[tasks."build:go"]
description = "Build for go target"
dir = "go"
run = "go build ./..."
[tasks."test:go"]
description = "Test for go target"
dir = "go"
run = "go test ./..."
[tasks."lint:go"]
description = "Lint for go target"
dir = "go"
run = "golangci-lint run"
[tasks."vet:go"]
description = "Vet for go target"
dir = "go"
run = "go vet ./..."
[tasks."check:go"]
description = "Check for go target"
depends = ["lint:go", "vet:go"]
[tasks."ci:go"]
description = "Run CI for go target"
depends = ["clean:go", "restore:go", "check:go", "build:go", "test:go"]
[tasks."clean:rs"]
description = "Clean for rs target"
dir = "rs"
run = "cargo clean"
[tasks."build:rs"]
description = "Build for rs target"
dir = "rs"
run = "cargo build"
[tasks."test:rs"]
description = "Test for rs target"
dir = "rs"
run = "cargo test"
[tasks."ci:rs"]
description = "Run CI for rs target"
depends = ["clean:rs", "build:rs", "test:rs"]
[tasks."build"]
description = "Build all targets"
depends = ["build:go", "build:rs"]
[tasks."test"]
description = "Test all targets"
depends = ["test:go", "test:rs"]
[tasks."ci"]
description = "Run CI for all targets"
depends = ["ci:go", "ci:rs"]Task Naming Convention
Tasks follow the pattern <command>:<target>:
| Command | Description |
|---|---|
build:go | Build Go target |
test:rs | Test Rust target |
lint:py | Lint Python target |
ci:ts | Full CI for TypeScript target |
Aggregate tasks run across all targets:
build- Build all targetstest- Test all targetsci- Full CI for all targets
Toolchain Mapping
Structyl automatically maps toolchains to mise tools:
| Toolchain | Mise Tools |
|---|---|
cargo | rust = "stable" |
dotnet | dotnet = "10.0" |
go | go = "1.24", golangci-lint = "latest" |
npm | node = "22" |
pnpm | node = "22", pnpm = "10" |
yarn | node = "22" |
bun | bun = "latest" |
python | python = "3.13" |
uv | python = "3.13", uv = "0.6", ruff = "latest" |
poetry | python = "3.13" |
gradle | java = "temurin-23" |
maven | java = "temurin-23" |
deno | deno = "latest" |
swift | swift = "latest" |
Docker Integration
Generated Dockerfiles install mise and run tasks:
FROM ubuntu:22.04
# Install mise
RUN curl -fsSL https://mise.run | sh
ENV PATH="/root/.local/bin:$PATH"
# Copy mise configuration
WORKDIR /workspace
COPY mise.toml mise.toml
RUN mise trust && mise install
# Set working directory to target
WORKDIR /workspace/goGitHub Actions
Generated workflow uses jdx/mise-action:
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
go:
name: Go
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: jdx/mise-action@v2
- run: mise run ci:go
rs:
name: Rust
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: jdx/mise-action@v2
- run: mise run ci:rsDisabling Mise
To use direct command execution instead of mise:
{
"mise": {
"enabled": false
}
}Or use the --docker flag, which falls back to direct execution in containers.
Best Practices
- Keep mise.toml gitignored: It's autogenerated from config.json
- Pin versions for production: Use specific versions instead of
latest - Use mise directly for development: Run
mise run build:golocally - Regenerate after config changes: Run
structyl mise syncor let auto-generate handle it