campaign

package
v0.33.12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 22, 2025 License: MIT Imports: 23 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildOrchestrator

func BuildOrchestrator(spec *CampaignSpec, campaignFilePath string) (*workflow.WorkflowData, string)

BuildOrchestrator constructs a minimal agentic workflow representation for a given CampaignSpec. The resulting WorkflowData is compiled via the standard CompileWorkflowDataWithValidation pipeline, and the orchestratorPath determines the emitted .lock.yml name.

func ComputeCompiledState

func ComputeCompiledState(spec CampaignSpec, workflowsDir string) string

ComputeCompiledState inspects the compiled state of all workflows referenced by a campaign. It returns:

"Yes"   - all referenced workflows exist and are compiled & up-to-date
"No"    - at least one workflow exists but is missing a lock file or is stale
"Missing workflow" - at least one referenced workflow markdown file does not exist
"N/A"   - campaign does not reference any workflows

func CreateSpecSkeleton

func CreateSpecSkeleton(rootDir, id string, force bool) (string, error)

CreateSpecSkeleton creates a new campaign spec YAML file under .github/workflows/ with a minimal skeleton definition. It returns the relative file path created.

func FetchCursorFreshnessFromRepoMemory added in v0.33.10

func FetchCursorFreshnessFromRepoMemory(cursorGlob string) (cursorPath string, cursorUpdatedAt string)

FetchCursorFreshnessFromRepoMemory finds the latest cursor/checkpoint file matching cursorGlob in the memory/campaigns branch and returns the matched path along with a best-effort freshness timestamp derived from git history.

Errors are treated as "no cursor" rather than failing the command.

func FetchItemCounts

func FetchItemCounts(trackerLabel string) (issuesOpen, issuesClosed, prsOpen, prsMerged int)

FetchItemCounts uses gh CLI (via workflow.ExecGH) to fetch basic counts of issues and pull requests tagged with the given tracker label.

If trackerLabel is empty or any errors occur, it falls back to zeros and logs at debug level instead of failing the command.

func NewCommand

func NewCommand() *cobra.Command

NewCommand creates the `gh aw campaign` command that surfaces first-class campaign definitions from YAML files.

func RenderClosingInstructions added in v0.33.2

func RenderClosingInstructions() string

RenderClosingInstructions renders the closing instructions

func RenderOrchestratorInstructions added in v0.33.2

func RenderOrchestratorInstructions(data CampaignPromptData) string

RenderOrchestratorInstructions renders the orchestrator instructions with the given data

func RenderProjectUpdateInstructions added in v0.33.2

func RenderProjectUpdateInstructions(data CampaignPromptData) string

RenderProjectUpdateInstructions renders the project update instructions with the given data

func ValidateSpec

func ValidateSpec(spec *CampaignSpec) []string

ValidateSpec performs lightweight semantic validation of a single CampaignSpec and returns a slice of human-readable problems.

It uses JSON schema validation first, then adds additional semantic checks.

func ValidateSpecWithSchema

func ValidateSpecWithSchema(spec *CampaignSpec) []string

ValidateSpecWithSchema validates a CampaignSpec against the JSON schema. Returns a list of validation error messages, or an empty list if valid.

func ValidateWorkflowsExist

func ValidateWorkflowsExist(spec *CampaignSpec, workflowsDir string) []string

ValidateWorkflowsExist checks that all workflows referenced in a campaign spec actually exist in the .github/workflows directory. Returns a list of problems for workflows that don't exist.

Types

type CampaignApprovalPolicy

type CampaignApprovalPolicy struct {
	RequiredApprovals int      `yaml:"required-approvals,omitempty" json:"required-approvals,omitempty"`
	RequiredRoles     []string `yaml:"required-roles,omitempty" json:"required-roles,omitempty"`
	ChangeControl     bool     `yaml:"change-control,omitempty" json:"change-control,omitempty"`
}

CampaignApprovalPolicy captures basic approval expectations for a campaign. It is intentionally lightweight and advisory; enforcement is left to workflows and organizational process.

type CampaignGovernancePolicy added in v0.33.10

