docs: update structured output documentation for JSON-only approach

Updated documentation to reflect that structured outputs are now only
accessible via the single structured_output JSON string, not as
individual fields.

Changes:
- docs/usage.md: Updated "Accessing Structured Outputs" section
  - Show fromJSON() usage in GitHub Actions expressions
  - Show jq usage in bash
  - Explain composite action limitation
  - Remove outdated "Output Naming Rules" and size limit sections
- action.yml: Updated json_schema input description
- examples/test-failure-analysis.yml: Updated to use fromJSON() and jq

Users now access fields via:
  fromJSON(steps.<id>.outputs.structured_output).field_name
Or:
  echo '${{ steps.<id>.outputs.structured_output }}' | jq '.field_name'

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
inigo
2025-11-18 14:07:00 -08:00
parent 8cd2cc1236
commit ec3a934da7
3 changed files with 51 additions and 29 deletions

View File

@@ -114,7 +114,7 @@ inputs:
required: false
default: ""
json_schema:
description: "JSON schema for structured output validation. When provided, Claude will return validated JSON matching this schema, and the action will automatically set GitHub Action outputs for each field."
description: "JSON schema for structured output validation. When provided, Claude will return validated JSON matching this schema. All fields are available in the structured_output output as a JSON string (use fromJSON() or jq to access fields)."
required: false
default: ""

View File

@@ -213,7 +213,7 @@ Get validated JSON results from Claude that automatically become GitHub Action o
}
- name: Retry if flaky
if: steps.analyze.outputs.is_flaky == 'true'
if: fromJSON(steps.analyze.outputs.structured_output).is_flaky == true
run: gh workflow run CI
```
@@ -222,29 +222,31 @@ Get validated JSON results from Claude that automatically become GitHub Action o
1. **Define Schema**: Provide a JSON schema in the `json_schema` input
2. **Claude Executes**: Claude uses tools to complete your task
3. **Validated Output**: Result is validated against your schema
4. **Auto-set Outputs**: Each field automatically becomes a GitHub Action output
4. **JSON Output**: All fields are returned in a single `structured_output` JSON string
### Type Conversions
### Accessing Structured Outputs
GitHub Actions outputs must be strings. Values are converted automatically:
All structured output fields are available in the `structured_output` output as a JSON string:
- `boolean``"true"` or `"false"`
- `number``"42"` or `"3.14"`
- `object/array` → JSON stringified (use `fromJSON()` in workflows to parse)
- `null``""` (empty string)
**In GitHub Actions expressions:**
### Output Naming Rules
```yaml
if: fromJSON(steps.analyze.outputs.structured_output).is_flaky == true
run: |
CONFIDENCE=${{ fromJSON(steps.analyze.outputs.structured_output).confidence }}
```
- Field names are sanitized: special characters replaced with underscores
- Must start with letter or underscore (GitHub Actions requirement)
- Reserved names (`conclusion`, `execution_file`) are automatically skipped
- Example: `test.result` becomes `test_result`
**In bash with jq:**
### Size Limits
```yaml
- name: Process results
run: |
OUTPUT='${{ steps.analyze.outputs.structured_output }}'
IS_FLAKY=$(echo "$OUTPUT" | jq -r '.is_flaky')
SUMMARY=$(echo "$OUTPUT" | jq -r '.summary')
```
- Maximum 1MB per output field
- Objects/arrays exceeding 1MB are skipped with warnings
- Primitive values exceeding 1MB are truncated
**Note**: Due to GitHub Actions limitations, composite actions cannot expose dynamic outputs. All fields are bundled in the single `structured_output` JSON string.
### Complete Example

View File

@@ -68,13 +68,17 @@ jobs:
# Auto-retry only if flaky AND high confidence (>= 0.7)
- name: Retry flaky tests
if: |
steps.detect.outputs.is_flaky == 'true' &&
steps.detect.outputs.confidence >= '0.7'
fromJSON(steps.detect.outputs.structured_output).is_flaky == true &&
fromJSON(steps.detect.outputs.structured_output).confidence >= 0.7
env:
GH_TOKEN: ${{ github.token }}
run: |
echo "🔄 Flaky test detected (confidence: ${{ steps.detect.outputs.confidence }})"
echo "Summary: ${{ steps.detect.outputs.summary }}"
OUTPUT='${{ steps.detect.outputs.structured_output }}'
CONFIDENCE=$(echo "$OUTPUT" | jq -r '.confidence')
SUMMARY=$(echo "$OUTPUT" | jq -r '.summary')
echo "🔄 Flaky test detected (confidence: $CONFIDENCE)"
echo "Summary: $SUMMARY"
echo ""
echo "Triggering automatic retry..."
@@ -84,10 +88,13 @@ jobs:
# Low confidence flaky detection - skip retry
- name: Low confidence detection
if: |
steps.detect.outputs.is_flaky == 'true' &&
steps.detect.outputs.confidence < '0.7'
fromJSON(steps.detect.outputs.structured_output).is_flaky == true &&
fromJSON(steps.detect.outputs.structured_output).confidence < 0.7
run: |
echo "⚠️ Possible flaky test but confidence too low (${{ steps.detect.outputs.confidence }})"
OUTPUT='${{ steps.detect.outputs.structured_output }}'
CONFIDENCE=$(echo "$OUTPUT" | jq -r '.confidence')
echo "⚠️ Possible flaky test but confidence too low ($CONFIDENCE)"
echo "Not retrying automatically - manual review recommended"
# Comment on PR if this was a PR build
@@ -96,16 +103,29 @@ jobs:
env:
GH_TOKEN: ${{ github.token }}
run: |
OUTPUT='${{ steps.detect.outputs.structured_output }}'
IS_FLAKY=$(echo "$OUTPUT" | jq -r '.is_flaky')
CONFIDENCE=$(echo "$OUTPUT" | jq -r '.confidence')
SUMMARY=$(echo "$OUTPUT" | jq -r '.summary')
pr_number=$(gh pr list --head "${{ github.event.workflow_run.head_branch }}" --json number --jq '.[0].number')
if [ -n "$pr_number" ]; then
if [ "$IS_FLAKY" = "true" ]; then
TITLE="🔄 Flaky Test Detected"
ACTION="✅ Automatically retrying the workflow"
else
TITLE="❌ Test Failure"
ACTION="⚠️ This appears to be a real bug - manual intervention needed"
fi
gh pr comment "$pr_number" --body "$(cat <<EOF
## ${{ steps.detect.outputs.is_flaky == 'true' && '🔄 Flaky Test Detected' || '❌ Test Failure' }}
## $TITLE
**Analysis**: ${{ steps.detect.outputs.summary }}
**Confidence**: ${{ steps.detect.outputs.confidence }}
**Analysis**: $SUMMARY
**Confidence**: $CONFIDENCE
${{ steps.detect.outputs.is_flaky == 'true' && '✅ Automatically retrying the workflow' || '⚠️ This appears to be a real bug - manual intervention needed' }}
$ACTION
[View workflow run](${{ github.event.workflow_run.html_url }})
EOF