agentleFS
sagy101sagy101/DotSkills/sbt-build-test/SKILL.md

sbt-build-test

Skill4 starsChanged 8 months agoMITView on GitHub

Use for ANY SBT operation: compile, test, coverage, publishLocal, dependency discovery, cross-repo builds. Handles multi-repo dependency chains automatically — detects upstream repos, publishes them in correct order, clears caches, and rebuilds. Uses an isolated build cache so normal sbt is never affected.

The file

We split this skill into the rules it gives an agent

7 rules. About 0 are common, 2 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use this skill when you need to:

    line 16
  2. Distinctive:

    Fix stale state: after upstream changes

    line 21
  3. Very specific:

    Create <workspace>/.sbt-workspace.conf only when you need overrides:

    line 33
  4. Very specific:

    Use the exact scoped project ID reported by sbt_status.sh for subproject names.

    line 99
  5. Very specific:

    rootPaths auto-detection: When --sbt-env dev is requested but the project has rootPaths/remoteCache settings AND external ProjectRef …

    line 101
  6. Very specific:

    Use sbt_status.sh before guessing dependency order: Do not guess publish order.

    line 235
  7. Very specific:

    All SBT caches (Ivy, Coursier, SBT boot, SBT global) are isolated inside SBT_BUILD_CACHE_ROOT (default: ~/.sbt-build-cache).

    line 241

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

SBT Multi-Repo Build & Test

Four commands for all SBT operations: build, status, refresh, reset.

When to use this skill

Use this skill when you need to:

  • Compile or test any SBT project (single or multi-project)
  • Collect scoped coverage while bypassing stale remote-cache pulls
  • Publish local artifacts for downstream validation
  • Understand dependencies between workspace repos
  • Fix stale state after upstream changes
  • Inspect test results from JUnit XML reports

Prerequisites

  1. SBT and the required JDK installed (default: Java 17).
  2. SBT repos under one workspace root, or define overrides in .sbt-workspace.conf.
  3. python3 available for test report parsing and workspace graph helpers.
  4. ~/.ivy2/.credentials present if the workspace resolves private artifacts.

Configuration

Create <workspace>/.sbt-workspace.conf only when you need overrides:

.java_version=17
.group_id=com.acme
shared-models=/absolute/path/to/shared-models

See references/CONFIG.md for full schema.

Commands

sbt_build.sh — Compile, test, publishLocal

The single command for all build operations. Accepts one project, several, or --all for the entire workspace. Automatically handles preflight, upstream dep publishing, log capture, and JUnit XML test report parsing.

bash <skill_dir>/scripts/sbt_build.sh <project-dir>... [options] -- <sbt-commands>
bash <skill_dir>/scripts/sbt_build.sh --all [options] -- <sbt-commands>
OptionDescription
--allBuild all workspace projects in dependency order
--workspace-dir <dir>Override workspace directory
--artifact-version <ver>Set ARTIFACT_VERSION for publishLocal
--sbt-env <value>Pass -Dsbt_env=<value> to SBT
--tail <lines>Lines of log tail to show (default: 60)
--auto-publish-depsAuto-publishLocal missing AND stale workspace deps before building
--continue-on-errorKeep going when a project fails (useful with --all)
--freshForce fresh SBT process (no server reuse) — use when SBT returns stale results
--coverageEnable scoverage for the requested command, disable remote-cache pulls for the scoped project, and emit coverageReport
--no-remote-cacheDisable remote-cache pulls for this run and clear local target/scala-* directories first
--skip-preflightSkip Java/cache pre-check (for repeated calls)

Examples:

# Compile one project
bash <skill_dir>/scripts/sbt_build.sh /path/to/service -- compile

# Run all tests (auto-parses JUnit XML reports)
bash <skill_dir>/scripts/sbt_build.sh /path/to/service -- test

# Test a specific subproject
bash <skill_dir>/scripts/sbt_build.sh /path/to/service -- "core / test"

# Collect coverage for a specific subproject test
bash <skill_dir>/scripts/sbt_build.sh /path/to/service --coverage -- "aws / testOnly com.example.AwsUserPaginationTest"

# Compile with auto-publish of missing upstream deps
bash <skill_dir>/scripts/sbt_build.sh /path/to/service --auto-publish-deps -- compile

# Compile several projects
bash <skill_dir>/scripts/sbt_build.sh /path/to/svc-a /path/to/svc-b -- compile

# Compile all workspace projects in dependency order
bash <skill_dir>/scripts/sbt_build.sh --all -- compile

# Compile + test everything with auto-publish
bash <skill_dir>/scripts/sbt_build.sh --all --auto-publish-deps -- test

