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
16 changes: 8 additions & 8 deletions .github/workflows/issue-arborist.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions pkg/actionpins/data/action_pins.json
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@
"version": "v4.35.4",
"sha": "68bde559dea0fdcac2102bfdf6230c5f70eb485e"
},
"github/gh-aw-actions/setup@v0.71.5": {
"repo": "github/gh-aw-actions/setup",
"version": "v0.71.5",
"sha": "b8068426813005612b960b5ab0b8bd2c27142323"
},
Comment on lines +161 to +165
"github/stale-repos@v9.0.8": {
"repo": "github/stale-repos",
"version": "v9.0.8",
Expand Down
42 changes: 40 additions & 2 deletions pkg/parser/frontmatter_content.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func ExtractFrontmatterFromContent(content string) (*FrontmatterResult, error) {
}

// Check if file starts with frontmatter delimiter.
if strings.TrimSpace(firstLine) != "---" {
if !isFrontmatterDelimiterLine(firstLine) {
log.Print("No frontmatter delimiter found, returning content as markdown")
// No frontmatter, return entire content as markdown
return &FrontmatterResult{
Expand Down Expand Up @@ -62,7 +62,7 @@ func ExtractFrontmatterFromContent(content string) (*FrontmatterResult, error) {
}
}

if strings.TrimSpace(content[lineStart:lineEnd]) == "---" {
if isFrontmatterDelimiterLine(content[lineStart:lineEnd]) {
frontmatterEndStart = lineStart
markdownStart = nextCursor
break
Expand Down Expand Up @@ -122,6 +122,44 @@ func ExtractFrontmatterFromContent(content string) (*FrontmatterResult, error) {
}, nil
}

// isFrontmatterDelimiterLine returns true when a line consists of "---" with optional surrounding whitespace.
func isFrontmatterDelimiterLine(line string) bool {
// Fast path for common delimiters.
if line == "---" || line == "---\r" {
return true
}

// Fast path for ASCII-trimmable whitespace.
start, end := 0, len(line)
for start < end {
switch line[start] {
case ' ', '\t', '\n', '\r', '\v', '\f':
start++
default:
goto leftTrimmed
}
}
leftTrimmed:
if start >= end {
return false
}
for end > start {
switch line[end-1] {
case ' ', '\t', '\n', '\r', '\v', '\f':
end--
default:
goto rightTrimmed
}
}
rightTrimmed:
if end-start == 3 && line[start] == '-' && line[start+1] == '-' && line[start+2] == '-' {
return true
}

// Fallback keeps previous behavior for uncommon Unicode whitespace.
return strings.TrimSpace(line) == "---"
}

// ExtractFrontmatterFromBuiltinFile is a caching wrapper around ExtractFrontmatterFromContent
// for builtin virtual files. Because builtin files are registered once at startup and never
// change, the parsed FrontmatterResult is identical across calls. This function caches the
Expand Down
8 changes: 8 additions & 0 deletions pkg/parser/frontmatter_extraction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ This is a test workflow with empty frontmatter.`,
},
wantMarkdown: "# Content",
},
{
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",
},
wantMarkdown: "# Test Workflow",
},
}

for _, tt := range tests {
Expand Down
7 changes: 4 additions & 3 deletions pkg/workflow/compiler_orchestrator_frontmatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,21 @@ func (c *Compiler) parseFrontmatterSection(markdownPath string) (*frontmatterPar
// Intentionally not wrapping to avoid exposing internal path details
return nil, fmt.Errorf("failed to read file: %v", err) //nolint:errorlint // intentionally not wrapping to avoid exposing os.PathError
}
contentString := string(content)

log.Printf("File size: %d bytes", len(content))

// Parse frontmatter and markdown
orchestratorFrontmatterLog.Printf("Parsing frontmatter from file: %s", cleanPath)
result, err := parser.ExtractFrontmatterFromContent(string(content))
result, err := parser.ExtractFrontmatterFromContent(contentString)
if err != nil {
orchestratorFrontmatterLog.Printf("Frontmatter extraction failed: %v", err)
// Use FrontmatterStart from result if available, otherwise default to line 2 (after opening ---)
frontmatterStart := 2
if result != nil && result.FrontmatterStart > 0 {
frontmatterStart = result.FrontmatterStart
}
return nil, c.createFrontmatterError(cleanPath, string(content), err, frontmatterStart)
return nil, c.createFrontmatterError(cleanPath, contentString, err, frontmatterStart)
}

if len(result.Frontmatter) == 0 {
Expand All @@ -62,7 +63,7 @@ func (c *Compiler) parseFrontmatterSection(markdownPath string) (*frontmatterPar
}

// Preprocess schedule fields to convert human-friendly format to cron expressions
if err := c.preprocessScheduleFields(result.Frontmatter, cleanPath, string(content)); err != nil {
if err := c.preprocessScheduleFields(result.Frontmatter, cleanPath, contentString); err != nil {
orchestratorFrontmatterLog.Printf("Schedule preprocessing failed: %v", err)
return nil, err
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/workflow/data/action_pins.json
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@
"version": "v4.35.4",
"sha": "68bde559dea0fdcac2102bfdf6230c5f70eb485e"
},
"github/gh-aw-actions/setup@v0.71.5": {
"repo": "github/gh-aw-actions/setup",
"version": "v0.71.5",
"sha": "b8068426813005612b960b5ab0b8bd2c27142323"
},
Comment on lines +161 to +165
"github/stale-repos@v9.0.8": {
"repo": "github/stale-repos",
"version": "v9.0.8",
Expand Down
Loading