Add private frontmatter field to block add command#17801
Conversation
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
private frontmatter field to block add command
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR adds a private frontmatter field to prevent workflows from being shared across repositories via the gh aw add command. When a workflow is marked with private: true, attempting to add it to another repository will result in an error.
Changes:
- Added
Privatefield toFrontmatterConfigstruct as a pointer type (consistent withStrictfield) - Implemented
ExtractWorkflowPrivatehelper function to extract the private field from workflow frontmatter - Added validation in
ResolveWorkflowsto reject workflows withprivate: true - Updated JSON schema, editor autocomplete data, and regenerated reference documentation
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/workflow/frontmatter_types.go | Added Private field to FrontmatterConfig struct |
| pkg/parser/schemas/main_workflow_schema.json | Added private field definition to JSON schema |
| pkg/cli/packages.go | Implemented ExtractWorkflowPrivate helper function |
| pkg/cli/add_workflow_resolution.go | Added private workflow validation and IsPrivate field to ResolvedWorkflow |
| pkg/cli/add_private_test.go | Added unit tests for ExtractWorkflowPrivate function |
| docs/public/editor/autocomplete-data.json | Added private field to editor autocomplete data |
| docs/src/content/docs/reference/frontmatter-full.md | Regenerated documentation to include private field and other schema updates |
Comments suppressed due to low confidence (1)
pkg/cli/add_workflow_resolution.go:150
- The
IsPrivatefield is set but never used. Since the function returns early on line 134 when a workflow is private, this field will always befalsein any ResolvedWorkflow that is successfully created. Consider removing this field from the ResolvedWorkflow struct since it serves no purpose.
IsPrivate: isPrivate,
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| // Check if workflow is private - private workflows cannot be added to other repositories | ||
| isPrivate := ExtractWorkflowPrivate(string(fetched.Content)) | ||
| if isPrivate { |
There was a problem hiding this comment.
The private check blocks local workflows from being added to the current repository. Lines 78-93 show that workflows from the current repository are intentionally allowed when they are local file paths. However, the private check on line 133 applies to all workflows, including local ones. This means a user with a private workflow file on their local filesystem cannot add it to their own repository, which seems overly restrictive. The private field should only prevent sharing workflows with other repositories, not prevent local use. Consider skipping the private check for local workflows by checking spec.IsLocal or using isLocalWorkflowPath(spec.WorkflowPath) before the private check.
| if isPrivate { | |
| if isPrivate && !spec.IsLocal { |
| //go:build !integration | ||
|
|
||
| package cli | ||
|
|
||
| import ( | ||
| "testing" | ||
| ) | ||
|
|
||
| // TestExtractWorkflowPrivate tests the ExtractWorkflowPrivate function | ||
| func TestExtractWorkflowPrivate(t *testing.T) { | ||
| tests := []struct { | ||
| name string | ||
| content string | ||
| expected bool | ||
| }{ | ||
| { | ||
| name: "workflow with private: true", | ||
| content: `--- | ||
| name: Test Workflow | ||
| private: true | ||
| on: push | ||
| --- | ||
|
|
||
| # Test Workflow`, | ||
| expected: true, | ||
| }, | ||
| { | ||
| name: "workflow with private: false", | ||
| content: `--- | ||
| name: Test Workflow | ||
| private: false | ||
| on: push | ||
| --- | ||
|
|
||
| # Test Workflow`, | ||
| expected: false, | ||
| }, | ||
| { | ||
| name: "workflow without private field", | ||
| content: `--- | ||
| name: Test Workflow | ||
| on: push | ||
| --- | ||
|
|
||
| # Test Workflow`, | ||
| expected: false, | ||
| }, | ||
| { | ||
| name: "workflow without frontmatter", | ||
| content: "# Test Workflow\n\nThis is the workflow content.", | ||
| expected: false, | ||
| }, | ||
| } | ||
|
|
||
| for _, tt := range tests { | ||
| t.Run(tt.name, func(t *testing.T) { | ||
| result := ExtractWorkflowPrivate(tt.content) | ||
| if result != tt.expected { | ||
| t.Errorf("ExtractWorkflowPrivate() = %v, want %v", result, tt.expected) | ||
| } | ||
| }) | ||
| } | ||
| } |
There was a problem hiding this comment.
The test file only covers the ExtractWorkflowPrivate function but doesn't test the actual blocking behavior in ResolveWorkflows. Consider adding an integration test that verifies a workflow with private: true is properly rejected when attempting to resolve it for adding to another repository. This would ensure the end-to-end functionality works as expected.
| // IsPrivate indicates if the workflow has private: true in its frontmatter | ||
| IsPrivate bool |
There was a problem hiding this comment.
Since the ResolveWorkflows function returns an error when encountering a private workflow (line 134 in add_workflow_resolution.go), the IsPrivate field will always be false for any successfully resolved workflow. This field serves no purpose and should be removed to avoid confusion.
This issue also appears on line 150 of the same file.
| // IsPrivate indicates if the workflow has private: true in its frontmatter | |
| IsPrivate bool |
Documents the new `private: true` frontmatter field that prevents workflows from being installed into other repositories via `gh aw add`. - Adds Private Workflows section to frontmatter reference - Adds note about private workflows to the packaging/imports guide Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Workflows marked
private: trueshould not be installable into other repositories viagh aw add. This adds that enforcement.Changes
FrontmatterConfig(pkg/workflow/frontmatter_types.go): NewPrivate *boolfield (pointer, consistent withStrict *bool)ExtractWorkflowPrivate(pkg/cli/packages.go): Helper to read theprivatefield from frontmatter, following the same pattern asExtractWorkflowDescription/ExtractWorkflowEngineResolveWorkflows(pkg/cli/add_workflow_resolution.go): Returns an error early if a resolved workflow hasprivate: true; also tracksIsPrivateonResolvedWorkflowpkg/parser/schemas/main_workflow_schema.json): Addedprivatefield definition with type, default, and descriptiondocs/public/editor/autocomplete-data.json): Addedprivateto the autocomplete data for editor supportdocs/src/content/docs/reference/frontmatter-full.md): Regenerated to include theprivatefieldUsage
Attempting to
gh aw addthis workflow from another repo:Original prompt
🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.