# Publish locally at a specific version
bash <skill_dir>/scripts/sbt_build.sh /path/to/library --artifact-version 0.532.0 -- publishLocal

Use the exact scoped project ID reported by sbt_status.sh for subproject names. In multi-project builds the ID may differ from the published artifact name (e.g. myModule vs my-module).

rootPaths auto-detection: When --sbt-env dev is requested but the project has rootPaths/remoteCache settings AND external ProjectRef entries, the skill auto-falls back to non-dev mode. No manual intervention needed.

Coverage mode: --coverage keeps the user command as a normal SBT argument, but wraps it with setup/teardown commands in the same session: it disables maybePullRemoteCache, clears target/scala-*, scopes clean/coverageReport when a subproject is specified, and forces Test / fork := false so scoverage measurements are written in-process.

sbt_status.sh — Discover dependencies and workspace state

Single command for all discovery and diagnostics.

bash <skill_dir>/scripts/sbt_status.sh <project-dir> [options]
OptionDescription
--workspaceFull workspace preflight + dependency graph
--plan-change <repo>Plan impact of a cross-repo change
--verify <artifact>Verify artifact resolution source
--workspace-dir <dir>Override workspace directory
--jsonJSON output (workspace and plan-change modes)

Default (no flags): Discovers the project's cross-repo dependencies, workspace artifacts, transitive deps, dirty repo warnings, version variables, and build configuration.

Examples:

# What does this project depend on?
bash <skill_dir>/scripts/sbt_status.sh /path/to/service

# Full workspace state: preflight + all repos + dependency graph
bash <skill_dir>/scripts/sbt_status.sh /path/to/service --workspace

# What happens if I change commons and rebuild service-a?
bash <skill_dir>/scripts/sbt_status.sh /path/to/service-a --plan-change /path/to/commons

# Where is this artifact being resolved from?
bash <skill_dir>/scripts/sbt_status.sh /path/to/service --verify platform-commons

sbt_refresh.sh — Fix stale state

Clears caches, publishes upstream deps, and rebuilds.

bash <skill_dir>/scripts/sbt_refresh.sh <project-dir> [options]
OptionDescription
--publish-upstreamsPublish upstream workspace deps in dependency order first
--artifact-version <ver>Version for publishLocal
--artifact <name>Artifact name for targeted cache clearing
--version <ver>Version for targeted cache clearing
--clean-targetDelete project target/ directory (also kills SBT server)
--kill-serverExplicitly shut down the SBT server for this project
--rebuildRebuild with compile after refresh
--rebuild-arg <arg>Explicit SBT arg for rebuild (overrides --rebuild)
--workspace-dir <dir>Override workspace directory
--dry-runShow what would be done without doing it

Examples:

# Full upstream publish + cache clear + rebuild (most common for cross-repo changes)
bash <skill_dir>/scripts/sbt_refresh.sh /path/to/service --publish-upstreams --clean-target --rebuild

# Clear caches for a specific artifact and rebuild
bash <skill_dir>/scripts/sbt_refresh.sh /path/to/service --artifact my-lib --version 0.532.0 --clean-target --rebuild

# Dry run to see what would happen
bash <skill_dir>/scripts/sbt_refresh.sh /path/to/service --publish-upstreams --dry-run

sbt_reset.sh — Wipe isolated cache and return to clean state

Removes all local publishes and cached artifacts so builds resolve from remote again.

bash <skill_dir>/scripts/sbt_reset.sh [options]
OptionDescription
--local-onlyOnly wipe local publishes, keep downloaded cache
--dry-runShow what would be deleted without deleting

Examples:

# Full reset — everything from remote again
bash <skill_dir>/scripts/sbt_reset.sh

# Only wipe local publishes
bash <skill_dir>/scripts/sbt_reset.sh --local-only

# Preview what would be deleted
bash <skill_dir>/scripts/sbt_reset.sh --dry-run

Decision Table

