This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
A single TypeScript codebase that produces both GitHub Actions and Azure Pipelines tasks which install and run the .NET CLI tools GitVersion and GitReleaseManager. Node >= 24 is required. Development is expected on Linux/macOS (use WSL on Windows).
npm run build # build everything (tools bundle + all three agent bundles) via vite/rolldown -> dist/tools
npm run build:tools # cli + per-tool runner libs
npm run build:agents # local + azure + github agent bundles
npm run test # run all tests (tools + agents) with vitest
npm run test:tools # only src/__tests__/tools
npm run test:agents # only src/__tests__/agents
npx vitest --run src/__tests__/tools/gitversion/runner.spec.ts --config src/__tests__/vitest.config.ts # single test file
npm run lint:check # eslint src (lint:fix to autofix)
npm run typecheck # tsc --noEmit
npm run format:check # prettier (format:fix to autofix)
npm run mdlint:check # markdownlint docs dist
# Run a built tool locally (after build), e.g.:
npm run run:local:gitversion -- --command executeNote: the README references npm run build:local etc., but the actual scripts are build:agent:local / build:agent:azure / build:agent:github.
The husky pre-commit hook runs npm run build and git add **/*.mjs*, then lint-staged. The bundled .mjs output is checked into the repo (repo-root action dirs and dist/) because that is what the published GitHub Action / Azure extension actually executes. When you change src/, the built artifacts change too — don't hand-edit the generated .mjs.
The code is organized along two orthogonal axes: tools (gitversion, gitreleasemanager) × agents / CI platforms (local, azure, github). A tool is platform-agnostic; an agent abstracts one CI platform.
cli.ts parses --agent, --tool, --command and calls run(). getToolRunner() dynamically imports the built bundles by convention:
- the agent from
./{agent}/agent.mjs(exportsBuildAgent) - the tool runner from
./libs/{tool}.mjs(exportsRunner)
This module layout is produced by the vite configs, so build output paths and these import strings must stay in sync.
-
IBuildAgent/BuildAgentBase(src/agents/common/build-agent.ts) — the CI-platform abstraction: reading typed inputs (getInput<T>,getBooleanInput<T>), setting outputs/variables,exec, tool caching, path/dir helpers. Each platform subclass (src/agents/{local,azure,github}/build-agent.ts) maps these onto that platform's env vars (e.g. GitHub usesGITHUB_WORKSPACE,RUNNER_TEMP,RUNNER_TOOL_CACHEand issues workflow commands). -
DotnetTool(src/tools/common/dotnet-tool.ts) — installs a .NET global tool from NuGet: resolves the version spec (queries the NuGet search API for non-explicit specs, validates againstversionRange), checks/populates the tool cache, locates the executable (including architecture-specific subdirs), and executes it with--roll-forward Major. UsesArgumentsBuilder(arguments-builder.ts) to build CLI args. -
RunnerBase/IRunner(src/tools/common/runner.ts) — per-tool command dispatch. Each tool'srunner.ts(src/tools/{tool}/runner.ts) switches on the command (e.g. gitversion:setup/execute/command) and wraps each insafeExecute, which disables telemetry, runs the action, logs output, and callssetSucceeded/setFailedon the agent.
Per-tool inputs are read through a SettingsProvider (settings.ts) using the agent's typed getInput<T>; models.ts holds the tool's types.
Each tool has: runner.ts (command dispatch, extends RunnerBase), tool.ts (extends DotnetTool, defines package name / version range / execution), settings.ts (SettingsProvider), models.ts, index.ts.
- GitHub Actions: entry points live in repo-root directories (
gitversion/,gitreleasemanager/,git/), one subdir per command, each withaction.yml+ builtmain.mjs. The rootaction.ymlpoints atgitversion/setup/main.js. - Azure Pipelines: built into
dist/azure/, one subdir per command withtask.json, plusmanifest.config.cjs/tasks.json. Packaged/published withtfx(publish:azure:*scripts);publish:preparerunsdist/azure/updateTasks.mjs.
@lib, @agents/common, @agents/{azure,local,github}, @tools/common, @tools/{gitversion,gitreleasemanager}. Use these instead of deep relative imports.
Vitest, globals enabled, config at src/__tests__/vitest.config.ts (targets node24, emits junit-report.xml). Tests mirror src/ structure under src/__tests__/{tools,agents}/; shared helpers in src/__tests__/tools/common/utils.ts.