type CampaignGovernancePolicy struct {
	// MaxNewItemsPerRun caps how many new items (issues/PRs) the launcher should
	// add to the Project board per run. 0 means "use defaults".
	MaxNewItemsPerRun int `yaml:"max-new-items-per-run,omitempty" json:"max_new_items_per_run,omitempty"`

	// MaxDiscoveryItemsPerRun caps how many candidate issues/PRs the launcher
	// and orchestrator may scan during discovery in a single run.
	// 0 means "use defaults".
	MaxDiscoveryItemsPerRun int `yaml:"max-discovery-items-per-run,omitempty" json:"max_discovery_items_per_run,omitempty"`

	// MaxDiscoveryPagesPerRun caps how many pages of results the launcher and
	// orchestrator may fetch in a single run.
	// 0 means "use defaults".
	MaxDiscoveryPagesPerRun int `yaml:"max-discovery-pages-per-run,omitempty" json:"max_discovery_pages_per_run,omitempty"`

	// OptOutLabels is a list of labels that opt an issue/PR out of campaign
	// tracking. Items with any of these labels should be ignored by launcher/
	// orchestrator.
	OptOutLabels []string `yaml:"opt-out-labels,omitempty" json:"opt_out_labels,omitempty"`

	// DoNotDowngradeDoneItems prevents moving Project status backwards (e.g.
	// Done -> In Progress) if the underlying issue/PR is reopened.
	DoNotDowngradeDoneItems *bool `yaml:"do-not-downgrade-done-items,omitempty" json:"do_not_downgrade_done_items,omitempty"`

	// MaxProjectUpdatesPerRun controls the update-project safe-output maximum
	// for generated coordinator workflows. 0 means "use defaults".
	MaxProjectUpdatesPerRun int `yaml:"max-project-updates-per-run,omitempty" json:"max_project_updates_per_run,omitempty"`

	// MaxCommentsPerRun controls the add-comment safe-output maximum for
	// generated coordinator workflows. 0 means "use defaults".
	MaxCommentsPerRun int `yaml:"max-comments-per-run,omitempty" json:"max_comments_per_run,omitempty"`
}

CampaignGovernancePolicy captures lightweight pacing and opt-out policies. This is intentionally scoped to what gh-aw can apply safely and consistently via prompts and safe-output job limits.

type CampaignMetricsSnapshot

type CampaignMetricsSnapshot struct {
	Date                string  `json:"date,omitempty"`
	CampaignID          string  `json:"campaign_id,omitempty"`
	TasksTotal          int     `json:"tasks_total,omitempty"`
	TasksCompleted      int     `json:"tasks_completed,omitempty"`
	TasksInProgress     int     `json:"tasks_in_progress,omitempty"`
	TasksBlocked        int     `json:"tasks_blocked,omitempty"`
	VelocityPerDay      float64 `json:"velocity_per_day,omitempty"`
	EstimatedCompletion string  `json:"estimated_completion,omitempty"`
}

CampaignMetricsSnapshot describes the JSON structure used by campaign metrics snapshots written into the memory/campaigns branch.

This mirrors the example in the campaigns guide:

{
  "date": "2025-01-16",
  "campaign_id": "security-q1-2025",
  "tasks_total": 200,
  "tasks_completed": 15,
  "tasks_in_progress": 30,
  "tasks_blocked": 5,
  "velocity_per_day": 7.5,
  "estimated_completion": "2025-02-12"
}

func FetchMetricsFromRepoMemory

func FetchMetricsFromRepoMemory(metricsGlob string) (*CampaignMetricsSnapshot, error)

FetchMetricsFromRepoMemory attempts to load the latest JSON metrics snapshot matching the provided glob from the memory/campaigns branch. It is best-effort: errors are logged and treated as "no metrics" rather than failing the command.

type CampaignPromptData added in v0.33.2

type CampaignPromptData struct {
	// ProjectURL is the GitHub Project URL
	ProjectURL string

	// TrackerLabel is the label used to associate issues/PRs with this campaign.
	TrackerLabel string

	// CursorGlob is a glob for locating the durable cursor/checkpoint file in repo-memory.
	CursorGlob string

	// MaxDiscoveryItemsPerRun caps how many candidate items may be scanned during discovery.
	MaxDiscoveryItemsPerRun int

	// MaxDiscoveryPagesPerRun caps how many pages may be fetched during discovery.
	MaxDiscoveryPagesPerRun int
}

CampaignPromptData holds data for rendering campaign orchestrator prompts

