Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions pkg/cli/commands_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,25 @@ func TestExtractWorkflowNameFromFile_NonExistentFile(t *testing.T) {
}
}

func TestExtractWorkflowNameFromFile_LargeFrontmatterLine(t *testing.T) {
tmpDir := testutil.TempDir(t, "test-*")
filePath := filepath.Join(tmpDir, "large-frontmatter.md")
content := "---\nblob: " + strings.Repeat("x", 70*1024) + "\n---\n\n# Large Frontmatter Workflow\n"

Comment on lines +119 to +121
err := os.WriteFile(filePath, []byte(content), 0644)
if err != nil {
t.Fatalf("Failed to create test file: %v", err)
}

result, err := extractWorkflowNameFromFile(filePath)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
if result != "Large Frontmatter Workflow" {
t.Fatalf("Expected %q, got %q", "Large Frontmatter Workflow", result)
}
}

func TestIsGitRepo(t *testing.T) {
// Test in current directory (should be a git repo based on project setup)
result := isGitRepo()
Expand Down
24 changes: 19 additions & 5 deletions pkg/cli/workflows.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"path/filepath"
"strconv"
"strings"
"sync"

"github.com/github/gh-aw/pkg/console"
"github.com/github/gh-aw/pkg/constants"
Expand All @@ -23,6 +24,14 @@ import (

var workflowsLog = logger.New("cli:workflows")

var workflowTitleScannerBufferPool = sync.Pool{
New: func() any {
return make([]byte, 4*1024)
},
}

const workflowTitleScannerBufferSize = 4 * 1024

func getWorkflowsDir() string {
return ".github/workflows"
}
Expand Down Expand Up @@ -335,11 +344,16 @@ func filterMarkdownFilesWithFrontmatter(mdFiles []string) ([]string, error) {
// Returns an error if frontmatter is opened but never closed.
func fastParseTitleFromReader(r io.Reader) (string, error) {
scanner := bufio.NewScanner(r)
// Use a small initial buffer (4 KB, matching the default scanner allocation)
// but allow growth up to 1 MB to handle files with large frontmatter values
// or long base64-encoded lines. Keeping the initial size small avoids a
// costly 64 KB heap allocation on every call.
scanner.Buffer(make([]byte, 4*1024), 1024*1024)
// Reuse the small initial scanner buffer across calls while still allowing
// growth up to 1 MB for large frontmatter values or long base64-encoded lines.
scannerBuffer := workflowTitleScannerBufferPool.Get().([]byte)
if cap(scannerBuffer) != workflowTitleScannerBufferSize {
scannerBuffer = make([]byte, workflowTitleScannerBufferSize)
} else {
scannerBuffer = scannerBuffer[:workflowTitleScannerBufferSize]
}
defer workflowTitleScannerBufferPool.Put(scannerBuffer)
scanner.Buffer(scannerBuffer, 1024*1024)
firstLine := true
inFrontmatter := false
for scanner.Scan() {
Expand Down
2 changes: 1 addition & 1 deletion pkg/parser/frontmatter_extraction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ This is a test workflow with empty frontmatter.`,
wantMarkdown: "# Content",
},
{
name: "frontmatter delimiters with surrounding whitespace",
name: "frontmatter delimiters with surrounding whitespace",
content: " \t--- \t\r\non: push\r\n \t--- \t\r\n\r\n# Test Workflow\r\n",
wantYAML: map[string]any{
"on": "push",
Expand Down
Loading