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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
20 changes: 10 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -449,24 +449,24 @@ fmt: fmt-go fmt-cjs fmt-json

.PHONY: fmt-go
fmt-go:
@GOPATH=$$(go env GOPATH); \
if command -v golangci-lint >/dev/null 2>&1 || [ -x "$$GOPATH/bin/golangci-lint" ]; then \
PATH="$$GOPATH/bin:$$PATH" golangci-lint fmt; \
else \
echo "golangci-lint is not installed. Run 'make deps-dev' to install dependencies."; \
exit 1; \
fi
@echo "→ Formatting Go code..."
@go fmt ./...
@echo "✓ Go code formatted"

# Format JavaScript (.cjs and .js) and JSON files in actions/setup/js directory
.PHONY: fmt-cjs
fmt-cjs:
cd actions/setup/js && npm run format:cjs
npx prettier --write 'scripts/**/*.js' --ignore-path .prettierignore
@echo "→ Formatting JavaScript files..."
@cd actions/setup/js && npm run format:cjs
@npx prettier --write 'scripts/**/*.js' --ignore-path .prettierignore
@echo "✓ JavaScript files formatted"

# Format JSON files in pkg directory (excluding actions/setup/js, which is handled by npm script)
.PHONY: fmt-json
fmt-json:
cd actions/setup/js && npm run format:pkg-json
@echo "→ Formatting JSON files..."
@cd actions/setup/js && npm run format:pkg-json
@echo "✓ JSON files formatted"

# Check formatting
.PHONY: fmt-check
Expand Down
9 changes: 3 additions & 6 deletions docs/src/content/docs/setup/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,10 @@ There are hundreds of other ways to use GitHub Agentic Workflows, which you can

Before installing, ensure you have:

- ✅ **AI Account** - You need one of the following:
- [GitHub Copilot](https://github.com/features/copilot) subscription
- [Anthropic Claude](https://www.anthropic.com/) API key (recommended for simple setup)
- [OpenAI Codex](https://openai.com/api/) API key
- ✅ **GitHub Repository** - a GitHub repository you are a maintainer on
- ✅ **AI Account** - A [GitHub Copilot](https://github.com/features/copilot) subscription, or a [Anthropic Claude](https://www.anthropic.com/) or [OpenAI Codex](https://openai.com/api/) API key
- ✅ **GitHub Repository** - a GitHub repository you are maintainer on
- ✅ **GitHub Actions** enabled in your repository
- ✅ **GitHub CLI** (`gh`) - A command-line tool for GitHub. [Install here](https://cli.github.com) v2.0.0+ and authenticate with `gh auth login`
- ✅ **GitHub CLI** (`gh`) - A command-line tool for GitHub. [Install here](https://cli.github.com) v2.0.0+
- ✅ **Operating System**: Linux, macOS, or Windows with WSL

### Step 1 — Install the extension
Expand Down
15 changes: 11 additions & 4 deletions pkg/cli/add_workflow_compilation.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@ func compileWorkflow(filePath string, verbose bool, quiet bool, engineOverride s
// compileWorkflowWithRefresh compiles a workflow file with optional stop time refresh.
// This function handles the compilation process and ensures .gitattributes is updated.
func compileWorkflowWithRefresh(filePath string, verbose bool, quiet bool, engineOverride string, refreshStopTime bool) error {
// Create compiler and compile the workflow
compiler := workflow.NewCompiler(verbose, engineOverride, GetVersion())
// Create compiler with auto-detected version and action mode
compiler := workflow.NewCompiler(
workflow.WithVerbose(verbose),
workflow.WithEngineOverride(engineOverride),
)

compiler.SetRefreshStopTime(refreshStopTime)
compiler.SetQuiet(quiet)
if err := CompileWorkflowWithValidation(compiler, filePath, verbose, false, false, false, false, false); err != nil {
Expand Down Expand Up @@ -100,8 +104,11 @@ func compileWorkflowWithTrackingAndRefresh(filePath string, verbose bool, quiet
tracker.TrackCreated(gitAttributesPath)
}

// Create compiler and set the file tracker
compiler := workflow.NewCompiler(verbose, engineOverride, GetVersion())
// Create compiler with auto-detected version and action mode
compiler := workflow.NewCompiler(
workflow.WithVerbose(verbose),
workflow.WithEngineOverride(engineOverride),
)
compiler.SetFileTracker(tracker)
compiler.SetRefreshStopTime(refreshStopTime)
compiler.SetQuiet(quiet)
Expand Down
10 changes: 9 additions & 1 deletion pkg/cli/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/githubnext/gh-aw/pkg/console"
"github.com/githubnext/gh-aw/pkg/constants"
"github.com/githubnext/gh-aw/pkg/logger"
"github.com/githubnext/gh-aw/pkg/workflow"
)

var commandsLog = logger.New("cli:commands")
Expand All @@ -21,6 +22,12 @@ var (
version = "dev"
)

func init() {
// Set the default version in the workflow package
// This allows workflow.NewCompiler() to auto-detect the version
workflow.SetDefaultVersion(version)
}

//go:embed templates/github-agentic-workflows.md
var copilotInstructionsTemplate string

Expand Down Expand Up @@ -57,9 +64,10 @@ var campaignWorkflowExecutionTemplate string
//go:embed templates/close-agentic-campaign.md
var campaignClosingInstructionsTemplate string

// SetVersionInfo sets the version information for the CLI
// SetVersionInfo sets the version information for the CLI and workflow package
func SetVersionInfo(v string) {
version = v
workflow.SetDefaultVersion(v) // Keep workflow package in sync
}

// GetVersion returns the current version
Expand Down
30 changes: 15 additions & 15 deletions pkg/cli/commands_file_watching_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func TestWatchAndCompileWorkflows(t *testing.T) {
os.Chdir(tempDir)
defer os.Chdir(oldDir)

compiler := workflow.NewCompiler(false, "", "test")
compiler := workflow.NewCompiler()

err := watchAndCompileWorkflows("", compiler, false)
if err == nil {
Expand All @@ -50,7 +50,7 @@ func TestWatchAndCompileWorkflows(t *testing.T) {
t.Fatalf("Failed to init git repo: %v", initErr)
}

compiler := workflow.NewCompiler(false, "", "test")
compiler := workflow.NewCompiler()

err := watchAndCompileWorkflows("", compiler, false)
if err == nil {
Expand All @@ -77,7 +77,7 @@ func TestWatchAndCompileWorkflows(t *testing.T) {
workflowsDir := filepath.Join(tempDir, ".github/workflows")
os.MkdirAll(workflowsDir, 0755)

compiler := workflow.NewCompiler(false, "", "test")
compiler := workflow.NewCompiler()

err := watchAndCompileWorkflows("nonexistent.md", compiler, false)
if err == nil {
Expand Down Expand Up @@ -166,7 +166,7 @@ func TestCompileAllWorkflowFiles(t *testing.T) {
}

// Create a basic compiler
compiler := workflow.NewCompiler(false, "", "test")
compiler := workflow.NewCompiler()

stats, err := compileAllWorkflowFiles(compiler, workflowsDir, true)
if err != nil {
Expand Down Expand Up @@ -213,7 +213,7 @@ func TestCompileAllWorkflowFiles(t *testing.T) {
invalidContent := "---\nmalformed: yaml: content:\n - missing\n proper: structure\n---\n# Invalid\n\nThis should fail"
os.WriteFile(invalidFile, []byte(invalidContent), 0644)

compiler := workflow.NewCompiler(false, "", "test")
compiler := workflow.NewCompiler()

// This should not return an error (it prints errors but continues)
stats, err := compileAllWorkflowFiles(compiler, workflowsDir, false)
Expand All @@ -235,7 +235,7 @@ func TestCompileAllWorkflowFiles(t *testing.T) {
content := "---\non: push\nengine: claude\n---\n# Verbose Test\n\nTest content for verbose mode"
os.WriteFile(testFile, []byte(content), 0644)

compiler := workflow.NewCompiler(false, "", "test")
compiler := workflow.NewCompiler()

// Test verbose mode (should not error)
stats, err := compileAllWorkflowFiles(compiler, workflowsDir, true)
Expand Down Expand Up @@ -269,7 +269,7 @@ func TestCompileModifiedFiles(t *testing.T) {
oldTime := time.Now().Add(-2 * time.Hour)
os.Chtimes(file2, oldTime, oldTime)

compiler := workflow.NewCompiler(false, "", "test")
compiler := workflow.NewCompiler()

// Test with recent files - compileModifiedFiles takes a slice of files
modifiedFiles := []string{file1} // Only include the recent file
Expand All @@ -284,7 +284,7 @@ func TestCompileModifiedFiles(t *testing.T) {
})

t.Run("compile modified files with no files", func(t *testing.T) {
compiler := workflow.NewCompiler(false, "", "test")
compiler := workflow.NewCompiler()

// Test with empty file list (should not error)
emptyFiles := []string{}
Expand All @@ -293,7 +293,7 @@ func TestCompileModifiedFiles(t *testing.T) {
})

t.Run("compile modified files with invalid files", func(t *testing.T) {
compiler := workflow.NewCompiler(false, "", "test")
compiler := workflow.NewCompiler()

// Test with invalid file paths
invalidFiles := []string{"nonexistent/path/file.md"}
Expand All @@ -311,7 +311,7 @@ func TestCompileModifiedFiles(t *testing.T) {
content := "---\non: push\nengine: claude\n---\n# Recent Test\n\nRecent content"
os.WriteFile(recentFile, []byte(content), 0644)

compiler := workflow.NewCompiler(false, "", "test")
compiler := workflow.NewCompiler()

// Test verbose mode
modifiedFiles := []string{recentFile}
Expand Down Expand Up @@ -414,7 +414,7 @@ func TestCompileSingleFile(t *testing.T) {
content := "---\non: push\nengine: claude\n---\n# Test\n\nTest workflow content"
os.WriteFile(filePath, []byte(content), 0644)

compiler := workflow.NewCompiler(false, "", "test")
compiler := workflow.NewCompiler()
stats := &CompilationStats{}

// Compile without checking existence
Expand Down Expand Up @@ -449,7 +449,7 @@ func TestCompileSingleFile(t *testing.T) {
content := "---\nmalformed: yaml: content:\n - missing\n proper: structure\n---\n# Invalid\n"
os.WriteFile(filePath, []byte(content), 0644)

compiler := workflow.NewCompiler(false, "", "test")
compiler := workflow.NewCompiler()
stats := &CompilationStats{}

// Compile without checking existence
Expand Down Expand Up @@ -486,7 +486,7 @@ func TestCompileSingleFile(t *testing.T) {
content := "---\non: push\nengine: claude\n---\n# Test\n\nTest workflow content"
os.WriteFile(filePath, []byte(content), 0644)

compiler := workflow.NewCompiler(false, "", "test")
compiler := workflow.NewCompiler()
stats := &CompilationStats{}

// Compile with existence check
Expand All @@ -509,7 +509,7 @@ func TestCompileSingleFile(t *testing.T) {
// Use a non-existent file path
filePath := filepath.Join(workflowsDir, "nonexistent.md")

compiler := workflow.NewCompiler(false, "", "test")
compiler := workflow.NewCompiler()
stats := &CompilationStats{}

// Compile with existence check - should skip
Expand All @@ -534,7 +534,7 @@ func TestCompileSingleFile(t *testing.T) {
content := "---\non: push\nengine: claude\n---\n# Verbose Test\n\nTest workflow content"
os.WriteFile(filePath, []byte(content), 0644)

compiler := workflow.NewCompiler(false, "", "test")
compiler := workflow.NewCompiler()
stats := &CompilationStats{}

// Compile in verbose mode
Expand Down
19 changes: 11 additions & 8 deletions pkg/cli/compile_campaign_orchestrator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ func TestGenerateAndCompileCampaignOrchestrator(t *testing.T) {
MemoryPaths: []string{"memory/campaigns/test-campaign/**"},
}

compiler := workflow.NewCompiler(false, "", GetVersion())
compiler.SetSkipValidation(true)
compiler.SetNoEmit(false)
compiler.SetStrictMode(false)
// Compiler with auto-detected version and action mode
compiler := workflow.NewCompiler(
workflow.WithSkipValidation(true),
workflow.WithNoEmit(false),
workflow.WithStrictMode(false),
)

orchestratorPath, err := generateAndCompileCampaignOrchestrator(GenerateCampaignOrchestratorOptions{
Compiler: compiler,
Expand Down Expand Up @@ -149,10 +151,11 @@ func TestCampaignSourceCommentStability(t *testing.T) {
MemoryPaths: []string{"memory/campaigns/test-campaign/**"},
}

compiler := workflow.NewCompiler(false, "", GetVersion())
compiler.SetSkipValidation(true)
compiler.SetNoEmit(false)
compiler.SetStrictMode(false)
compiler := workflow.NewCompiler(
workflow.WithSkipValidation(true),
workflow.WithNoEmit(false),
workflow.WithStrictMode(false),
)

// Save original working directory
originalWd, err := os.Getwd()
Expand Down
12 changes: 7 additions & 5 deletions pkg/cli/compile_command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ func TestTrackWorkflowFailure(t *testing.T) {

// TestCompileWorkflowWithValidation_InvalidFile tests error handling
func TestCompileWorkflowWithValidation_InvalidFile(t *testing.T) {
compiler := workflow.NewCompiler(false, "", "test")
compiler := workflow.NewCompiler()

// Try to compile a non-existent file
err := CompileWorkflowWithValidation(
Expand Down Expand Up @@ -369,8 +369,10 @@ This is a test workflow.
}

// Create compiler with noEmit flag
compiler := workflow.NewCompiler(false, "", "test")
compiler.SetNoEmit(true)
compiler := workflow.NewCompiler(
workflow.WithVersion("test"),
workflow.WithNoEmit(true),
)

// Parse the workflow
workflowData, err := compiler.ParseWorkflowFile(testFile)
Expand Down Expand Up @@ -426,7 +428,7 @@ This is a test workflow.
}

// Create compiler
compiler := workflow.NewCompiler(false, "", "test")
compiler := workflow.NewCompiler()

// Compile the workflow
err := CompileWorkflowWithValidation(
Expand Down Expand Up @@ -758,7 +760,7 @@ This is a test workflow.

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
compiler := workflow.NewCompiler(false, "", "test")
compiler := workflow.NewCompiler()
// Note: SetSkipValidation controls schema validation, which is
// different from the validateActionSHAs parameter we're testing.
// We skip schema validation here to focus on the security tool independence test.
Expand Down
7 changes: 5 additions & 2 deletions pkg/cli/compile_compiler_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,11 @@ func createAndConfigureCompiler(config CompileConfig) *workflow.Compiler {
}
}

// Create compiler with verbose flag and AI engine override
compiler := workflow.NewCompiler(config.Verbose, config.EngineOverride, GetVersion())
// Create compiler with auto-detected version and action mode
compiler := workflow.NewCompiler(
workflow.WithVerbose(config.Verbose),
workflow.WithEngineOverride(config.EngineOverride),
)
compileCompilerSetupLog.Print("Created compiler instance")

// Configure compiler flags
Expand Down
6 changes: 4 additions & 2 deletions pkg/cli/compile_force_refresh_action_pins_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ func TestForceRefreshActionPins_ClearCache(t *testing.T) {
assert.Len(t, testCache.Entries, 2, "Cache should have 2 entries before force refresh")

// Create compiler with force refresh enabled
compiler := workflow.NewCompiler(false, "", "test")
compiler.SetForceRefreshActionPins(true)
compiler := workflow.NewCompiler(
workflow.WithVersion("test"),
workflow.WithForceRefreshActionPins(true),
)

// Get the shared action resolver - this should skip loading the cache
actionCache, _ := compiler.GetSharedActionResolverForTest()
Expand Down
Loading
Loading