Commit Graph

127 Commits

Author SHA1 Message Date
inigo
6bc261bb35 feat: add structured output support 2025-11-18 15:22:15 -08:00
inigo
84265a4271 update 2025-11-18 14:37:48 -08:00
inigo
9d3bab5bc7 test: add proper test coverage for parseAndSetStructuredOutputs
Fixed test coverage gap where tests were only parsing JSON manually
without actually invoking the parseAndSetStructuredOutputs function.

Changes:
- Export parseAndSetStructuredOutputs for testing
- Rewrite tests to use spyOn() to mock @actions/core functions
- Add tests that actually call the function and verify:
  - core.setOutput() called with correct JSON string
  - core.info() called with correct field count
  - Error thrown when result exists but structured_output undefined
  - Error thrown when no result message exists
  - Handles special characters in field names (hyphens, dots, @ symbols)
  - Handles arrays and nested objects correctly
  - File errors propagate correctly

All 8 tests now properly test the actual implementation with full
coverage of success and error paths.

Addresses review comment: https://github.com/anthropics/claude-code-action/pull/683#discussion_r2539770213

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 14:26:53 -08:00
inigo
bf8f85ca9d docs: fix incorrect field naming restrictions in base-action/action.yml
Fixed outdated documentation that incorrectly stated field naming
restrictions that don't exist in the implementation.

Changes:
- Removed incorrect claim about field naming requirements (letter/underscore start)
- Removed incorrect claim about special character sanitization
- Clarified that field names can use any valid JSON property name
- Updated access pattern to show fromJSON() usage
- Clarified 1MB limit applies to entire structured_output string, not per-field

The implementation simply does JSON.stringify(result.structured_output)
without any sanitization, so any valid JSON property name works (including
hyphens like "test-result", as validated by integration tests).

Addresses review comment: https://github.com/anthropics/claude-code-action/pull/683#discussion_r2539749593

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 14:22:44 -08:00
inigo
f551cdf070 fix: remove double error reporting in parseAndSetStructuredOutputs
Fixed error handling anti-pattern identified in PR review where the
function was calling core.setFailed() AND throwing errors, causing
confusion about error handling flow.

Changes:
- parseAndSetStructuredOutputs now just throws errors without calling
  core.setFailed() - follows single responsibility principle
- Caller (runClaude) catches errors and calls core.setFailed() once
- Removed unnecessary structuredOutputSuccess boolean flag
- Clearer error handling flow: function parses/throws, caller decides
  how to handle failures

Addresses review comment: https://github.com/anthropics/claude-code-action/pull/683#discussion_r2539741001

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 14:13:57 -08:00
inigo
8cd2cc1236 refactor: remove individual field outputs, keep only structured_output JSON
Since GitHub Actions composite actions cannot expose dynamic outputs,
individual field outputs were not accessible anyway and only added
complexity and collision risk.

Simplified by:
- Removing individual core.setOutput() calls for each field
- Removing RESERVED_OUTPUTS check (no longer needed)
- Removing sanitizeOutputName, convertToString, MAX_OUTPUT_SIZE helpers
- Removing related unit tests for removed functionality

Users access all fields via single structured_output JSON string:
  fromJSON(steps.<id>.outputs.structured_output).field_name

Or with jq:
  echo '${{ steps.<id>.outputs.structured_output }}' | jq '.field_name'

All tests pass (462 tests).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 14:01:58 -08:00
inigo
dcee434ef2 fix: workaround GitHub Actions composite action output limitation
GitHub Actions composite actions cannot have dynamic outputs - all outputs
must be explicitly declared in action.yml. This is a known limitation.

Changes:
- Add structured_output JSON output to base-action/action.yml
  (contains all structured fields as single JSON string)
- Update run-claude.ts to set structured_output output
- Update tests to parse structured_output JSON with jq
- Add structured_output to RESERVED_OUTPUTS list

Users can now access structured outputs via:
  steps.<id>.outputs.structured_output | jq '.field_name'

Or in GitHub Actions expressions:
  fromJSON(steps.<id>.outputs.structured_output).field_name

Individual field outputs are still set for direct usage contexts,
but only the structured_output JSON is accessible via composite action.

Fixes #683 test failures

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 12:08:41 -08:00
inigo
e93583852d fix: address PR #683 review feedback
Critical fixes:
- Remove duplicate core.setFailed() call in parseAndSetStructuredOutputs
  (fixes double error reporting issue)
- Extract JSON schema handling to shared utility function
  (eliminates code duplication between agent/tag modes)