ScenarioCommand
Edit target service code, compilesbt_build.sh <target> -- compile
Edit target service code, testsbt_build.sh <target> -- test
Test a specific subprojectsbt_build.sh <target> -- "<subproject> / test"
Collect coverage for a specific subproject testsbt_build.sh <target> --coverage -- "<subproject> / testOnly <suite>"
Check what this project depends onsbt_status.sh <target>
Check full workspace statesbt_status.sh <target> --workspace
Upstream library changed, rebuild downstreamsbt_refresh.sh <downstream> --publish-upstreams --clean-target --rebuild
Dependency declarations changed in build.sbtsbt_status.sh <target> then sbt_build.sh <target> -- compile
Downstream still sees old artifactsbt_refresh.sh <downstream> --artifact <name> --version <ver> --clean-target --rebuild
Plan a cross-repo changesbt_status.sh <target> --plan-change <changed-repo>
Verify artifact resolution sourcesbt_status.sh <target> --verify <artifact-name>
Compile with auto-fix for missing depssbt_build.sh <target> --auto-publish-deps -- compile
Compile several specific projectssbt_build.sh <proj-a> <proj-b> -- compile
Compile all workspace projectssbt_build.sh --all -- compile
Compile + test everythingsbt_build.sh --all --auto-publish-deps --continue-on-error -- test
Reset to clean state (resolve from remote)sbt_reset.sh
Reset only local publishessbt_reset.sh --local-only
SBT returns stale test results after editssbt_build.sh <target> --fresh -- test
SBT server is stuck/corruptedsbt_refresh.sh <target> --kill-server --clean-target --rebuild

Exit Codes

CodeMeaning
0SUCCESS — build/test completed without errors
1SBT error — compilation failure, test failure, or dependency resolution error
2Infrastructure error — lock contention, missing Java, missing config, or no test reports

Important rules

  1. Use sbt_build.sh for all compile, test, and publishLocal flows. It preserves full logs, auto-checks deps, and auto-parses test reports.
  2. All skill-driven SBT runs use the isolated cache at ~/.sbt-build-cache (Ivy, Coursier, SBT boot, SBT global) to avoid contaminating system caches.
  3. Use sbt_status.sh before guessing dependency order. Do not guess publish order.
  4. Show the dry-run plan before running sbt_refresh.sh with --publish-upstreams for the first time in a session.
  5. JUnit XML is the source of truth for test results. Console success only means SBT finished.

Parallel worktree builds

All SBT caches (Ivy, Coursier, SBT boot, SBT global) are isolated inside SBT_BUILD_CACHE_ROOT (default: ~/.sbt-build-cache). For parallel builds across git worktrees, set a different cache root per worktree:

# In worktree 1
export SBT_BUILD_CACHE_ROOT=~/.sbt-build-cache/wt-main

# In worktree 2
export SBT_BUILD_CACHE_ROOT=~/.sbt-build-cache/wt-feature-x

Each worktree gets its own publishLocal artifacts, Coursier downloads, and SBT boot files. No lock contention or cache corruption between parallel builds.

Note: The first build in a new cache root is slower due to cold Coursier and SBT boot caches. Subsequent builds are fast.

Error handling

ErrorCauseFix
Java <version> not foundRequested JDK is not installedUpdate .sbt-workspace.conf or install the matching JDK
python3 is requiredReport parsing runtime missingInstall python3
Credentials file does not existPrivate resolver credentials missingCreate ~/.ivy2/.credentials
cannot be mapped using the root pathsLocal publishes conflict with root-path/remote-cache settingsAuto-detected by sbt_build.sh — falls back to non-dev mode automatically
MISSING: <artifact> @ <version>Workspace dep not in isolated cacheUse --auto-publish-deps on sbt_build.sh, or run sbt_refresh.sh --publish-upstreams
STALE: <artifact> @ <version>Upstream workspace repo on a feature branch with no local publishWarning only. Republish upstream if you hit runtime errors
NoSuchMethodError / NoSuchFieldErrorStale artifact on classpathsbt_refresh.sh <project> --publish-upstreams --clean-target --rebuild
not a valid commandWrong scoped SBT commandRun sbt_status.sh <project> and use a listed subproject name
No test-reports directory foundTests did not generate XML reportsRun tests first via sbt_build.sh
CRASH (no JUnit XML produced)Test suite crashed before writing XMLCheck SBT log for ClassCastException, OutOfMemoryError, or initialization errors
Stale lock file detectedA previous build was killed leaving a lockAuto-cleaned — no action needed
WARNING: Log file is from a previous runSBT did not execute (likely lock contention)Check for concurrent builds or stale SBT server

Troubleshooting

ProblemFix
Console output truncatedsbt_build.sh saves full logs — inspect the log file path in the summary
Downstream still sees old artifactsbt_refresh.sh <project> --artifact <name> --clean-target --rebuild
Unsure if a change affects the targetsbt_status.sh <target> --plan-change <changed-repo>
Need the full workspace dependency ordersbt_status.sh <project> --workspace
NoSuchMethodError at runtimesbt_refresh.sh <project> --publish-upstreams --clean-target --rebuild
Upstream repo on a feature branchsbt_status.sh <project> --workspace to see branch alignment

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.