Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
31 changes: 19 additions & 12 deletions .github/workflows/cli-version-checker.lock.yml

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

31 changes: 19 additions & 12 deletions .github/workflows/poem-bot.lock.yml

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

31 changes: 19 additions & 12 deletions .github/workflows/security-fix-pr.lock.yml

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

31 changes: 19 additions & 12 deletions .github/workflows/technical-doc-writer.lock.yml

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

31 changes: 19 additions & 12 deletions .github/workflows/tidy.lock.yml

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

31 changes: 19 additions & 12 deletions .github/workflows/unbloat-docs.lock.yml

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

36 changes: 36 additions & 0 deletions pkg/cli/add_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,42 @@ func addSourceToWorkflow(content, source string) (string, error) {
return "", fmt.Errorf("failed to parse frontmatter: %w", err)
}

// Try to preserve original frontmatter formatting by manually inserting the source field
if len(result.FrontmatterLines) > 0 {
// Check if source field already exists
if result.Frontmatter != nil {
if _, exists := result.Frontmatter["source"]; exists {
// Source field exists, replace it by parsing and re-marshaling (fallback behavior)
return addSourceToWorkflowFallback(result, source)
}
}

// Source field doesn't exist, insert it manually to preserve formatting
frontmatterLines := make([]string, len(result.FrontmatterLines))
copy(frontmatterLines, result.FrontmatterLines)

// Add source field at the end of the frontmatter, preserving original formatting
sourceField := fmt.Sprintf("source: %s", source)
frontmatterLines = append(frontmatterLines, sourceField)

// Reconstruct the file with preserved formatting
var lines []string
lines = append(lines, "---")
lines = append(lines, frontmatterLines...)
lines = append(lines, "---")
if result.Markdown != "" {
lines = append(lines, result.Markdown)
}

return strings.Join(lines, "\n"), nil
}

// Fallback to original behavior if no frontmatter lines are available
return addSourceToWorkflowFallback(result, source)
}

// addSourceToWorkflowFallback implements the original behavior as a fallback
func addSourceToWorkflowFallback(result *parser.FrontmatterResult, source string) (string, error) {
// Initialize frontmatter if it doesn't exist
if result.Frontmatter == nil {
result.Frontmatter = make(map[string]any)
Expand Down
55 changes: 55 additions & 0 deletions pkg/cli/add_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,41 @@ This workflow has complex 'on' triggers.`,
expectError: false,
checkSource: true,
},
{
name: "preserve_formatting_with_comments_and_blank_lines",
content: `---
on:
workflow_dispatch:

schedule:
# Run daily at 2am UTC, all days except Saturday and Sunday
- cron: "0 2 * * 1-5"

stop-after: +48h # workflow will no longer trigger after 48 hours

timeout_minutes: 30

permissions: read-all

network: defaults

engine: claude

tools:
# Web tools for testing
web-search: null

# Memory cache
cache-memory: true
---

# Well Formatted Workflow

This workflow has proper formatting with comments and blank lines.`,
source: "githubnext/agentics/workflows/formatted.md@v1.0.0",
expectError: false,
checkSource: true,
},
}

for _, tt := range tests {
Expand Down Expand Up @@ -113,11 +148,31 @@ This workflow has complex 'on' triggers.`,
if strings.Contains(tt.content, "# Test Workflow") && !strings.Contains(result, "# Test Workflow") {
t.Errorf("addSourceToWorkflow() result does not preserve markdown content")
}
if strings.Contains(tt.content, "# Well Formatted Workflow") && !strings.Contains(result, "# Well Formatted Workflow") {
t.Errorf("addSourceToWorkflow() result does not preserve markdown content")
}

// Verify that "on" keyword is not quoted
if strings.Contains(result, `"on":`) {
t.Errorf("addSourceToWorkflow() result contains quoted 'on' keyword, should be unquoted. Result:\n%s", result)
}

// For the formatting preservation test, verify that comments and blank lines are preserved
if tt.name == "preserve_formatting_with_comments_and_blank_lines" {
if !strings.Contains(result, "# Run daily at 2am UTC, all days except Saturday and Sunday") {
t.Errorf("addSourceToWorkflow() result does not preserve comments")
}
if !strings.Contains(result, "stop-after: +48h # workflow will no longer trigger") {
t.Errorf("addSourceToWorkflow() result does not preserve inline comments")
}
if !strings.Contains(result, " # Web tools for testing") {
t.Errorf("addSourceToWorkflow() result does not preserve indented comments")
}
// Check that there are still blank lines by checking for consecutive newlines
if !strings.Contains(result, "\n\n") {
t.Errorf("addSourceToWorkflow() result does not preserve blank lines")
}
}
}
})
}
Expand Down
Loading
Loading