55Add ` func config ci --github ` command to generate GitHub Actions workflow files for function deployment.
66
77** Workflow contains:**
8+
89- Checkout code
910- Setup func CLI (using knative-func-action)
1011- Optional test step (language-specific)
1112- Deploy using ` func deploy ` (local) or ` func deploy --remote ` (remote)
1213
1314** Build modes:**
15+
1416- Local build (default): Builds in GitHub runner, deploys to cluster
1517- Remote build (--remote): Build and deploy on-cluster
1618
@@ -25,10 +27,10 @@ Add `func config ci --github` command to generate GitHub Actions workflow files
2527 - ✅ Generates workflow with: checkout → setup func → test → deploy
2628 - ✅ Triggers on push to ` main ` branch (default)
2729 - ✅ Runs on ` ubuntu-latest `
28- - ✅ File named ` deploy -local.yaml`
30+ - ✅ File named ` build -local-deploy-remote .yaml`
2931
30323 . ** Remote Build Mode**
31- - ✅ ` --remote ` flag generates ` deploy-remote.yaml `
33+ - ✅ ` --remote ` flag generates ` build-and- deploy-remote.yaml`
3234 - ✅ Uses ` func deploy --remote `
3335 - ✅ Includes cluster auth configuration (defaults initially)
3436
@@ -44,7 +46,7 @@ Add `func config ci --github` command to generate GitHub Actions workflow files
4446
4547## Key Decisions
4648
47- - ** Workflow naming:** ` deploy -local.yaml` and ` deploy-remote.yaml `
49+ - ** Workflow naming:** ` build -local-deploy-remote .yaml` and ` build-and- deploy-remote.yaml`
4850- ** Default branch:** ` main `
4951- ** Event triggers:** ` push ` first, ` pull_request ` later, workflow_dispatch later
5052- ** Runtime priority:** Go → Python → others
@@ -60,118 +62,136 @@ Add `func config ci --github` command to generate GitHub Actions workflow files
6062
6163### Phase 1: Test Infrastructure & Basic Command Structure
6264
63- ** Step 1.1: Command skeleton**
65+ #### Step 1.1: Command skeleton
6466
6567Test Cases:
68+
6669- ` TestNewConfigCICmd_CommandExists ` - Command wired up correctly
6770- ` TestNewConfigCICmd_FailsWhenNotInitialized ` - Fail when not in function dir
6871- ` TestConfigCI_RequiresGithubFlag ` - --github flag required initially
6972
7073Implementation:
74+
7175- Basic command structure with --github flag
7276- Function initialization check using functionLoader
7377- Error handling and fail fast
7478- Wire into config.go
7579
76- ** Refactor:**
80+ Refactor:
81+
7782- Extract common patterns
7883- Consistent error messaging
7984
8085---
8186
8287### Phase 2: Workflow File Generation - Local Build
8388
84- ** Step 2.1: Directory and file creation**
89+ #### Step 2.1: Directory and file creation
8590
8691Test Cases:
92+
8793- ` TestConfigCI_GitHub_CreatesWorkflowDirectory ` - Creates .github/workflows/
88- - ` TestConfigCI_GitHub_GeneratesLocalWorkflowFile ` - Creates deploy -local.yaml
94+ - ` TestConfigCI_GitHub_GeneratesLocalWorkflowFile ` - Creates build -local-deploy-remote .yaml
8995- ` TestConfigCI_GitHub_LocalWorkflow_HasCorrectStructure ` - Valid YAML structure
9096
9197Implementation:
98+
9299- Create workflow template (embedded or separate package)
93100- Directory creation logic
94101- File writing logic
95102- Basic YAML: checkout → setup func → deploy
96103
97- ** Refactor:**
104+ Refactor:
105+
98106- Extract template rendering
99107- Create workflow config struct
100108
101- ** Step 2.2: Go-specific workflow content**
109+ #### Step 2.2: Go-specific workflow content
102110
103111Test Cases:
112+
104113- ` TestConfigCI_GitHub_GoFunction_IncludesTestStep ` - Test step for Go
105114- ` TestConfigCI_GitHub_DefaultTrigger_PushToMain ` - Triggers on push to main
106115- ` TestConfigCI_GitHub_UsesUbuntuRunner ` - Runner is ubuntu-latest
107116- ` TestConfigCI_GitHub_IncludesClusterConfig ` - Cluster config placeholders
108117
109118Implementation:
119+
110120- Detect function runtime from Function struct
111121- Add conditional test step for Go
112122- Set default trigger: push on main
113123- Add cluster config (env vars/secrets placeholders)
114124
115125** Refactor:**
126+
116127- Runtime-specific customization logic
117128- Maintainable/extensible template
118129
119130---
120131
121132### Phase 3: Remote Build Support
122133
123- ** Step 3.1: Remote build flag**
134+ #### Step 3.1: Remote build flag
124135
125136Test Cases:
137+
126138- ` TestConfigCI_GitHub_Remote_GeneratesRemoteWorkflowFile ` - Creates deploy-remote.yaml
127139- ` TestConfigCI_GitHub_Remote_UsesRemoteDeployCommand ` - Uses func deploy --remote
128140- ` TestConfigCI_GitHub_Remote_IncludesAuthConfig ` - Cluster auth config present
129141
130142Implementation:
143+
131144- Add --remote flag
132145- Template variation for remote builds
133146- Generate deploy-remote.yaml when --remote set
134147- Remote-specific cluster auth setup
135148
136149** Refactor:**
150+
137151- Consolidate local/remote template logic
138152- Use conditionals or separate templates
139153
140154---
141155
142156### Phase 4: Configuration Options
143157
144- ** Step 4.1: Branch configuration**
158+ #### Step 4.1: Branch configuration
145159
146160Test Cases:
161+
147162- ` TestConfigCI_GitHub_CustomBranch_SetsTrigger ` - --branch flag sets trigger branch
148163- ` TestConfigCI_GitHub_DefaultBranch_IsMain ` - Default is main
149164
150165Implementation:
166+
151167- Add --branch flag
152168- Use flag value in template
153169- Default to "main"
154170
155171** Refactor:**
172+
156173- Create configuration struct for all workflow options
157174
158175---
159176
160177### Phase 5: Collision Detection & Error Handling
161178
162- ** Step 5.1: Existing workflow detection**
179+ #### Step 5.1: Existing workflow detection
163180
164181Test Cases:
182+
165183- ` TestConfigCI_GitHub_Local_FailsWhenFileExists ` - Fails if deploy-local.yaml exists
166- - ` TestConfigCI_GitHub_Remote_FailsWhenFileExists ` - Fails if deploy-remote.yaml exists
184+ - ` TestConfigCI_GitHub_Remote_FailsWhenFileExists ` - Fails if build-and- deploy-remote.yaml exists
167185- ` TestConfigCI_GitHub_ExistingWorkflow_ShowsHelpfulError ` - Helpful error message
168186
169187Implementation:
188+
170189- Check file existence before generation
171190- Return descriptive error on collision
172191- Suggest alternatives to user
173192
174193** Refactor:**
194+
175195- Extract file existence checking
176196- Improve error messaging
177197
@@ -181,53 +201,156 @@ Implementation:
181201
182202### ✅ Completed
183203
184- ** Phase 1: Test Infrastructure & Basic Command Structure** ✅
204+ #### Phase 1: Test Infrastructure & Basic Command Structure
205+
185206- Created ` cmd/common ` package for reusable loader/saver interfaces
186207- Created ` cmd/testing ` factory with ` CreateFuncInTempDir() ` helper
187- - Created ` cmd/config_ci.go ` with basic command structure
188- - Created ` cmd/config_ci_test.go ` with ` ciOpts ` struct pattern
189- - Wired command into ` cmd/config.go:74 `
190- - Tests passing (3/3):
191- - ` TestNewConfigCICmd_CommandExists `
192- - ` TestNewConfigCICmd_FailsWhenNotInitialized `
193- - ` TestNewConfigCICmd_SuccessWhenInitialized `
194- - Commit: ` bd22332f ` - feat: add config ci command and refactor interfaces
195-
196- ** Phase 2, Step 2.1: Workflow directory/file creation** ✅
208+ - Created [ cmd/config_ci.go] ( cmd/config_ci.go ) with comprehensive flag support
209+ - Created [ cmd/config_ci_test.go] ( cmd/config_ci_test.go ) with 10 passing tests
210+ - Wired command into ` cmd/config.go `
211+
212+ #### Phase 2: Workflow File Generation
213+
197214- Created YAML structure types: ` GithubWorkflow ` , ` WorkflowTriggers ` , ` PushTrigger ` , ` Job ` , ` Step `
198- - Implemented workflow generation with hardcoded values:
199- - Name: "Remote Build and Deploy"
200- - Trigger: push to main branch
201- - Runner: ubuntu-latest
202- - Steps: checkout → func cli setup → deploy --remote
203215- Created ` cmd/ci ` package for CI logic separation
204- - ` cmd/ci/config.go ` - CIConfig with path resolution methods
205- - ` cmd/ci/workflow.go ` - Workflow structs and generation logic
206- - Added ` NewGithubWorkflow(name) ` factory function
207- - Added ` PersistToDisk() ` function for file writing
208- - Tests passing (5/5):
209- - ` TestNewConfigCICmd_CreatesGithubWorkflowDirectory `
210- - ` TestNewConfigCICmd_GeneratesLocalWorkflowFile `
211- - ` TestNewConfigCICmd_WorkflowYAMLHasCorrectStructure `
212- - ` TestNewConfigCICmd_WorkflowYAMLHasCustomName `
213- - Plus 2 existing tests
214- - Commits:
215- - ` e4541136 ` - feat: generate github workflow for remote build
216- - ` d2c850fc ` - refactor: extract ci logic into dedicated package
217-
218- ### 🔄 In Progress
219-
220- ** Phase 2, Step 2.2: Go-specific workflow content**
221- - Next: Detect runtime and conditionally add test step for Go functions
222-
223- ### ⏳ Next Steps
224-
225- 1 . Complete Phase 2, Step 2.2 (4 tests for Go-specific content):
226- - Runtime detection from Function struct
227- - Conditional test step for Go
228- - Validate default triggers
229- - Cluster config placeholders
230- 2 . Begin Phase 3: Remote build support
216+ - [ cmd/ci/config.go] ( cmd/ci/config.go ) - CIConfig with builder pattern, flag reading via Cobra
217+ - [ cmd/ci/workflow.go] ( cmd/ci/workflow.go ) - Workflow generation with conditional steps
218+ - Workflow generation features:
219+ - Checkout → K8s context setup → Registry login (conditional) → func CLI install → Deploy
220+ - Kubernetes context setup using kubeconfig secret
221+ - Conditional registry authentication step
222+ - Conditional debug features (workflow_dispatch + CLI caching)
223+ - Deploy command varies based on build mode
224+ - Registry URL format changes based on login mode
225+
226+ #### Phase 3: Remote Build Support
227+
228+ - Implemented ` --remote ` flag to switch between local/remote builds
229+ - Remote build: ` func deploy --remote ` (builds on cluster with Tekton)
230+ - Local build (default): ` func deploy ` (builds in GitHub runner with Docker)
231+ - Workflow name auto-adjusts: "Func Deploy" vs "Remote Func Deploy"
232+
233+ #### Phase 4: Configuration Options
234+
235+ ** Implemented flags:**
236+
237+ - ` --github ` - Enable GitHub Actions workflow generation
238+ - ` --workflow-name <name> ` - Custom workflow name (default: "Func Deploy")
239+ - ` --branch <name> ` - Customize trigger branch (default: "main")
240+ - ` --remote ` - Use remote build on cluster (default: false)
241+ - ` --self-hosted-runner ` - Use self-hosted runner instead of ubuntu-latest
242+ - ` --use-registry-login ` - Include docker/login-action step (default: true)
243+ - ` --debug ` - Add workflow_dispatch trigger + func CLI caching for fast iterations
244+ - ` --kubeconfig-secret-name <name> ` - Custom kubeconfig secret name (default: "KUBECONFIG")
245+ - ` --registry-login-url-variable-name <name> ` - Custom registry login URL variable (default: "REGISTRY_LOGIN_URL")
246+ - ` --registry-user-variable-name <name> ` - Custom registry user variable (default: "REGISTRY_USERNAME")
247+ - ` --registry-pass-secret-name <name> ` - Custom registry password secret (default: "REGISTRY_PASSWORD")
248+ - ` --registry-url-variable-name <name> ` - Custom registry URL variable for no-login mode (default: "REGISTRY_URL")
249+
250+ ** Registry URL behavior:**
251+
252+ - With ` --use-registry-login=true ` : ` --registry=${{ vars.REGISTRY_LOGIN_URL }}/${{ vars.REGISTRY_USERNAME }} `
253+ - With ` --use-registry-login=false ` : ` --registry=${{ vars.REGISTRY_URL }} `
254+
255+ #### Phase 4 (continued): Feature Flag Support
256+
257+ ** Implementation:**
258+
259+ - Added ` ConfigCIFeatureFlag ` constant in [ cmd/config_ci.go:86] ( cmd/config_ci.go#L86 )
260+ - Feature flag check in ` runConfigCIGithub() ` (line 92-94)
261+ - Environment variable: ` FUNC_ENABLE_CI_CONFIG=true `
262+ - Error message: "Set FUNC_ENABLE_CI_CONFIG to 'true' to use this feature"
263+ - Test helper ` defaultOpts() ` for common test setup
264+ - Refactored test assertions into helper functions
265+
266+ #### Test Coverage
267+
268+ All 11 tests passing:
269+
270+ - ` TestNewConfigCICmd_RequiresFeatureFlag ` - ** NEW** - Tests feature flag enforcement
271+ - ` TestNewConfigCICmd_CISubcommandAndGithubOptionExist `
272+ - ` TestNewConfigCICmd_FailsWhenNotInitialized `
273+ - ` TestNewConfigCICmd_SuccessWhenInitialized `
274+ - ` TestNewConfigCICmd_CreatesGithubWorkflowDirectory `
275+ - ` TestNewConfigCICmd_GeneratesWorkflowFile `
276+ - ` TestNewConfigCICmd_WorkflowYAMLHasCorrectStructure `
277+ - ` TestNewConfigCICmd_WorkflowYAMLHasCustomValues ` - Tests custom branch, secret/var names, self-hosted
278+ - ` TestNewConfigCICmd_WorkflowHasNoRegistryLogin ` - Tests ` --use-registry-login=false `
279+ - ` TestNewConfigCICmd_RemoteBuildAndDeployWorkflow ` - Tests ` --remote ` flag
280+ - ` TestNewConfigCICmd_HasWorkflowDispatchAndCacheInDebugMode ` - Tests ` --debug ` flag
281+
282+ #### Recent Commits
283+
284+ - ` a231cc9d ` - feat: add flags for all configurable parameters
285+ - ` 4d6cd5d1 ` - refactor: distinguish secrets from vars in CI
286+ - ` fd6bc843 ` - refactor: move ci config to command flags
287+ - ` 1465082a ` - feat: add local build workflow and debug options
288+
289+ ### 🔜 Next Steps
290+
291+ #### Phase 4 (continued): Additional Configuration Options
292+
293+ ** Verbose Logging (Do Now):**
294+
295+ - Add progress messages with ` -v ` flag
296+ - Log: "Generating workflow...", "Writing to file...", "Complete"
297+ - Use existing ` func ` CLI logging infrastructure
298+ - Test: ` TestNewConfigCICmd_VerboseOutput `
299+
300+ ** Path Flag Support (After Phase 5):**
301+
302+ - Support ` --path ` flag to specify function directory
303+ - Use provided path instead of CWD
304+ - Validate path points to initialized function
305+ - Test: ` TestNewConfigCICmd_CustomPath `
306+
307+ #### Phase 5: Collision Detection & Error Handling
308+
309+ ** Objective:** Prevent accidental overwrites and provide helpful error messages
310+
311+ ** Test Cases:**
312+
313+ - ` TestNewConfigCICmd_FailsWhenFileExists ` - Fails if workflow file already exists
314+ - ` TestNewConfigCICmd_ExistingWorkflow_ShowsHelpfulError ` - Returns descriptive error with suggestions
315+
316+ ** Implementation:**
317+
318+ 1 . Check if workflow file exists before generation in [ cmd/ci/workflow.go] ( cmd/ci/workflow.go )
319+ 2 . Return error with suggestions:
320+ - Delete existing file manually
321+ - Use different workflow name with ` --workflow-name `
322+ - Generate to different directory
323+ 3 . Update ` Persist() ` method to check file existence
324+
325+ ** Acceptance:** Command fails gracefully when workflow already exists, preventing data loss
326+
327+ #### Phase 6: Runtime Detection & Test Steps (Later)
328+
329+ ** Objective:** Add language-specific test steps to workflow
330+
331+ ** Implementation:**
332+
333+ 1 . Read ` Function.Runtime ` from function config
334+ 2 . Add conditional test step based on runtime:
335+ - Go: ` go test ./... `
336+ - Python: ` pytest `
337+ - Node: ` npm test `
338+ 3 . Skip test step if runtime not supported
339+
340+ ** Test Cases:**
341+
342+ - ` TestNewConfigCICmd_GoFunction_IncludesTestStep `
343+ - ` TestNewConfigCICmd_PythonFunction_IncludesTestStep `
344+ - ` TestNewConfigCICmd_UnsupportedRuntime_NoTestStep `
345+
346+ ** Acceptance:** Generated workflows include appropriate test commands for supported runtimes
347+
348+ ### ⏳ Optional Future Enhancements (Not Required)
349+
350+ - Support for ` pull_request ` event triggers
351+ - Support for multiple concurrent workflows (local + remote)
352+ - Interactive mode with prompts for missing configuration
353+ - ` --force ` flag to allow overwriting existing workflows
231354
232355---
233356
0 commit comments