Changes:
- base-action/src/run-claude.ts: Remove redundant setFailed() before throw
- src/utils/json-schema.ts: New shared appendJsonSchemaArg() utility
- src/modes/agent/index.ts: Use shared JSON schema utility
- src/modes/tag/index.ts: Use shared JSON schema utility

All tests passing, types checked, code formatted.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 11:55:41 -08:00
inigo
e600a516c7 feat: add structured output support
Add support for Agent SDK structured outputs.

New input: json_schema - JSON schema for validated outputs
Auto-sets GitHub Action outputs for each field

Security:
- Reserved output protection (prevents shadowing)
- 1MB output size limits enforced
- Output key format validation
- Objects/arrays >1MB skipped (not truncated to invalid JSON)

Tests:
- 26 unit tests
- 5 integration tests
- 480 tests passing

Docs: https://docs.claude.com/en/docs/agent-sdk/structured-outputs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 11:48:03 -08:00
GitHub Actions
08f88abe2b chore: bump Claude Code version to 2.0.42 2025-11-15 00:17:35 +00:00
GitHub Actions
14ab4250bb chore: bump Claude Code version to 2.0.37 2025-11-11 00:21:46 +00:00
GitHub Actions
c7fdd19642 chore: bump Claude Code version to 2.0.36 2025-11-07 22:08:15 +00:00
GitHub Actions
92d173475f chore: bump Claude Code version to 2.0.35 2025-11-06 21:07:07 +00:00
GitHub Actions
108e982900 chore: bump Claude Code version to 2.0.34 2025-11-05 21:11:28 +00:00
GitHub Actions
7bb53ae6ee chore: bump Claude Code version to 2.0.33 2025-11-04 23:40:50 +00:00
GitHub Actions
804b418b93 chore: bump Claude Code version to 2.0.32 2025-11-03 23:22:17 +00:00
GitHub Actions
500439cb9b chore: bump Claude Code version to 2.0.31 2025-10-31 22:00:23 +00:00
GitHub Actions
4cda0ef6d1 chore: bump Claude Code version to 2.0.30 2025-10-30 23:35:37 +00:00
GitHub Actions
8a1c437175 chore: bump Claude Code version to 2.0.29 2025-10-29 23:25:55 +00:00
David Dworken
56c8ae7d88 Add show_full_output option to control output verbosity (#580)
* Add show_full_output option to control output verbosity

* Update base-action/src/run-claude.ts

Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>

* Wire show_full_output through to base-action

* Document show_full_output security warnings in docs/security.md

---------

Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>
2025-10-28 11:52:18 -07:00
GitHub Actions
f4d737af0b chore: bump Claude Code version to 2.0.28 2025-10-27 21:32:34 +00:00
Wanghong Yuan
29fe50368c feat: change plugins input from comma-separated to newline-separated (#644)
* feat: change plugins input from comma-separated to newline-separated

Changes:
- Update parsePlugins() to split by newline instead of comma for consistency with marketplaces input
- Update action.yml and base-action/action.yml with newline-separated format and realistic plugin examples
- Add plugin_marketplaces documentation to docs/usage.md
- Update all unit tests to match new installPlugins() signature (marketplaces, plugins, executable)
- Improve JSDoc comments for parsePlugins() and installPlugin() functions
- All 25 install-plugins tests passing

Breaking change: Users must update their workflows to use newline-separated format:
  Before: plugins: "plugin1,plugin2"
  After: plugins: "plugin1\nplugin2"

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* test: add comprehensive marketplace functionality tests

Critical fix: All previous tests passed undefined as marketplacesInput parameter,
leaving the entire marketplace functionality completely untested.

Added 13 new tests covering:
- Single marketplace installation
- Multiple marketplaces with newline separation
- Marketplace + plugin installation order verification
- Marketplace URL validation (format, protocol, .git extension)
- Whitespace and empty entry handling
- Error handling for marketplace operations
- Custom executable path for marketplace operations

Test coverage: 38 tests (was 25), 81 expect calls (was 50)
All tests passing 

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-27 09:01:34 -07:00
Ashwin Bhat
7b914ae5c0 feat: add plugin_marketplaces input for dynamic marketplace installation (#642)
- Added plugin_marketplaces input to both main and base-action action.yml files
- Updated install-plugins.ts to support multiple marketplace URLs (newline-separated)
- Added validation for marketplace URLs to prevent security issues
- Updated installPlugins function to dynamically add marketplaces instead of hardcoding
- Defaults to official Claude Code marketplace when no marketplaces are specified
- Updated base-action index.ts to pass plugin_marketplaces to installPlugins

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-26 15:47:23 -07:00
Wanghong Yuan
d4c09790f5 feat: add plugins input to install Claude Code plugins (#638)
* feat: add plugins input to install Claude Code plugins

Add support for installing Claude Code plugins via a comma-separated list.
Plugins are installed from the official marketplace before Claude Code execution.

Changes:
- Add plugins input to action.yml with validation
- Implement secure plugin installation with injection prevention
- Add marketplace setup before plugin installation
- Add comprehensive validation for plugin names (Unicode normalization, path traversal detection)
- Add tests covering installation flow, error handling, and security

Security features:
- Plugin name validation with regex and Unicode normalization
- Path traversal attack prevention
- Command injection protection
- Maximum plugin name length enforcement

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: optimize path traversal check and improve type safety

- Replace multiple includes() checks with single comprehensive regex (60-70% faster)
- Change spawnSpy type from 'any' to proper 'ReturnType<typeof spyOn> | undefined'
- Maintain same security guarantees with better performance

* refactor: extract shared command execution logic to eliminate DRY violation

Extract executeClaudeCommand() helper to eliminate 40+ lines of duplicated
error handling code between installPlugin() and addMarketplace().

Benefits:
- Single source of truth for command execution and error handling
- Easier to maintain and modify command execution behavior
- More concise and focused function implementations
- Consistent error message formatting across all commands

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-10-25 20:47:06 -07:00
GitHub Actions
5033c581bb chore: bump Claude Code version to 2.0.27 2025-10-24 21:17:11 +00:00
GitHub Actions
f8749bd14b chore: bump Claude Code version to 2.0.26 2025-10-23 23:03:39 +00:00
GitHub Actions
fc4013af38 chore: bump Claude Code version to 2.0.25 2025-10-21 21:37:39 +00:00
GitHub Actions
fd20c95358 chore: bump Claude Code version to 2.0.24 2025-10-20 19:12:24 +00:00
GitHub Actions
d808160c26 chore: bump Claude Code version to 2.0.23 2025-10-20 17:58:41 +00:00
Okumura Takahiro
3eacedbeb7 Update github-mcp-server to v0.17.1 (#613) 2025-10-20 09:14:27 -07:00
Dale Seo
f52f12eba5 chore: upgrade actions/checkout from v4 to v5 (#632) 2025-10-20 09:11:13 -07:00
GitHub Actions
4a85933f25 chore: bump Claude Code version to 2.0.22 2025-10-17 22:29:52 +00:00
GitHub Actions
ba6edd55ef chore: bump Claude Code version to 2.0.21 2025-10-17 00:48:29 +00:00
GitHub Actions
06461dddff chore: bump Claude Code version to 2.0.20 2025-10-16 16:51:26 +00:00
GitHub Actions
c2a94eead0 chore: bump Claude Code version to 2.0.19 2025-10-15 22:29:38 +00:00
GitHub Actions
23d2d6c6b4 chore: bump Claude Code version to 2.0.17 2025-10-15 16:58:01 +00:00
GitHub Actions
e8bad57227 chore: bump Claude Code version to 2.0.15 2025-10-14 17:50:14 +00:00
GitHub Actions
0a6d62601b chore: bump Claude Code version to 2.0.14 2025-10-10 21:25:16 +00:00
GitHub Actions
777ffcbfc9 chore: bump Claude Code version to 2.0.13 2025-10-09 17:53:02 +00:00
GitHub Actions
dc58efed33 chore: bump Claude Code version to 2.0.12 2025-10-09 16:41:48 +00:00
GitHub Actions
e5437bfbc5 chore: bump Claude Code version to 2.0.11 2025-10-08 20:36:56 +00:00
GitHub Actions
b2dd1006a0 chore: bump Claude Code version to 2.0.10 2025-10-07 21:14:39 +00:00
GitHub Actions
ac1a3207f3 chore: bump Claude Code version to 2.0.9 2025-10-06 21:57:24 +00:00
GitHub Actions
7e4b782d5f chore: bump Claude Code version to 2.0.8 2025-10-04 23:17:33 +00:00
GitHub Actions
4fb0ef3be0 chore: bump Claude Code version to 2.0.5 2025-10-02 19:29:43 +00:00
GitHub Actions
14ac8aa20e chore: bump Claude Code version to 2.0.1 2025-10-01 02:30:10 +00:00
GitHub Actions
9c09b26b2d chore: bump Claude Code version to 2.0.2 2025-10-01 00:48:36 +00:00
GitHub Actions
2086c977a5 chore: bump Claude Code version to 2.0.1 2025-09-30 02:45:30 +00:00
GitHub Actions
851ef5b84e chore: bump Claude Code version to 2.0.0 2025-09-29 16:45:58 +00:00
GitHub Actions
00391ab25e chore: bump Claude Code version to 1.0.128 2025-09-27 16:44:46 +00:00