From 311eb9641035cb286a64d16014647b73f851209e Mon Sep 17 00:00:00 2001 From: Virgil Date: Thu, 2 Apr 2026 03:12:19 +0000 Subject: [PATCH] feat(build): add workflow output short aliases Co-Authored-By: Virgil --- cmd/build/cmd_workflow.go | 44 +++++++++++++-------- cmd/build/cmd_workflow_test.go | 30 ++++++++++---- pkg/api/provider.go | 12 ++++++ pkg/api/provider_test.go | 71 ++++++++++++++++++++++++++++++++++ pkg/api/ui/dist/core-build.js | 2 +- pkg/build/workflow.go | 36 +++++++++++++---- pkg/build/workflow_test.go | 32 ++++++++++----- ui/src/build-release.ts | 4 ++ ui/src/shared/api.ts | 2 + 9 files changed, 191 insertions(+), 42 deletions(-) diff --git a/cmd/build/cmd_workflow.go b/cmd/build/cmd_workflow.go index e560c2b..2409ab3 100644 --- a/cmd/build/cmd_workflow.go +++ b/cmd/build/cmd_workflow.go @@ -14,17 +14,19 @@ import ( ) var ( - releaseWorkflowPathInput string - releaseWorkflowPathAliasInput string - releaseWorkflowPathHyphenAliasInput string - releaseWorkflowPathSnakeAliasInput string - releaseWorkflowOutputPathHyphenInput string - releaseWorkflowOutputPathSnakeInput string - releaseWorkflowOutputPathInput string - releaseWorkflowOutputLegacyInput string - releaseWorkflowOutputPathAliasInput string - releaseWorkflowOutputPathHyphenAliasInput string - releaseWorkflowOutputPathSnakeAliasInput string + releaseWorkflowPathInput string + releaseWorkflowPathAliasInput string + releaseWorkflowPathHyphenAliasInput string + releaseWorkflowPathSnakeAliasInput string + releaseWorkflowOutputPathHyphenInput string + releaseWorkflowOutputPathSnakeInput string + releaseWorkflowOutputPathInput string + releaseWorkflowOutputLegacyInput string + releaseWorkflowOutputPathAliasInput string + releaseWorkflowOutputPathHyphenAliasInput string + releaseWorkflowOutputPathSnakeAliasInput string + releaseWorkflowWorkflowOutputHyphenAliasInput string + releaseWorkflowWorkflowOutputSnakeAliasInput string ) // releaseWorkflowInputs keeps the workflow alias inputs grouped by meaning @@ -39,6 +41,8 @@ type releaseWorkflowInputs struct { outputPathSnakeInput string legacyOutputInput string workflowOutputPathInput string + workflowOutputHyphenInput string + workflowOutputSnakeInput string workflowOutputPathHyphenInput string workflowOutputPathSnakeInput string } @@ -67,8 +71,10 @@ func (inputs releaseWorkflowInputs) resolvedWorkflowTargetPath(projectDir string inputs.outputPathSnakeInput, inputs.legacyOutputInput, inputs.workflowOutputPathInput, - inputs.workflowOutputPathHyphenInput, + inputs.workflowOutputSnakeInput, + inputs.workflowOutputHyphenInput, inputs.workflowOutputPathSnakeInput, + inputs.workflowOutputPathHyphenInput, ) if err != nil { return "", err @@ -90,6 +96,8 @@ var releaseWorkflowCmd = &cli.Command{ outputPathSnakeInput: releaseWorkflowOutputPathSnakeInput, legacyOutputInput: releaseWorkflowOutputLegacyInput, workflowOutputPathInput: releaseWorkflowOutputPathAliasInput, + workflowOutputHyphenInput: releaseWorkflowWorkflowOutputHyphenAliasInput, + workflowOutputSnakeInput: releaseWorkflowWorkflowOutputSnakeAliasInput, workflowOutputPathHyphenInput: releaseWorkflowOutputPathHyphenAliasInput, workflowOutputPathSnakeInput: releaseWorkflowOutputPathSnakeAliasInput, }) @@ -113,8 +121,8 @@ func initWorkflowFlags() { releaseWorkflowCmd.Flags().StringVar(&releaseWorkflowOutputPathAliasInput, "workflowOutputPath", "", i18n.T("cmd.build.workflow.flag.workflow_output_path")) releaseWorkflowCmd.Flags().StringVar(&releaseWorkflowOutputPathHyphenAliasInput, "workflow-output-path", "", i18n.T("cmd.build.workflow.flag.workflow_output_path")) releaseWorkflowCmd.Flags().StringVar(&releaseWorkflowOutputPathSnakeAliasInput, "workflow_output_path", "", i18n.T("cmd.build.workflow.flag.workflow_output_path")) - releaseWorkflowCmd.Flags().StringVar(&releaseWorkflowOutputPathAliasInput, "workflow-output", "", i18n.T("cmd.build.workflow.flag.workflow_output_path")) - releaseWorkflowCmd.Flags().StringVar(&releaseWorkflowOutputPathAliasInput, "workflow_output", "", i18n.T("cmd.build.workflow.flag.workflow_output_path")) + releaseWorkflowCmd.Flags().StringVar(&releaseWorkflowWorkflowOutputHyphenAliasInput, "workflow-output", "", i18n.T("cmd.build.workflow.flag.workflow_output_path")) + releaseWorkflowCmd.Flags().StringVar(&releaseWorkflowWorkflowOutputSnakeAliasInput, "workflow_output", "", i18n.T("cmd.build.workflow.flag.workflow_output_path")) } // buildCmd := &cli.Command{Use: "build"} @@ -135,8 +143,8 @@ func AddWorkflowCommand(buildCmd *cli.Command) { // runReleaseWorkflow(ctx, releaseWorkflowInputs{outputPathInput: "ci/release.yml"}) // uses the outputPath alias // runReleaseWorkflow(ctx, releaseWorkflowInputs{legacyOutputInput: "ci/release.yml"}) // uses the legacy output alias // runReleaseWorkflow(ctx, releaseWorkflowInputs{workflowOutputPathInput: "ci/release.yml"}) // uses the workflowOutputPath alias -// runReleaseWorkflow(ctx, releaseWorkflowInputs{workflowOutputPathInput: "ci/release.yml"}) // uses the workflow-output alias -// runReleaseWorkflow(ctx, releaseWorkflowInputs{workflowOutputPathInput: "ci/release.yml"}) // uses the workflow_output alias +// runReleaseWorkflow(ctx, releaseWorkflowInputs{workflowOutputHyphenInput: "ci/release.yml"}) // uses the workflow-output alias +// runReleaseWorkflow(ctx, releaseWorkflowInputs{workflowOutputSnakeInput: "ci/release.yml"}) // uses the workflow_output alias // runReleaseWorkflow(ctx, releaseWorkflowInputs{workflowOutputPathSnakeInput: "ci/release.yml"}) // uses the workflow_output_path alias // runReleaseWorkflow(ctx, releaseWorkflowInputs{workflowOutputPathHyphenInput: "ci/release.yml"}) // uses the workflow-output-path alias func runReleaseWorkflow(_ context.Context, inputs releaseWorkflowInputs) error { @@ -177,7 +185,7 @@ func resolveReleaseWorkflowInputPathAliases(projectDir, pathInput, workflowPathI // resolveReleaseWorkflowOutputPathAliases keeps the CLI error wording stable while // delegating the conflict detection to the shared build helper. -func resolveReleaseWorkflowOutputPathAliases(projectDir, outputPathInput, outputPathHyphenInput, outputPathSnakeInput, legacyOutputInput, workflowOutputPathInput, workflowOutputPathHyphenInput, workflowOutputPathSnakeInput string) (string, error) { +func resolveReleaseWorkflowOutputPathAliases(projectDir, outputPathInput, outputPathHyphenInput, outputPathSnakeInput, legacyOutputInput, workflowOutputPathInput, workflowOutputSnakeInput, workflowOutputHyphenInput, workflowOutputPathSnakeInput, workflowOutputPathHyphenInput string) (string, error) { resolvedWorkflowOutputPath, err := build.ResolveReleaseWorkflowOutputPathAliasesInProjectWithMedium( io.Local, projectDir, @@ -186,6 +194,8 @@ func resolveReleaseWorkflowOutputPathAliases(projectDir, outputPathInput, output outputPathSnakeInput, legacyOutputInput, workflowOutputPathInput, + workflowOutputSnakeInput, + workflowOutputHyphenInput, workflowOutputPathSnakeInput, workflowOutputPathHyphenInput, ) diff --git a/cmd/build/cmd_workflow_test.go b/cmd/build/cmd_workflow_test.go index fcbf6df..a75cd53 100644 --- a/cmd/build/cmd_workflow_test.go +++ b/cmd/build/cmd_workflow_test.go @@ -47,7 +47,7 @@ func TestBuildCmd_resolveReleaseWorkflowOutputPathInput_Bad(t *testing.T) { func TestBuildCmd_resolveReleaseWorkflowOutputPathAliases_Good(t *testing.T) { projectDir := t.TempDir() - path, err := resolveReleaseWorkflowOutputPathAliases(projectDir, "ci/release.yml", "", "", "", "", "./ci/release.yml", "ci/release.yml") + path, err := resolveReleaseWorkflowOutputPathAliases(projectDir, "ci/release.yml", "", "", "", "", "./ci/release.yml", "ci/release.yml", "", "") require.NoError(t, err) assert.Equal(t, ax.Join(projectDir, "ci", "release.yml"), path) } @@ -55,7 +55,7 @@ func TestBuildCmd_resolveReleaseWorkflowOutputPathAliases_Good(t *testing.T) { func TestBuildCmd_resolveReleaseWorkflowOutputPathAliases_CamelCaseGood(t *testing.T) { projectDir := t.TempDir() - path, err := resolveReleaseWorkflowOutputPathAliases(projectDir, "ci/release.yml", "", "", "", "", "", "") + path, err := resolveReleaseWorkflowOutputPathAliases(projectDir, "ci/release.yml", "", "", "", "", "", "", "", "") require.NoError(t, err) assert.Equal(t, ax.Join(projectDir, "ci", "release.yml"), path) } @@ -63,7 +63,23 @@ func TestBuildCmd_resolveReleaseWorkflowOutputPathAliases_CamelCaseGood(t *testi func TestBuildCmd_resolveReleaseWorkflowOutputPathAliases_WorkflowCamelCaseGood(t *testing.T) { projectDir := t.TempDir() - path, err := resolveReleaseWorkflowOutputPathAliases(projectDir, "", "", "", "", "ci/release.yml", "", "") + path, err := resolveReleaseWorkflowOutputPathAliases(projectDir, "", "", "", "", "ci/release.yml", "", "", "", "") + require.NoError(t, err) + assert.Equal(t, ax.Join(projectDir, "ci", "release.yml"), path) +} + +func TestBuildCmd_resolveReleaseWorkflowOutputPathAliases_WorkflowHyphenGood(t *testing.T) { + projectDir := t.TempDir() + + path, err := resolveReleaseWorkflowOutputPathAliases(projectDir, "", "", "", "", "", "ci/release.yml", "", "", "") + require.NoError(t, err) + assert.Equal(t, ax.Join(projectDir, "ci", "release.yml"), path) +} + +func TestBuildCmd_resolveReleaseWorkflowOutputPathAliases_WorkflowSnakeGood(t *testing.T) { + projectDir := t.TempDir() + + path, err := resolveReleaseWorkflowOutputPathAliases(projectDir, "", "", "", "", "", "", "ci/release.yml", "", "") require.NoError(t, err) assert.Equal(t, ax.Join(projectDir, "ci", "release.yml"), path) } @@ -71,7 +87,7 @@ func TestBuildCmd_resolveReleaseWorkflowOutputPathAliases_WorkflowCamelCaseGood( func TestBuildCmd_resolveReleaseWorkflowOutputPathAliases_Bad(t *testing.T) { projectDir := t.TempDir() - _, err := resolveReleaseWorkflowOutputPathAliases(projectDir, "ci/release.yml", "", "", "", "ops/release.yml", "", "") + _, err := resolveReleaseWorkflowOutputPathAliases(projectDir, "ci/release.yml", "", "", "", "ops/release.yml", "", "", "", "") require.Error(t, err) assert.Contains(t, err.Error(), "workflow output aliases specify different locations") } @@ -79,7 +95,7 @@ func TestBuildCmd_resolveReleaseWorkflowOutputPathAliases_Bad(t *testing.T) { func TestBuildCmd_resolveReleaseWorkflowOutputPathAliases_HyphenatedGood(t *testing.T) { projectDir := t.TempDir() - path, err := resolveReleaseWorkflowOutputPathAliases(projectDir, "", "ci/release.yml", "", "", "", "", "") + path, err := resolveReleaseWorkflowOutputPathAliases(projectDir, "", "ci/release.yml", "", "", "", "", "", "", "") require.NoError(t, err) assert.Equal(t, ax.Join(projectDir, "ci", "release.yml"), path) } @@ -88,7 +104,7 @@ func TestBuildCmd_resolveReleaseWorkflowOutputPathAliases_AbsoluteEquivalent_Goo projectDir := t.TempDir() absolutePath := ax.Join(projectDir, "ci", "release.yml") - path, err := resolveReleaseWorkflowOutputPathAliases(projectDir, "ci/release.yml", "", "", "", "", "", absolutePath) + path, err := resolveReleaseWorkflowOutputPathAliases(projectDir, "ci/release.yml", "", "", "", "", "", "", "", absolutePath) require.NoError(t, err) assert.Equal(t, absolutePath, path) } @@ -98,7 +114,7 @@ func TestBuildCmd_resolveReleaseWorkflowOutputPathAliases_AbsoluteDirectory_Good absoluteDir := ax.Join(projectDir, "ops") require.NoError(t, io.Local.EnsureDir(absoluteDir)) - path, err := resolveReleaseWorkflowOutputPathAliases(projectDir, "", "", "", "", absoluteDir, "", "") + path, err := resolveReleaseWorkflowOutputPathAliases(projectDir, "", "", "", "", absoluteDir, "", "", "", "") require.NoError(t, err) assert.Equal(t, ax.Join(absoluteDir, "release.yml"), path) } diff --git a/pkg/api/provider.go b/pkg/api/provider.go index 4afadfc..8acebc6 100644 --- a/pkg/api/provider.go +++ b/pkg/api/provider.go @@ -199,6 +199,14 @@ func (p *BuildProvider) Describe() []api.RouteDescription { "type": "string", "description": "Predictable alias for outputPath, relative to the project directory or absolute.", }, + "workflow_output": map[string]any{ + "type": "string", + "description": "Snake_case alias for workflowOutputPath.", + }, + "workflow-output": map[string]any{ + "type": "string", + "description": "Hyphenated alias for workflowOutputPath.", + }, "workflow_output_path": map[string]any{ "type": "string", "description": "Snake_case alias for workflowOutputPath.", @@ -584,6 +592,8 @@ type ReleaseWorkflowRequest struct { OutputPathSnake string `json:"output_path"` LegacyOutputPath string `json:"output"` WorkflowOutputPath string `json:"workflowOutputPath"` + WorkflowOutputSnake string `json:"workflow_output"` + WorkflowOutputHyphen string `json:"workflow-output"` WorkflowOutputPathSnake string `json:"workflow_output_path"` WorkflowOutputPathHyphen string `json:"workflow-output-path"` } @@ -642,6 +652,8 @@ func (r ReleaseWorkflowRequest) resolvedOutputPath(dir string, medium io.Medium) r.OutputPathSnake, r.LegacyOutputPath, r.WorkflowOutputPath, + r.WorkflowOutputSnake, + r.WorkflowOutputHyphen, r.WorkflowOutputPathSnake, r.WorkflowOutputPathHyphen, ) diff --git a/pkg/api/provider_test.go b/pkg/api/provider_test.go index 96ffa4f..4bd56bf 100644 --- a/pkg/api/provider_test.go +++ b/pkg/api/provider_test.go @@ -126,6 +126,16 @@ func TestProvider_BuildProviderDescribe_Good(t *testing.T) { assert.Equal(t, "string", workflowOutputPathSchema["type"]) assert.Equal(t, "Predictable alias for outputPath, relative to the project directory or absolute.", workflowOutputPathSchema["description"]) + workflowOutputSnakeSchema, ok := properties["workflow_output"].(map[string]any) + require.True(t, ok) + assert.Equal(t, "string", workflowOutputSnakeSchema["type"]) + assert.Equal(t, "Snake_case alias for workflowOutputPath.", workflowOutputSnakeSchema["description"]) + + workflowOutputHyphenSchema, ok := properties["workflow-output"].(map[string]any) + require.True(t, ok) + assert.Equal(t, "string", workflowOutputHyphenSchema["type"]) + assert.Equal(t, "Hyphenated alias for workflowOutputPath.", workflowOutputHyphenSchema["description"]) + workflowOutputPathSnakeSchema, ok := properties["workflow_output_path"].(map[string]any) require.True(t, ok) assert.Equal(t, "string", workflowOutputPathSnakeSchema["type"]) @@ -156,6 +166,19 @@ func TestProvider_ReleaseWorkflowRequestResolvedOutputPath_Good(t *testing.T) { assert.Equal(t, ax.Join(absoluteDir, "release.yml"), path) } +func TestProvider_ReleaseWorkflowRequestResolvedOutputPathAliases_Good(t *testing.T) { + projectDir := t.TempDir() + + req := ReleaseWorkflowRequest{ + WorkflowOutputSnake: "ci/workflow-output.yml", + WorkflowOutputHyphen: "ci/workflow-output.yml", + } + + path, err := req.resolvedOutputPath(projectDir, io.Local) + require.NoError(t, err) + assert.Equal(t, ax.Join(projectDir, "ci", "workflow-output.yml"), path) +} + func TestProvider_BuildProviderDefaultProjectDir_Good(t *testing.T) { p := NewProvider("", nil) assert.Equal(t, ".", p.projectDir) @@ -506,6 +529,30 @@ func TestProvider_GenerateReleaseWorkflow_WorkflowOutputPath_Good(t *testing.T) assert.Contains(t, content, "workflow_dispatch:") } +func TestProvider_GenerateReleaseWorkflow_WorkflowOutputSnake_Good(t *testing.T) { + gin.SetMode(gin.TestMode) + + projectDir := t.TempDir() + p := NewProvider(projectDir, nil) + + recorder := httptest.NewRecorder() + request := httptest.NewRequest(http.MethodPost, "/release/workflow", bytes.NewBufferString(`{"workflow_output":"ci/workflow-output.yml"}`)) + request.Header.Set("Content-Type", "application/json") + + ctx, _ := gin.CreateTestContext(recorder) + ctx.Request = request + + p.generateReleaseWorkflow(ctx) + + assert.Equal(t, http.StatusOK, recorder.Code) + + path := ax.Join(projectDir, "ci", "workflow-output.yml") + content, err := io.Local.Read(path) + require.NoError(t, err) + assert.Contains(t, content, "workflow_call:") + assert.Contains(t, content, "workflow_dispatch:") +} + func TestProvider_GenerateReleaseWorkflow_WorkflowOutputPathSnake_Good(t *testing.T) { gin.SetMode(gin.TestMode) @@ -580,6 +627,30 @@ func TestProvider_GenerateReleaseWorkflow_WorkflowOutputPathHyphen_Good(t *testi assert.Contains(t, content, "workflow_dispatch:") } +func TestProvider_GenerateReleaseWorkflow_WorkflowOutputHyphen_Good(t *testing.T) { + gin.SetMode(gin.TestMode) + + projectDir := t.TempDir() + p := NewProvider(projectDir, nil) + + recorder := httptest.NewRecorder() + request := httptest.NewRequest(http.MethodPost, "/release/workflow", bytes.NewBufferString(`{"workflow-output":"ci/workflow-output.yml"}`)) + request.Header.Set("Content-Type", "application/json") + + ctx, _ := gin.CreateTestContext(recorder) + ctx.Request = request + + p.generateReleaseWorkflow(ctx) + + assert.Equal(t, http.StatusOK, recorder.Code) + + path := ax.Join(projectDir, "ci", "workflow-output.yml") + content, err := io.Local.Read(path) + require.NoError(t, err) + assert.Contains(t, content, "workflow_call:") + assert.Contains(t, content, "workflow_dispatch:") +} + func TestProvider_GenerateReleaseWorkflow_ConflictingWorkflowOutputAliases_Bad(t *testing.T) { gin.SetMode(gin.TestMode) diff --git a/pkg/api/ui/dist/core-build.js b/pkg/api/ui/dist/core-build.js index 18ae378..d472696 100644 --- a/pkg/api/ui/dist/core-build.js +++ b/pkg/api/ui/dist/core-build.js @@ -1253,7 +1253,7 @@ let g = class extends k { this.generatingWorkflow = !0, this.error = "", this.workflowSuccess = ""; try { const s = {}, e = this.workflowPath.trim(), t = this.workflowOutputPath.trim(); - e && (s.path = e), e && (s.workflowPath = e, s.workflow_path = e, s["workflow-path"] = e), t && (s.outputPath = t), t && (s["output-path"] = t, s.output_path = t, s.output = t, s.workflowOutputPath = t, s.workflow_output_path = t, s["workflow-output-path"] = t); + e && (s.path = e), e && (s.workflowPath = e, s.workflow_path = e, s["workflow-path"] = e), t && (s.outputPath = t), t && (s["output-path"] = t, s.output_path = t, s.output = t, s.workflowOutputPath = t, s.workflow_output = t, s["workflow-output"] = t, s.workflow_output_path = t, s["workflow-output-path"] = t); const i = (await this.api.releaseWorkflow(s)).path ?? t ?? e ?? ".github/workflows/release.yml"; this.workflowSuccess = `Workflow generated at ${i}`; } catch (s) { diff --git a/pkg/build/workflow.go b/pkg/build/workflow.go index 9f2e003..909042b 100644 --- a/pkg/build/workflow.go +++ b/pkg/build/workflow.go @@ -190,22 +190,26 @@ func ResolveReleaseWorkflowOutputPath(outputPathInput, outputPathSnakeInput, leg "", "", "", + "", + "", ) } // ResolveReleaseWorkflowOutputPathAliases resolves every public workflow output // alias across the CLI, API, and UI layers. // -// build.ResolveReleaseWorkflowOutputPathAliases("ci/release.yml", "", "", "", "", "", "") // "ci/release.yml" -// build.ResolveReleaseWorkflowOutputPathAliases("", "ci/release.yml", "", "", "", "", "") // "ci/release.yml" -// build.ResolveReleaseWorkflowOutputPathAliases("", "", "", "", "ci/release.yml", "", "") // "ci/release.yml" -// build.ResolveReleaseWorkflowOutputPathAliases("", "", "", "", "", "", "ci/release.yml") // "ci/release.yml" +// build.ResolveReleaseWorkflowOutputPathAliases("ci/release.yml", "", "", "", "", "", "", "", "") // "ci/release.yml" +// build.ResolveReleaseWorkflowOutputPathAliases("", "ci/release.yml", "", "", "", "", "", "", "") // "ci/release.yml" +// build.ResolveReleaseWorkflowOutputPathAliases("", "", "", "", "ci/release.yml", "", "", "", "") // "ci/release.yml" +// build.ResolveReleaseWorkflowOutputPathAliases("", "", "", "", "", "ci/release.yml", "", "", "") // "ci/release.yml" func ResolveReleaseWorkflowOutputPathAliases( outputPathInput, outputPathHyphenInput, outputPathSnakeInput, legacyOutputInput, workflowOutputPathInput, + workflowOutputSnakeInput, + workflowOutputHyphenInput, workflowOutputPathSnakeInput, workflowOutputPathHyphenInput string, ) (string, error) { @@ -215,6 +219,8 @@ func ResolveReleaseWorkflowOutputPathAliases( outputPathSnakeInput, legacyOutputInput, workflowOutputPathInput, + workflowOutputSnakeInput, + workflowOutputHyphenInput, workflowOutputPathSnakeInput, workflowOutputPathHyphenInput, "build.ResolveReleaseWorkflowOutputPathAliases", @@ -224,8 +230,8 @@ func ResolveReleaseWorkflowOutputPathAliases( // ResolveReleaseWorkflowOutputPathAliasesInProject resolves the workflow output // aliases relative to a project directory before checking for conflicts. // -// build.ResolveReleaseWorkflowOutputPathAliasesInProject("/tmp/project", "ci/release.yml", "", "", "", "", "", "") // "/tmp/project/ci/release.yml" -// build.ResolveReleaseWorkflowOutputPathAliasesInProject("/tmp/project", "", "", "", "", "/tmp/project/ci/release.yml", "", "") // "/tmp/project/ci/release.yml" +// build.ResolveReleaseWorkflowOutputPathAliasesInProject("/tmp/project", "ci/release.yml", "", "", "", "", "", "", "") // "/tmp/project/ci/release.yml" +// build.ResolveReleaseWorkflowOutputPathAliasesInProject("/tmp/project", "", "", "", "", "/tmp/project/ci/release.yml", "", "", "") // "/tmp/project/ci/release.yml" func ResolveReleaseWorkflowOutputPathAliasesInProject( projectDir, outputPathInput, @@ -233,6 +239,8 @@ func ResolveReleaseWorkflowOutputPathAliasesInProject( outputPathSnakeInput, legacyOutputInput, workflowOutputPathInput, + workflowOutputSnakeInput, + workflowOutputHyphenInput, workflowOutputPathSnakeInput, workflowOutputPathHyphenInput string, ) (string, error) { @@ -244,6 +252,8 @@ func ResolveReleaseWorkflowOutputPathAliasesInProject( outputPathSnakeInput, legacyOutputInput, workflowOutputPathInput, + workflowOutputSnakeInput, + workflowOutputHyphenInput, workflowOutputPathSnakeInput, workflowOutputPathHyphenInput, ) @@ -254,7 +264,7 @@ func ResolveReleaseWorkflowOutputPathAliasesInProject( // provided filesystem medium to treat existing directories as workflow // directories even when callers omit a trailing separator. // -// build.ResolveReleaseWorkflowOutputPathAliasesInProjectWithMedium(io.Local, "/tmp/project", "", "", "", "", "/tmp/project/ci", "", "") // "/tmp/project/ci/release.yml" +// build.ResolveReleaseWorkflowOutputPathAliasesInProjectWithMedium(io.Local, "/tmp/project", "", "", "", "", "/tmp/project/ci", "", "", "") // "/tmp/project/ci/release.yml" func ResolveReleaseWorkflowOutputPathAliasesInProjectWithMedium( filesystem io_interface.Medium, projectDir, @@ -263,6 +273,8 @@ func ResolveReleaseWorkflowOutputPathAliasesInProjectWithMedium( outputPathSnakeInput, legacyOutputInput, workflowOutputPathInput, + workflowOutputSnakeInput, + workflowOutputHyphenInput, workflowOutputPathSnakeInput, workflowOutputPathHyphenInput string, ) (string, error) { @@ -274,6 +286,8 @@ func ResolveReleaseWorkflowOutputPathAliasesInProjectWithMedium( outputPathSnakeInput, legacyOutputInput, workflowOutputPathInput, + workflowOutputSnakeInput, + workflowOutputHyphenInput, workflowOutputPathSnakeInput, workflowOutputPathHyphenInput, "build.ResolveReleaseWorkflowOutputPathAliasesInProject", @@ -316,6 +330,8 @@ func resolveReleaseWorkflowOutputAliasSet( outputPathSnakeInput, legacyOutputInput, workflowOutputPathInput, + workflowOutputSnakeInput, + workflowOutputHyphenInput, workflowOutputPathSnakeInput, workflowOutputPathHyphenInput, errorName string, @@ -326,6 +342,8 @@ func resolveReleaseWorkflowOutputAliasSet( normalizeWorkflowOutputAlias(outputPathSnakeInput), normalizeWorkflowOutputAlias(legacyOutputInput), normalizeWorkflowOutputAlias(workflowOutputPathInput), + normalizeWorkflowOutputAlias(workflowOutputSnakeInput), + normalizeWorkflowOutputAlias(workflowOutputHyphenInput), normalizeWorkflowOutputAlias(workflowOutputPathSnakeInput), normalizeWorkflowOutputAlias(workflowOutputPathHyphenInput), } @@ -357,6 +375,8 @@ func resolveReleaseWorkflowOutputAliasSetInProject( outputPathSnakeInput, legacyOutputInput, workflowOutputPathInput, + workflowOutputSnakeInput, + workflowOutputHyphenInput, workflowOutputPathSnakeInput, workflowOutputPathHyphenInput, errorName string, @@ -367,6 +387,8 @@ func resolveReleaseWorkflowOutputAliasSetInProject( cleanWorkflowInput(outputPathSnakeInput), cleanWorkflowInput(legacyOutputInput), cleanWorkflowInput(workflowOutputPathInput), + cleanWorkflowInput(workflowOutputSnakeInput), + cleanWorkflowInput(workflowOutputHyphenInput), cleanWorkflowInput(workflowOutputPathSnakeInput), cleanWorkflowInput(workflowOutputPathHyphenInput), } diff --git a/pkg/build/workflow_test.go b/pkg/build/workflow_test.go index bde9942..1641476 100644 --- a/pkg/build/workflow_test.go +++ b/pkg/build/workflow_test.go @@ -403,7 +403,7 @@ func TestWorkflow_ResolveReleaseWorkflowOutputPath_Good(t *testing.T) { }) t.Run("accepts the hyphenated output path alias", func(t *testing.T) { - path, err := ResolveReleaseWorkflowOutputPathAliases("", "ci/release.yml", "", "", "", "", "") + path, err := ResolveReleaseWorkflowOutputPathAliases("", "ci/release.yml", "", "", "", "", "", "", "") require.NoError(t, err) assert.Equal(t, "ci/release.yml", path) }) @@ -442,19 +442,31 @@ func TestWorkflow_ResolveReleaseWorkflowOutputPath_Bad(t *testing.T) { func TestWorkflow_ResolveReleaseWorkflowOutputPathAliases_Good(t *testing.T) { t.Run("accepts workflowOutputPath aliases", func(t *testing.T) { - path, err := ResolveReleaseWorkflowOutputPathAliases("", "", "", "", "ci/release.yml", "", "") + path, err := ResolveReleaseWorkflowOutputPathAliases("", "", "", "", "ci/release.yml", "", "", "", "") require.NoError(t, err) assert.Equal(t, "ci/release.yml", path) }) t.Run("accepts the hyphenated workflowOutputPath alias", func(t *testing.T) { - path, err := ResolveReleaseWorkflowOutputPathAliases("", "", "", "", "", "", "ci/release.yml") + path, err := ResolveReleaseWorkflowOutputPathAliases("", "", "", "", "", "", "ci/release.yml", "", "") + require.NoError(t, err) + assert.Equal(t, "ci/release.yml", path) + }) + + t.Run("accepts the workflow_output alias", func(t *testing.T) { + path, err := ResolveReleaseWorkflowOutputPathAliases("", "", "", "", "", "ci/release.yml", "", "", "") + require.NoError(t, err) + assert.Equal(t, "ci/release.yml", path) + }) + + t.Run("accepts the workflow-output alias", func(t *testing.T) { + path, err := ResolveReleaseWorkflowOutputPathAliases("", "", "", "", "", "", "ci/release.yml", "", "") require.NoError(t, err) assert.Equal(t, "ci/release.yml", path) }) t.Run("normalises matching workflow output aliases", func(t *testing.T) { - path, err := ResolveReleaseWorkflowOutputPathAliases("ci/release.yml", "", "", "./ci/release.yml", "ci/release.yml", "", "") + path, err := ResolveReleaseWorkflowOutputPathAliases("ci/release.yml", "", "", "./ci/release.yml", "ci/release.yml", "", "", "", "") require.NoError(t, err) assert.Equal(t, "ci/release.yml", path) }) @@ -467,19 +479,19 @@ func TestWorkflow_ResolveReleaseWorkflowOutputPathAliasesInProject_Good(t *testi require.NoError(t, ax.MkdirAll(absoluteDirectory, 0o755)) t.Run("accepts the preferred output path", func(t *testing.T) { - path, err := ResolveReleaseWorkflowOutputPathAliasesInProject(projectDir, "ci/release.yml", "", "", "", "", "", "") + path, err := ResolveReleaseWorkflowOutputPathAliasesInProject(projectDir, "ci/release.yml", "", "", "", "", "", "", "", "") require.NoError(t, err) assert.Equal(t, absolutePath, path) }) t.Run("accepts an absolute workflow output alias equivalent to the project path", func(t *testing.T) { - path, err := ResolveReleaseWorkflowOutputPathAliasesInProject(projectDir, "", "", "", "", absolutePath, "", "") + path, err := ResolveReleaseWorkflowOutputPathAliasesInProject(projectDir, "", "", "", "", absolutePath, "", "", "", "") require.NoError(t, err) assert.Equal(t, absolutePath, path) }) t.Run("accepts matching relative and absolute aliases", func(t *testing.T) { - path, err := ResolveReleaseWorkflowOutputPathAliasesInProject(projectDir, "ci/release.yml", "", "", "", "", "", absolutePath) + path, err := ResolveReleaseWorkflowOutputPathAliasesInProject(projectDir, "ci/release.yml", "", "", "", "", "", "", "", absolutePath) require.NoError(t, err) assert.Equal(t, absolutePath, path) }) @@ -488,7 +500,7 @@ func TestWorkflow_ResolveReleaseWorkflowOutputPathAliasesInProject_Good(t *testi fs := io.NewMockMedium() fs.Dirs[absoluteDirectory] = true - path, err := ResolveReleaseWorkflowOutputPathAliasesInProjectWithMedium(fs, projectDir, "", "", "", "", absoluteDirectory, "", "") + path, err := ResolveReleaseWorkflowOutputPathAliasesInProjectWithMedium(fs, projectDir, "", "", "", "", absoluteDirectory, "", "", "", "") require.NoError(t, err) assert.Equal(t, ax.Join(absoluteDirectory, DefaultReleaseWorkflowFileName), path) }) @@ -497,14 +509,14 @@ func TestWorkflow_ResolveReleaseWorkflowOutputPathAliasesInProject_Good(t *testi func TestWorkflow_ResolveReleaseWorkflowOutputPathAliasesInProject_Bad(t *testing.T) { projectDir := t.TempDir() - path, err := ResolveReleaseWorkflowOutputPathAliasesInProject(projectDir, "ci/release.yml", "", "", "", "", "", ax.Join(projectDir, "ops", "release.yml")) + path, err := ResolveReleaseWorkflowOutputPathAliasesInProject(projectDir, "ci/release.yml", "", "", "", "", "", "", "", ax.Join(projectDir, "ops", "release.yml")) assert.Error(t, err) assert.Empty(t, path) assert.Contains(t, err.Error(), "output aliases specify different locations") } func TestWorkflow_ResolveReleaseWorkflowOutputPathAliases_Bad(t *testing.T) { - path, err := ResolveReleaseWorkflowOutputPathAliases("ci/release.yml", "", "", "", "ops/release.yml", "", "") + path, err := ResolveReleaseWorkflowOutputPathAliases("ci/release.yml", "", "", "", "ops/release.yml", "", "", "", "") assert.Error(t, err) assert.Empty(t, path) assert.Contains(t, err.Error(), "output aliases specify different locations") diff --git a/ui/src/build-release.ts b/ui/src/build-release.ts index b76db51..77087f9 100644 --- a/ui/src/build-release.ts +++ b/ui/src/build-release.ts @@ -327,6 +327,8 @@ export class BuildRelease extends LitElement { output_path?: string; output?: string; workflowOutputPath?: string; + workflow_output?: string; + 'workflow-output'?: string; workflow_output_path?: string; 'workflow-output-path'?: string; } = {}; @@ -344,6 +346,8 @@ export class BuildRelease extends LitElement { request.output_path = outputPath; request.output = outputPath; request.workflowOutputPath = outputPath; + request.workflow_output = outputPath; + request['workflow-output'] = outputPath; request.workflow_output_path = outputPath; request['workflow-output-path'] = outputPath; } diff --git a/ui/src/shared/api.ts b/ui/src/shared/api.ts index ca2e26e..12e901f 100644 --- a/ui/src/shared/api.ts +++ b/ui/src/shared/api.ts @@ -66,6 +66,8 @@ export class BuildApi { output_path?: string; output?: string; workflowOutputPath?: string; + workflow_output?: string; + 'workflow-output'?: string; workflow_output_path?: string; 'workflow-output-path'?: string; } = {}) {