type CampaignRuntimeStatus

type CampaignRuntimeStatus struct {
	ID           string   `json:"id" console:"header:ID"`
	Name         string   `json:"name" console:"header:Name"`
	TrackerLabel string   `json:"tracker_label,omitempty" console:"header:Tracker Label,omitempty"`
	Workflows    []string `json:"workflows,omitempty" console:"header:Workflows,omitempty"`
	Compiled     string   `json:"compiled" console:"header:Compiled"`

	IssuesOpen   int `json:"issues_open,omitempty" console:"header:Issues Open,omitempty"`
	IssuesClosed int `json:"issues_closed,omitempty" console:"header:Issues Closed,omitempty"`
	PRsOpen      int `json:"prs_open,omitempty" console:"header:PRs Open,omitempty"`
	PRsMerged    int `json:"prs_merged,omitempty" console:"header:PRs Merged,omitempty"`

	// Optional metrics from repo-memory (when MetricsGlob is set and a
	// matching JSON snapshot is found on the memory/campaigns branch).
	MetricsTasksTotal          int     `json:"metrics_tasks_total,omitempty" console:"header:Tasks Total,omitempty"`
	MetricsTasksCompleted      int     `json:"metrics_tasks_completed,omitempty" console:"header:Tasks Completed,omitempty"`
	MetricsVelocityPerDay      float64 `json:"metrics_velocity_per_day,omitempty" console:"header:Velocity/Day,omitempty"`
	MetricsEstimatedCompletion string  `json:"metrics_estimated_completion,omitempty" console:"header:ETA,omitempty"`

	// Optional durable cursor/checkpoint info from repo-memory.
	CursorPath      string `json:"cursor_path,omitempty" console:"header:Cursor Path,omitempty,maxlen:40"`
	CursorUpdatedAt string `json:"cursor_updated_at,omitempty" console:"header:Cursor Updated,omitempty,maxlen:30"`
}

CampaignRuntimeStatus represents the live status of a campaign, including compiled workflow state and basic issue/PR counts derived from the tracker label.

func BuildRuntimeStatus

func BuildRuntimeStatus(spec CampaignSpec, workflowsDir string) CampaignRuntimeStatus

BuildRuntimeStatus builds a CampaignRuntimeStatus for a single campaign spec.

type CampaignSpec

