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
3 changes: 2 additions & 1 deletion pkg/cli/templates/instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,8 @@ Agentic workflows compile to GitHub Actions YAML:
4. **Use @include directives** for common patterns and security boilerplate
5. **Test with `gh aw compile`** before committing
6. **Review generated `.lock.yml`** files before deploying
7. **Use specific tool permissions** rather than broad access
7. **Set `stop-time`** for cost-sensitive workflows
8. **Use specific tool permissions** rather than broad access

## Validation

Expand Down
9 changes: 0 additions & 9 deletions pkg/parser/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ func TestValidateMainWorkflowFrontmatterWithSchema(t *testing.T) {
"steps": []string{"step1"},
"engine": "claude",
"tools": map[string]any{"github": "test"},
"max-runs": 5,
"stop-time": "2024-12-31",
"alias": "test-workflow",
},
Expand Down Expand Up @@ -177,14 +176,6 @@ func TestValidateMainWorkflowFrontmatterWithSchema(t *testing.T) {
wantErr: true,
errContains: "got string, want integer",
},
{
name: "invalid type for max-runs",
frontmatter: map[string]any{
"max-runs": "not-a-number",
},
wantErr: true,
errContains: "got string, want integer",
},
{
name: "valid frontmatter with complex on object",
frontmatter: map[string]any{
Expand Down
4 changes: 0 additions & 4 deletions pkg/parser/schemas/main_workflow_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -371,10 +371,6 @@
]
}
},
"max-runs": {
"type": "integer",
"description": "Maximum number of workflow runs"
},
"stop-time": {
"type": "string",
"description": "Time when workflow should stop running"
Expand Down
41 changes: 2 additions & 39 deletions pkg/workflow/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,6 @@ type WorkflowData struct {
AllowedTools string
AI string // "claude" or "codex" (for backwards compatibility)
EngineConfig *EngineConfig // Extended engine configuration
MaxRuns string
StopTime string
Alias string // for @alias trigger support
AliasOtherEvents map[string]any // for merging alias with other events
Expand Down Expand Up @@ -640,7 +639,6 @@ func (c *Compiler) parseWorkflowFile(markdownPath string) (*WorkflowData, error)
workflowData.PostSteps = c.extractTopLevelYAMLSection(result.Frontmatter, "post-steps")
workflowData.RunsOn = c.extractTopLevelYAMLSection(result.Frontmatter, "runs-on")
workflowData.Cache = c.extractTopLevelYAMLSection(result.Frontmatter, "cache")
workflowData.MaxRuns = c.extractYAMLValue(result.Frontmatter, "max-runs")
workflowData.StopTime = c.extractYAMLValue(result.Frontmatter, "stop-time")
workflowData.Alias = c.extractAliasName(result.Frontmatter)
workflowData.AIReaction = c.extractYAMLValue(result.Frontmatter, "ai-reaction")
Expand Down Expand Up @@ -1611,10 +1609,10 @@ func (c *Compiler) buildMainJob(data *WorkflowData, jobName string) (*Job, error
return job, nil
}

// generateSafetyChecks generates safety checks for max-runs and stop-time before executing agentic tools
// generateSafetyChecks generates safety checks for stop-time before executing agentic tools
func (c *Compiler) generateSafetyChecks(yaml *strings.Builder, data *WorkflowData) {
// If no safety settings, skip generating safety checks
if data.MaxRuns == "" && data.StopTime == "" {
if data.StopTime == "" {
return
}

Expand All @@ -1627,41 +1625,6 @@ func (c *Compiler) generateSafetyChecks(yaml *strings.Builder, data *WorkflowDat
workflowName := data.Name
yaml.WriteString(fmt.Sprintf(" WORKFLOW_NAME=\"%s\"\n", workflowName))

// Add max-runs check
if data.MaxRuns != "" {
yaml.WriteString(" \n")
yaml.WriteString(" # Check max-runs limit\n")
yaml.WriteString(fmt.Sprintf(" MAX_RUNS=%s\n", data.MaxRuns))
yaml.WriteString(" echo \"Checking max-runs limit: $MAX_RUNS\"\n")
yaml.WriteString(" \n")
yaml.WriteString(" # Count successful runs with workflow-complete.txt artifact\n")
yaml.WriteString(" echo \"Counting successful workflow runs with workflow-complete.txt artifact...\"\n")
yaml.WriteString(" SUCCESSFUL_RUNS=0\n")
yaml.WriteString(" \n")
yaml.WriteString(" # Get completed workflow runs\n")
yaml.WriteString(" COMPLETED_RUNS=$(gh run list --workflow \"$WORKFLOW_NAME\" --status completed --json databaseId -L 1000 --jq '.[].databaseId')\n")
yaml.WriteString(" \n")
yaml.WriteString(" # Check each completed run for workflow-complete.txt artifact\n")
yaml.WriteString(" for run_id in $COMPLETED_RUNS; do\n")
yaml.WriteString(" echo \"Checking run $run_id for workflow-complete.txt artifact...\"\n")
yaml.WriteString(" if gh run view $run_id --json artifacts --jq '.artifacts[].name' | grep -q '^workflow-complete.txt$'; then\n")
yaml.WriteString(" SUCCESSFUL_RUNS=$((SUCCESSFUL_RUNS + 1))\n")
yaml.WriteString(" echo \" ✓ Run $run_id has workflow-complete.txt artifact\"\n")
yaml.WriteString(" else\n")
yaml.WriteString(" echo \" ✗ Run $run_id does not have workflow-complete.txt artifact\"\n")
yaml.WriteString(" fi\n")
yaml.WriteString(" done\n")
yaml.WriteString(" \n")
yaml.WriteString(" echo \"Successful runs count: $SUCCESSFUL_RUNS\"\n")
yaml.WriteString(" \n")
yaml.WriteString(" if [ \"$SUCCESSFUL_RUNS\" -ge \"$MAX_RUNS\" ]; then\n")
yaml.WriteString(" echo \"Maximum successful runs limit ($MAX_RUNS) reached. Disabling workflow to prevent cost overrun.\"\n")
yaml.WriteString(" gh workflow disable \"$WORKFLOW_NAME\"\n")
yaml.WriteString(" echo \"Workflow disabled. Current run will continue but no future runs will be triggered.\"\n")
yaml.WriteString(" exit 1\n")
yaml.WriteString(" fi\n")
}

// Add stop-time check
if data.StopTime != "" {
yaml.WriteString(" \n")
Expand Down