Justfile Conventions#
Justfile conventions in the opnDossier project establish coding standards for task automation recipes that ensure consistency, maintainability, and predictable behavior across development and CI/CD environments. The justfile serves as the central command runner for the project, containing 50+ carefully designed tasks organized into 12 logical groups that orchestrate development workflows, quality gates, testing, security scanning, license compliance, and release management.
These conventions reflect the project's commitment to local/CI parity, where developers can run the exact same checks locally as those executed in continuous integration pipelines. The conventions prioritize mise-managed tools over ad-hoc shell scripting, ensuring consistent tool versions and eliminating "works on my machine" problems. This approach was formalized through PR #172 and PR #173, which migrated the project from multiple disparate setup actions to unified mise-based tool management.
The justfile implements brand principles documented in AGENTS.md emphasizing polish over scale, sane defaults with clean outputs, and operator trust with full control. These principles directly influence how tasks are designed, how they handle errors, and how they communicate with users through terminal output.
Core Conventions#
Mise-Managed Tools Over Shell Scripting#
The project enforces a strict preference for mise-managed tools over direct shell scripting or ad-hoc tool installation. All external tool invocations use the mise_exec wrapper variable defined as mise exec --, which ensures tools run through the standardized mise environment with versions pinned in mise.toml.
Pattern Examples:
- Go commands:
{{ mise_exec }} go mod tidy - Linting:
{{ mise_exec }} golangci-lint run --fix ./... - Security:
{{ mise_exec }} gosec ./... - SBOM:
{{ mise_exec }} cyclonedx-gomod bin -output sbom-binary.cyclonedx.json - License notices:
{{ mise_exec }} go-licenses report ./...
This approach was formalized in PR #172, which migrated from multiple setup actions (actions/setup-go, actions/setup-python) to unified jdx/mise-action@v2, and PR #173, which wrapped commands like cyclonedx-gomod with {{ mise_exec }} prefix.
Benefits:
- Version-pinned tool access via
mise.toml - Eliminates dependency on system PATH
- Consistent behavior across development machines and CI
- Single source of truth for tool versions
Shell Scripting Exceptions:
Bash script blocks are acceptable for conditional logic and tool existence checks:
#!/usr/bin/env bash
if ! command -v git-cliff >/dev/null 2>&1; then
echo "Error: git-cliff not found. Run 'just install' to install it."
exit 1
fi
Output Message Patterns#
The justfile uses @echo statements (with @ to suppress command echoing) strategically to provide user feedback. However, the conventions emphasize avoiding redundant output when underlying tools already provide sufficient feedback.
Informational Messages:
Used when tasks perform silent operations or require progress indicators:
Success Confirmations:
The justfile includes explicit success confirmation messages for compound operations:
@echo "✅ All CI checks passed"@echo "✅ Documentation generated"@echo "✅ All security checks complete"
These messages appear after orchestration tasks that chain multiple dependent operations, providing clear feedback when a complex workflow completes successfully. The checkmark emoji (✅) serves as a visual indicator in terminal output.
Error Messages:
Clear, actionable error messages with next steps:
echo "No baseline found. Run 'just bench-save' first."echo "Error: git-cliff not found. Run 'just install' to install it."echo "Error: act not found. Install: brew install act"
Error messages follow AGENTS.md Section 5.2 error handling principles:
- Provide context about what failed
- Include actionable remediation steps
- Avoid exposing sensitive information per security standards
Terminal Output Compatibility#
While justfile recipes themselves don't directly implement styling checks, they should respect the broader project standards documented in AGENTS.md Section 5.11 Terminal Output Styling:
- Check
TERM != "dumb"andNO_COLOR == ""before applying styles - Provide plain text fallback for CI/automation environments
- Ensure output works in TERM=dumb environments
Task Organization and Structure#
Logical Grouping#
The justfile organizes tasks using [group('name')] attributes into 12 categories:
- help — Documentation and discovery
- setup — Installation and environment setup
- dev — Development workflow
- quality — Code formatting and linting
- test — Testing and benchmarking
- build — Binary compilation
- release — Release management
- docs — Documentation generation
- security — Security scanning and SBOM
- licensing — License compliance and attribution
- ci — CI orchestration tasks
- act — GitHub Actions local testing
Task Dependencies#
Tasks use just's built-in dependency system to orchestrate workflows:
CI Master Check:
ci-check: check format-check lint test test-integration
This task chains 5 quality gates that must all pass before code is CI-ready.
Full Validation:
ci-full: ci-check security-all release-check docs-test
Complete pre-release validation
Security All:
security-all: sbom scan
Combines SBOM generation and security scanning
License Notices:
notices:
{{ mise_exec }} go-licenses report ./... \
--ignore github.com/EvilBit-Labs/opnDossier \
--template packaging/notices.tpl > THIRD_PARTY_NOTICES 2>/dev/null
Generates third-party license attribution file using go-licenses tool and custom template, automatically run before releases via GoReleaser.
Private Tasks and Aliases#
Private tasks prefixed with [private] are hidden from just --list but used internally:
[private] default— Shows unsorted list when running barejust[private] _update-go— Go dependency updates[private] _require-git-cliff— Validates git-cliff is installed
Convenient single-letter aliases:
alias i := installalias f := formatalias t := testalias b := build
Task Documentation#
Every public task includes a descriptive comment that appears in just --list:
# Format code and apply fixes
format:
@{{ mise_exec }} golangci-lint run --fix ./...
Configuration and Variables#
Global Variables#
The justfile defines configuration variables at the top:
mise_exec := "mise exec --"
project_dir := justfile_directory()
binary_name := "opndossier"
Platform Detection#
Cross-platform compatibility using conditional expressions:
_cmd_exists := if os_family() == "windows" { "where" } else { "command -v" }
_null := if os_family() == "windows" { "nul" } else { "/dev/null" }
Dynamic Binary Naming#
Binary name includes platform-specific extensions:
{{ binary_name }}{{ if os_family() == "windows" { ".exe" } else { "" } }}
Used in build, build-release, and clean tasks.
Security and Build Hardening#
Release Build Flags#
The build-release task uses hardened compilation flags:
@CGO_ENABLED=0 {{ mise_exec }} go build -trimpath -ldflags="-s -w" -o {{ binary_name }}
CGO_ENABLED=0— Static linking, no C dependencies-trimpath— Remove filesystem paths for reproducible builds-ldflags="-s -w"— Strip debug info and symbol tables
User Confirmation#
Destructive operations require explicit confirmation:
[confirm("This will remove build artifacts. Continue?")]
clean:
...
Local/CI Parity#
The justfile implements local/CI parity, allowing developers to run the exact same checks locally as those executed in CI:
just ci-check— Run full CI checks (pre-commit, format, lint, test)just ci-full— Complete pre-release validation including security
AGENTS.md emphasizes: "Tasks are NOT complete until just ci-check passes"
Usage Examples#
Development Workflow#
# Initial setup
just install
# Development iteration
just format # Format code
just lint # Run linters
just test # Run tests
# Pre-commit check
just ci-check # Run all CI validations locally
Release Workflow#
# Pre-release validation
just ci-full # All checks including security
just release-snapshot # Test build without publishing
just changelog-unreleased # Review changes
just notices # Generate license attribution file
# Create release
just release # Build, sign, and publish
Benchmarking Workflow#
# Save baseline
just bench-save
# Make changes, then compare
just bench-compare
Relevant Code Files#
| File | Purpose | Lines | Link |
|---|---|---|---|
justfile | Central task runner with 50+ recipes | 456 | View |
mise.toml | Tool version definitions | — | View |
AGENTS.md | Development standards and guidelines | — | View |
.golangci.yml | Linter configuration (70+ linters) | 247 | View |
.pre-commit-config.yaml | Pre-commit hooks configuration | — | View |
.goreleaser.yaml | Release automation with SBOM/signing | 342 | View |
packaging/notices.tpl | Template for third-party license notices | 12 | View |
Related Topics#
- mise Tool Management — Version management system for development tools
- just Command Runner — Task runner used by the project
- AGENTS.md Development Standards — Comprehensive coding standards and conventions
- Pre-commit Hooks — Automated code quality checks integrated with justfile tasks
- GitHub Actions — CI/CD workflows that mirror justfile task structure