type CampaignSpec struct {
	ID          string `yaml:"id" json:"id" console:"header:ID"`
	Name        string `yaml:"name" json:"name" console:"header:Name,maxlen:30"`
	Description string `yaml:"description,omitempty" json:"description,omitempty" console:"header:Description,omitempty,maxlen:60"`

	// ProjectURL points to the GitHub Project used as the primary campaign
	// dashboard.
	ProjectURL string `yaml:"project-url,omitempty" json:"project_url,omitempty" console:"header:Project URL,omitempty,maxlen:40"`

	// Version is an optional spec version string (for example: v1).
	// When omitted, it defaults to v1 during validation.
	Version string `yaml:"version,omitempty" json:"version,omitempty" console:"header:Version,omitempty"`

	// Workflows associates this campaign with one or more workflow IDs
	// (basename of the Markdown file without .md).
	Workflows []string `yaml:"workflows,omitempty" json:"workflows,omitempty" console:"header:Workflows,omitempty,maxlen:40"`

	// MemoryPaths documents where this campaign writes its repo-memory
	// (for example: memory/campaigns/incident-*/**).
	MemoryPaths []string `yaml:"memory-paths,omitempty" json:"memory_paths,omitempty" console:"header:Memory Paths,omitempty,maxlen:40"`

	// MetricsGlob is an optional glob (relative to the repository root)
	// used to locate JSON metrics snapshots stored in the
	// memory/campaigns branch. When set, `gh aw campaign status` will
	// attempt to read the latest matching metrics file and surface a few
	// key fields.
	MetricsGlob string `yaml:"metrics-glob,omitempty" json:"metrics_glob,omitempty" console:"header:Metrics Glob,omitempty,maxlen:30"`

	// CursorGlob is an optional glob (relative to the repository root)
	// used to locate a durable cursor/checkpoint file stored in the
	// memory/campaigns branch. When set, generated coordinator workflows
	// will be instructed to continue incremental discovery from this cursor
	// and `gh aw campaign status` will surface its freshness.
	CursorGlob string `yaml:"cursor-glob,omitempty" json:"cursor_glob,omitempty" console:"header:Cursor Glob,omitempty,maxlen:30"`

	// Owners lists the primary human owners for this campaign.
	Owners []string `yaml:"owners,omitempty" json:"owners,omitempty" console:"header:Owners,omitempty,maxlen:30"`

	// ExecutiveSponsors lists executive stakeholders or sponsors who are
	// accountable for the outcome of this campaign.
	ExecutiveSponsors []string `` /* 127-byte string literal not displayed */

	// RiskLevel is an optional free-form field (e.g. low/medium/high).
	RiskLevel string `yaml:"risk-level,omitempty" json:"risk_level,omitempty" console:"header:Risk Level,omitempty"`

	// TrackerLabel describes the label used to associate issues/PRs with
	// this campaign (for example: campaign:incident-response).
	TrackerLabel string `yaml:"tracker-label,omitempty" json:"tracker_label,omitempty" console:"header:Tracker Label,omitempty"`

	// State describes the lifecycle stage of the campaign definition.
	// Valid values are: planned, active, paused, completed, archived.
	State string `yaml:"state,omitempty" json:"state,omitempty" console:"header:State,omitempty"`

	// Tags provide free-form categorization for reporting (for example:
	// security, modernization, rollout).
	Tags []string `yaml:"tags,omitempty" json:"tags,omitempty" console:"header:Tags,omitempty,maxlen:30"`

	// AllowedSafeOutputs documents which safe-outputs operations this
	// campaign is expected to use (for example: create-issue,
	// create-pull-request). This is currently informational but can be
	// enforced by validation in the future.
	AllowedSafeOutputs []string `` /* 133-byte string literal not displayed */

	// ProjectGitHubToken is an optional GitHub token expression (e.g.,
	// ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}) used for GitHub Projects v2
	// operations. When specified, this token is passed to the update-project
	// safe output configuration in the generated orchestrator workflow.
	ProjectGitHubToken string `` /* 126-byte string literal not displayed */

	// Governance configures lightweight pacing and opt-out policies for campaign
	// orchestrator workflows. These guardrails are primarily enforced through
	// generated prompts and safe-output maxima.
	Governance *CampaignGovernancePolicy `yaml:"governance,omitempty" json:"governance,omitempty"`

	// ApprovalPolicy describes high-level approval expectations for this
	// campaign (for example: number of approvals and required roles).
	ApprovalPolicy *CampaignApprovalPolicy `yaml:"approval-policy,omitempty" json:"approval-policy,omitempty"`

	// ConfigPath is populated at load time with the relative path of
	// the YAML file on disk, to help users locate definitions.
	ConfigPath string `yaml:"-" json:"config_path" console:"header:Config Path,maxlen:60"`
}

CampaignSpec defines a first-class campaign configuration loaded from YAML frontmatter in Markdown files.

Files are discovered from the local repository under:

.github/workflows/*.campaign.md

This provides a thin, declarative layer on top of existing agentic workflows and repo-memory conventions.

func FilterSpecs

func FilterSpecs(specs []CampaignSpec, pattern string) []CampaignSpec

FilterSpecs filters campaigns by a simple substring match on ID or Name (case-insensitive). When pattern is empty, all campaigns are returned.

func LoadSpecs

func LoadSpecs(rootDir string) ([]CampaignSpec, error)

LoadSpecs scans the repository for campaign spec files and returns a slice of CampaignSpec. Campaign specs are stored as .campaign.md files in .github/workflows/. If the workflows directory does not exist, it returns an empty slice and no error.

func ValidateSpecFromFile

func ValidateSpecFromFile(filePath string) (*CampaignSpec, []string, error)

ValidateSpecFromFile validates a campaign spec file by loading and validating it. This is useful for validation commands that operate on files directly.

type CampaignValidationResult

type CampaignValidationResult struct {
	ID         string   `json:"id" console:"header:ID"`
	Name       string   `json:"name" console:"header:Name"`
	ConfigPath string   `json:"config_path" console:"header:Config Path"`
	Problems   []string `json:"problems,omitempty" console:"header:Problems,omitempty"`
}

CampaignValidationResult represents the result of validating a campaign spec.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL