-
Notifications
You must be signed in to change notification settings - Fork 254
Description
🐹 Go Fan Report: goccy/go-yaml
Module Overview
github.com/goccy/go-yaml is a modern, pure-Go YAML parser and encoder built from scratch as a superior alternative to the de facto standard go-yaml/yaml library. This module provides exceptional parsing capabilities, beautiful error messages, and advanced features that make working with YAML a joy!
Why it's awesome:
- ✅ Passes 60+ more YAML Test Suite cases than go-yaml/yaml
- ✅ Written in idiomatic Go (not a C port)
- ✅ Actively maintained - commits from TODAY (2026-02-16)!
- ✅ Beautiful colored error messages with source code context
- ✅ Advanced features like YAML Path, AST manipulation, anchor/alias support
Current Usage in gh-aw
Summary Statistics
- Files Using Module: 47 files
- Total API Calls: 101 occurrences across 45 files
- Version: v1.19.2 (latest release, already up-to-date!)
- Import Count: High usage throughout workflow compilation and parsing
Key APIs Used
yaml.Marshal()/yaml.Unmarshal()- Core marshaling/unmarshalingyaml.MarshalWithOptions()- Custom marshaling with optionsyaml.MapSlice/yaml.MapItem- Deterministic field orderingyaml.EncodeOption- Customization (Indent,UseLiteralStyleIfMultiline)
Primary Use Cases
1. Workflow YAML Generation (pkg/workflow/yaml.go:185)
Excellent abstraction layer for generating GitHub Actions workflows with conventional field ordering:
// Custom function using yaml.MapSlice for deterministic ordering
func MarshalWithFieldOrder(data map[string]any, priorityFields []string) ([]byte, error) {
orderedData := OrderMapFields(data, priorityFields)
return yaml.MarshalWithOptions(orderedData, DefaultMarshalOptions...)
}Why this is great:
- Ensures workflows follow GitHub Actions conventions (name, on, permissions, jobs)
- Makes git diffs meaningful and predictable
- Improves readability for developers
2. Standard Marshal Options (pkg/workflow/yaml_options.go:13)
Centralized configuration for consistent YAML output:
var DefaultMarshalOptions = []yaml.EncodeOption{
yaml.Indent(2), // GitHub Actions standard
yaml.UseLiteralStyleIfMultiline(true), // Better multiline readability
}3. YAML Parsing (pkg/parser/yaml_import.go:95)
Robust parsing of GitHub Actions workflow files with validation:
var workflow map[string]any
if err := yaml.Unmarshal(content, &workflow); err != nil {
return "", "", fmt.Errorf("failed to parse YAML workflow: %w", err)
}4. Error Handling (pkg/parser/yaml_error_test.go)
Custom error extraction with comprehensive test coverage for accurate error reporting.
Research Findings
Recent Updates (VERY Active!)
🔥 TODAY's Commits (2026-02-16)
-
Fix empty sequence item consuming sibling mapping key (Fix: Ensure localhost domains are always included in Playwright allowed_domains #850)
- Fixed parser ambiguity when empty
-is followed by mapping key - Prevents incorrect YAML parsing in edge cases
- Fixed parser ambiguity when empty
-
Fix sibling anchor aliases silently resolving to nil (Update Playwright MCP configuration to use Docker instead of npx #848)
- Fixed context map mutation causing false self-recursion detection
- Ensures anchor references work correctly in nested structures
These fixes show the library is extremely responsive to bugs!
Recent Releases
v1.19.2 (2026-01-08) - Current version ✅
- Fix anchor reference regression in nested structures
v1.19.1 (2025-12-17)
- Fix decoding of integer map keys
- Support line comments for flow sequences/maps
v1.19.0 (2025-11-29)
- RawMessage support (like
json.RawMessage) - NEW! - Non-string map keys - NEW!
- Normalize CR/CRLF in multiline strings
- Decode option for field prefixes
Best Practices from Maintainers
- Use
yaml.MapSlicefor deterministic ordering ✅ - Already doing this! - Leverage
FormatErrorWithToken()for pretty errors - Opportunity - Use YAML Path for queries - Not currently utilized
- Consider
RawMessagefor deferred decoding - Could be useful - Register custom marshalers for domain types - Advanced feature
Improvement Opportunities
🏃 Quick Wins
1. Explore YAML Path for Query Operations (Low Effort, HIGH Value)
What: Built-in YAML Path support for querying YAML structures
Example Usage:
path, err := yaml.PathString("$.jobs[*].steps[?(@.uses)]")
var actionSteps []string
if err := path.Read(strings.NewReader(yamlContent), &actionSteps); err != nil {
// handle error
}
// actionSteps now contains all steps that use actions!Potential Applications:
- Workflow validation: Find all action usages, check versions
- Security analysis: Query for secrets usage patterns
- Metrics collection: Extract job dependencies, step counts
- Configuration extraction: Pull specific values without full unmarshal
Benefit: Simpler, more expressive code for workflow analysis and validation.
2. Consider Using FormatErrorWithToken for Error Messages
What: Native API for formatting YAML errors with source context
Current State: Custom regex parsing in pkg/parser/yaml_error_test.go
Opportunity: Use yaml.FormatError() or FormatErrorWithToken() for consistent error formatting with better source code context and optional colorization.
3. Add Test Coverage for Recent Bug Fixes
What: Add test cases for edge cases fixed in #850 and #848
Why: TODAY's commits fix subtle parser bugs. Adding tests ensures gh-aw workflows don't hit these edge cases.
Where: Test files that parse complex YAML with anchors or empty sequences.
✨ Feature Opportunities
4. Consider RawMessage for Dynamic Workflow Schemas
What: New yaml.RawMessage type (added in v1.19.0) for deferred decoding
Use Case: Workflow steps with variable schemas where structure isn't known upfront
Example:
type WorkflowStep struct {
Name string `yaml:"name"`
ID string `yaml:"id,omitempty"`
Uses string `yaml:"uses,omitempty"`
Raw yaml.RawMessage `yaml:",inline"` // Defer decoding
}Benefit: More flexible parsing of extensible workflow features.
5. Smart Anchor Option for Workflow Reuse
What: v1.16.0 feature for automatic anchor generation
Use Case: Generate workflows with reusable step definitions
Benefit: Automatic deduplication of repeated structures via YAML anchors/aliases, reducing workflow file size and improving maintainability.
6. Leverage YAML Playground for Debugging
What: Official playground at (goccy.github.io/redacted)
Use Case: Visualize YAML processing for debugging complex workflows
Benefit: Helps users understand how gh-aw parses and generates YAML.
📐 Best Practice Alignment
7. Already Excellent! ✅✅✅
The gh-aw codebase demonstrates exceptional usage of goccy/go-yaml:
- ✅ Deterministic ordering via
yaml.MapSlice - ✅ Consistent options via
DefaultMarshalOptions - ✅ Clean abstractions (
MarshalWithFieldOrder,OrderMapFields) - ✅ GitHub Actions conventions (field ordering, null handling, key unquoting)
- ✅ Proper error handling with custom extraction
- ✅ Separation of concerns (dedicated YAML files)
The custom MarshalWithFieldOrder() function is a textbook example of how to use yaml.MapSlice for deterministic YAML generation!
🔧 General Improvements
8. Document Library Choice
What: Add documentation explaining why goccy/go-yaml was chosen over go-yaml/yaml
Where: Architecture docs or contributing guide
Key Points:
- 60+ more YAML Test Suite passes
- Better error messages
- Active maintenance (commits today!)
- Native Go implementation
- Advanced features (YAML Path, AST manipulation)
Benefit: Helps contributors understand the decision and appreciate the library's advantages.
9. Consider Using AutoInt Option
What: v1.16.0 option for automatic integer type inference
Where: Workflow input parsing with mixed number types
Benefit: Automatically decode YAML numbers as the most appropriate Go type (int, int64, uint, etc.).
10. Explore Custom Marshaler Context (v1.18.0)
What: Custom marshalers/unmarshalers now receive context
Use Case: Pass environment-specific state during workflow generation
Benefit: More flexible marshaling for complex domain objects.
Recommendations
Priority 1: Stay Current ✅ (Already Done!)
- Status: gh-aw is on v1.19.2 (latest release)
- Action: Continue monitoring for updates - this library is VERY active!
Priority 2: Explore YAML Path (Low Effort, High Value)
- Effort: LOW - simple API, well-documented
- Value: HIGH - could simplify many validation/query operations
- Timeline: Experiment in workflow validation code
- Example: Query for all GitHub Actions versions, check for outdated actions
Priority 3: Add Edge Case Tests (Low Effort, Medium Value)
- Effort: LOW - add test cases
- Value: MEDIUM - prevent regressions
- Timeline: Next test cleanup sprint
- What: Test empty sequences, nested anchors (recent bug fixes)
Priority 4: Consider RawMessage (Medium Effort, Medium Value)
- Effort: MEDIUM - requires refactoring
- Value: MEDIUM - better for extensible features
- Timeline: When adding dynamic workflow features
Priority 5: Document Library Choice (Low Effort, Low Value)
- Effort: LOW - write documentation
- Value: LOW - nice-to-have for contributors
- Timeline: During next documentation pass
Conclusion
gh-aw's usage of goccy/go-yaml is exemplary! 🎉
The codebase demonstrates:
- ✅ Excellent abstractions (
MarshalWithFieldOrder) - ✅ Proper use of advanced features (
yaml.MapSlice) - ✅ Consistent configuration (
DefaultMarshalOptions) - ✅ Clean separation of concerns
- ✅ Already on the latest version
The main opportunities are optional enhancements rather than fixes:
- Explore YAML Path for simpler queries
- Consider RawMessage for future extensibility
- Add tests for recent bug fixes
Why This Module Rocks 🚀
- 60+ more test cases passed than go-yaml/yaml
- Active maintenance (commits from TODAY!)
- Better errors with source code context and colors
- Advanced features (YAML Path, anchors, AST manipulation)
- Pure Go implementation (not a C port)
- No dependencies
- 2,109 stars and growing!
Module Summary Saved: scratchpad/mods/go-yaml.md
References:
- Repository: https://github.com/goccy/go-yaml
- Documentation: https://pkg.go.dev/github.com/goccy/go-yaml
- Playground: (goccy.github.io/redacted)
- Last Reviewed: 2026-02-16
- Review Trigger: Recent commit activity (2026-02-16)
Generated by Go Fan 🐹 - Your Daily Go Module Reviewer
Workflow Run: §22053663600
Note: This was intended to be a discussion, but discussions could not be created due to permissions issues. This issue was created as a fallback.
Tip: Discussion creation may fail if the specified category is not announcement-capable. Consider using the "Announcements" category or another announcement-capable category in your workflow configuration.
Generated by Go Fan
- expires on Feb 23, 2026, 7:27 AM UTC