mirror of
https://github.com/ivuorinen/gh-action-readme.git
synced 2026-02-05 10:45:17 +00:00
This commit represents a comprehensive refactoring of the codebase focused on improving code quality, testability, and maintainability. Key improvements: - Implement dependency injection and interface-based architecture - Add comprehensive test framework with fixtures and test suites - Fix all linting issues (errcheck, gosec, staticcheck, goconst, etc.) - Achieve full EditorConfig compliance across all files - Replace hardcoded test data with proper fixture files - Add configuration loader with hierarchical config support - Improve error handling with contextual information - Add progress indicators for better user feedback - Enhance Makefile with help system and improved editorconfig commands - Consolidate constants and remove deprecated code - Strengthen validation logic for GitHub Actions - Add focused consumer interfaces for better separation of concerns Testing improvements: - Add comprehensive integration tests - Implement test executor pattern for better test organization - Create extensive YAML fixture library for testing - Fix all failing tests and improve test coverage - Add validation test fixtures to avoid embedded YAML in Go files Build and tooling: - Update Makefile to show help by default - Fix editorconfig commands to use eclint properly - Add comprehensive help documentation to all make targets - Improve file selection patterns to avoid glob errors This refactoring maintains backward compatibility while significantly improving the internal architecture and developer experience.
101 lines
2.6 KiB
Go
101 lines
2.6 KiB
Go
package internal
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
// ActionYML models the action.yml metadata (fields are updateable as schema evolves).
|
|
type ActionYML struct {
|
|
Name string `yaml:"name"`
|
|
Description string `yaml:"description"`
|
|
Inputs map[string]ActionInput `yaml:"inputs"`
|
|
Outputs map[string]ActionOutput `yaml:"outputs"`
|
|
Runs map[string]any `yaml:"runs"`
|
|
Branding *Branding `yaml:"branding,omitempty"`
|
|
// Add more fields as the schema evolves
|
|
}
|
|
|
|
// ActionInput represents an input parameter for a GitHub Action.
|
|
type ActionInput struct {
|
|
Description string `yaml:"description"`
|
|
Required bool `yaml:"required"`
|
|
Default any `yaml:"default"`
|
|
}
|
|
|
|
// ActionOutput represents an output parameter for a GitHub Action.
|
|
type ActionOutput struct {
|
|
Description string `yaml:"description"`
|
|
}
|
|
|
|
// Branding represents the branding configuration for a GitHub Action.
|
|
type Branding struct {
|
|
Icon string `yaml:"icon"`
|
|
Color string `yaml:"color"`
|
|
}
|
|
|
|
// ParseActionYML reads and parses action.yml from given path.
|
|
func ParseActionYML(path string) (*ActionYML, error) {
|
|
f, err := os.Open(path) // #nosec G304 -- path from function parameter
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer func() {
|
|
_ = f.Close() // Ignore close error in defer
|
|
}()
|
|
var a ActionYML
|
|
dec := yaml.NewDecoder(f)
|
|
if err := dec.Decode(&a); err != nil {
|
|
return nil, err
|
|
}
|
|
return &a, nil
|
|
}
|
|
|
|
// DiscoverActionFiles finds action.yml and action.yaml files in the given directory.
|
|
// This consolidates the file discovery logic from both generator.go and dependencies/parser.go.
|
|
func DiscoverActionFiles(dir string, recursive bool) ([]string, error) {
|
|
var actionFiles []string
|
|
|
|
// Check if dir exists
|
|
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
|
return nil, fmt.Errorf("directory does not exist: %s", dir)
|
|
}
|
|
|
|
if recursive {
|
|
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if info.IsDir() {
|
|
return nil
|
|
}
|
|
|
|
// Check for action.yml or action.yaml files
|
|
filename := strings.ToLower(info.Name())
|
|
if filename == "action.yml" || filename == "action.yaml" {
|
|
actionFiles = append(actionFiles, path)
|
|
}
|
|
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to walk directory %s: %w", dir, err)
|
|
}
|
|
} else {
|
|
// Check only the specified directory
|
|
for _, filename := range []string{"action.yml", "action.yaml"} {
|
|
path := filepath.Join(dir, filename)
|
|
if _, err := os.Stat(path); err == nil {
|
|
actionFiles = append(actionFiles, path)
|
|
}
|
|
}
|
|
}
|
|
|
|
return actionFiles, nil
|
|
}
|