npm testWatch mode during development:
npm run test:watchThe test suite covers:
token-extractor.test.ts— JSON and regex-based token extraction, turns extraction (Claude Code JSONnum_turns, Codex exec JSONLturn.completedcount, regex fallback, null cases), priority logic, edge casescontext.test.ts— GitHub event → trigger type mapping, trigger ref extraction for all event types,issue_commentPR vs issue distinctioncomment.test.ts— Markdown comment formatting, status emojis, cost formatting, multi-run accumulation, newest-first ordering, 5-run visible limit with collapsible history, old/new column format compatibilityingest.test.ts— API client success/failure handling, retry logic, Authorization headerworkflow-run.test.ts—workflow_run_idauto-resolution: gate logic, status normalization, trigger number fallback, zip artifact parsing, partial artifact handlingpricing.test.ts—fetchPricingsuccess/failure/timeout/malformed-response handling,getPricingexact and prefix matching, case insensitivity,nullcache pricing
To test the full compiled action against a real or mocked AgentMeter API:
npm run buildCreate a test event payload file:
cat > /tmp/event.json << 'EOF'
{
"action": "labeled",
"issue": {
"number": 1,
"pull_request": null
},
"label": {
"name": "agent"
}
}
EOFExport the required env vars:
export INPUT_API_KEY="am_sk_your_key_here"
export INPUT_MODEL="claude-sonnet-4-5"
export INPUT_STATUS="success"
export INPUT_ENGINE="claude"
export INPUT_POST_COMMENT="false"
export INPUT_API_URL="http://localhost:3000" # or https://agentmeter.app
export GITHUB_REPOSITORY="yourorg/your-repo"
export GITHUB_RUN_ID="12345678"
export GITHUB_WORKFLOW="agent-implement"
export GITHUB_EVENT_NAME="issues"
export GITHUB_EVENT_PATH="/tmp/event.json"
export GITHUB_TOKEN="your_github_pat" # only needed if post_comment=truenode dist/index.jsexport INPUT_INPUT_TOKENS="5000"
export INPUT_OUTPUT_TOKENS="2000"
export INPUT_CACHE_READ_TOKENS="15000"
export INPUT_CACHE_WRITE_TOKENS="3000"
export INPUT_TURNS="12"
node dist/index.jsexport INPUT_AGENT_OUTPUT='{"usage":{"input_tokens":1000,"output_tokens":500,"cache_read_input_tokens":200,"cache_creation_input_tokens":100}}'
node dist/index.js# Claude Code JSON with num_turns
export INPUT_AGENT_OUTPUT='{"num_turns":7,"usage":{"input_tokens":1000,"output_tokens":500}}'
node dist/index.js
# Codex exec JSONL turn.completed events
export INPUT_AGENT_OUTPUT='{"type":"turn.completed"}
{"type":"turn.completed"}
{"type":"turn.completed"}'
node dist/index.js
# Explicit turns override (auto-extraction ignored)
export INPUT_TURNS="5"
node dist/index.jsexport INPUT_API_URL="http://localhost:3000"
export INPUT_API_KEY="am_sk_your_local_key"
node dist/index.jsThe repo includes .github/workflows/agentmeter-inline-test.yml which fires on every pull_request event and runs the action directly from the branch code (uses: ./.). This is the primary way to test action changes without merging to main first.
It uses hardcoded synthetic token counts and a sleep 10 step so the reported duration is non-zero.
.github/workflows/ci.yml runs on every push and PR:
npm run lint— Biome lintingnpm run type-check— TypeScript strict modenpm test— Full test suite
.github/workflows/build.yml also runs on every push and PR to verify dist/index.js is not stale.
- Ensure all tests pass:
npm test - Run type check:
npm run type-check - Commit everything — the pre-commit hook runs lint-staged (Biome auto-fix), then
npm run lintas a hard gate, thennpm run type-check, thennpm run build, and finally stagesdist/index.jsanddist/licenses.txt - Push to
main - Create a GitHub release with a semver tag:
v1.0.0 - Update the major version tag:
git tag -f v1 && git push -f origin v1 - In the GitHub release UI, check "Publish this Action to GitHub Marketplace"
Note:
dist/must be committed. GitHub Actions checks out the repo at the referenced tag and runsdist/index.jsdirectly — it does not runnpm installornpm run build. The pre-commit hook ensuresdist/is always up-to-date before any commit lands.