Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement repo level, user level and global environment variables support #3723

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
83 changes: 83 additions & 0 deletions cli/variable/variable.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2023 Woodpecker Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package variable

import (
"fmt"
"strconv"
"strings"

"github.com/urfave/cli/v3"

"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
"go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker"
)

// Command exports the variable command.
var Command = &cli.Command{
Name: "variable",
Usage: "manage variables",
Commands: []*cli.Command{
variableCreateCmd,
variableDeleteCmd,
variableUpdateCmd,
variableInfoCmd,
variableListCmd,
},
}

func parseTargetArgs(client woodpecker.Client, c *cli.Command) (global bool, orgID, repoID int64, err error) {
if c.Bool("global") {
return true, -1, -1, nil
}

Check warning on line 44 in cli/variable/variable.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable.go#L41-L44

Added lines #L41 - L44 were not covered by tests

repoIDOrFullName := c.String("repository")
if repoIDOrFullName == "" {
repoIDOrFullName = c.Args().First()
}

Check warning on line 49 in cli/variable/variable.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable.go#L46-L49

Added lines #L46 - L49 were not covered by tests

orgIDOrName := c.String("organization")
if orgIDOrName == "" && repoIDOrFullName == "" {
if err := cli.ShowSubcommandHelp(c); err != nil {
return false, -1, -1, err
}

Check warning on line 55 in cli/variable/variable.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable.go#L51-L55

Added lines #L51 - L55 were not covered by tests

return false, -1, -1, fmt.Errorf("missing arguments")

Check warning on line 57 in cli/variable/variable.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable.go#L57

Added line #L57 was not covered by tests
}

if orgIDOrName != "" && repoIDOrFullName == "" {
if orgID, err := strconv.ParseInt(orgIDOrName, 10, 64); err == nil {
return false, orgID, -1, nil
}

Check warning on line 63 in cli/variable/variable.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable.go#L60-L63

Added lines #L60 - L63 were not covered by tests

org, err := client.OrgLookup(orgIDOrName)
if err != nil {
return false, -1, -1, err
}

Check warning on line 68 in cli/variable/variable.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable.go#L65-L68

Added lines #L65 - L68 were not covered by tests

return false, org.ID, -1, nil

Check warning on line 70 in cli/variable/variable.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable.go#L70

Added line #L70 was not covered by tests
}

if orgIDOrName != "" && !strings.Contains(repoIDOrFullName, "/") {
repoIDOrFullName = orgIDOrName + "/" + repoIDOrFullName
}

Check warning on line 75 in cli/variable/variable.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable.go#L73-L75

Added lines #L73 - L75 were not covered by tests

repoID, err = internal.ParseRepo(client, repoIDOrFullName)
if err != nil {
return false, -1, -1, err
}

Check warning on line 80 in cli/variable/variable.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable.go#L77-L80

Added lines #L77 - L80 were not covered by tests

return false, -1, repoID, nil

Check warning on line 82 in cli/variable/variable.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable.go#L82

Added line #L82 was not covered by tests
}
88 changes: 88 additions & 0 deletions cli/variable/variable_add.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright 2023 Woodpecker Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package variable

import (
"context"
"os"
"strings"

"github.com/urfave/cli/v3"

"go.woodpecker-ci.org/woodpecker/v2/cli/common"
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
"go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker"
)

var variableCreateCmd = &cli.Command{
Name: "add",
Usage: "adds a variable",
ArgsUsage: "[repo-id|repo-full-name]",
Action: variableCreate,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "global",
Usage: "global variable",
},
common.OrgFlag,
common.RepoFlag,
&cli.StringFlag{
Name: "name",
Usage: "variable name",
},
&cli.StringFlag{
Name: "value",
Usage: "variable value",
},
},
}

func variableCreate(ctx context.Context, c *cli.Command) error {
client, err := internal.NewClient(ctx, c)
if err != nil {
return err
}

Check warning on line 56 in cli/variable/variable_add.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable_add.go#L52-L56

Added lines #L52 - L56 were not covered by tests

variable := &woodpecker.Variable{
Name: strings.ToLower(c.String("name")),
Value: c.String("value"),
}
if strings.HasPrefix(variable.Value, "@") {
path := strings.TrimPrefix(variable.Value, "@")
out, err := os.ReadFile(path)
if err != nil {
return err
}
variable.Value = string(out)

Check warning on line 68 in cli/variable/variable_add.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable_add.go#L58-L68

Added lines #L58 - L68 were not covered by tests
}

global, orgID, repoID, err := parseTargetArgs(client, c)
if err != nil {
return err
}

Check warning on line 74 in cli/variable/variable_add.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable_add.go#L71-L74

Added lines #L71 - L74 were not covered by tests

if global {
_, err = client.GlobalVariableCreate(variable)
return err
}

Check warning on line 79 in cli/variable/variable_add.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable_add.go#L76-L79

Added lines #L76 - L79 were not covered by tests

if orgID != -1 {
_, err = client.OrgVariableCreate(orgID, variable)
return err
}

Check warning on line 84 in cli/variable/variable_add.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable_add.go#L81-L84

Added lines #L81 - L84 were not covered by tests

_, err = client.VariableCreate(repoID, variable)
return err

Check warning on line 87 in cli/variable/variable_add.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable_add.go#L86-L87

Added lines #L86 - L87 were not covered by tests
}
94 changes: 94 additions & 0 deletions cli/variable/variable_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright 2023 Woodpecker Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package variable

import (
"context"
"fmt"
"html/template"
"os"

"github.com/urfave/cli/v3"

"go.woodpecker-ci.org/woodpecker/v2/cli/common"
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
"go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker"
)

var variableInfoCmd = &cli.Command{
Name: "info",
Usage: "display variable info",
ArgsUsage: "[repo-id|repo-full-name]",
Action: variableInfo,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "global",
Usage: "global variable",
},
common.OrgFlag,
common.RepoFlag,
&cli.StringFlag{
Name: "name",
Usage: "variable name",
},
common.FormatFlag(tmplVariableList, true),
},
}

func variableInfo(ctx context.Context, c *cli.Command) error {
var (
variableName = c.String("name")
format = c.String("format") + "\n"
)

if variableName == "" {
return fmt.Errorf("variable name is missing")
}

Check warning on line 58 in cli/variable/variable_info.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable_info.go#L50-L58

Added lines #L50 - L58 were not covered by tests

client, err := internal.NewClient(ctx, c)
if err != nil {
return err
}

Check warning on line 63 in cli/variable/variable_info.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable_info.go#L60-L63

Added lines #L60 - L63 were not covered by tests

global, orgID, repoID, err := parseTargetArgs(client, c)
if err != nil {
return err
}

Check warning on line 68 in cli/variable/variable_info.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable_info.go#L65-L68

Added lines #L65 - L68 were not covered by tests

var variable *woodpecker.Variable
switch {
case global:
variable, err = client.GlobalVariable(variableName)
if err != nil {
return err
}
case orgID != -1:
variable, err = client.OrgVariable(orgID, variableName)
if err != nil {
return err
}
default:
variable, err = client.Variable(repoID, variableName)
if err != nil {
return err
}

Check warning on line 86 in cli/variable/variable_info.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable_info.go#L70-L86

Added lines #L70 - L86 were not covered by tests
}

tmpl, err := template.New("_").Funcs(variableFuncMap).Parse(format)
if err != nil {
return err
}
return tmpl.Execute(os.Stdout, variable)

Check warning on line 93 in cli/variable/variable_info.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable_info.go#L89-L93

Added lines #L89 - L93 were not covered by tests
}
99 changes: 99 additions & 0 deletions cli/variable/variable_list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright 2023 Woodpecker Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package variable

import (
"context"
"html/template"
"os"
"strings"

"github.com/urfave/cli/v3"

"go.woodpecker-ci.org/woodpecker/v2/cli/common"
"go.woodpecker-ci.org/woodpecker/v2/cli/internal"
"go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker"
)

var variableListCmd = &cli.Command{
Name: "ls",
Usage: "list variables",
ArgsUsage: "[repo-id|repo-full-name]",
Action: variableList,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "global",
Usage: "global variable",
},
common.OrgFlag,
common.RepoFlag,
common.FormatFlag(tmplVariableList, true),
},
}

func variableList(ctx context.Context, c *cli.Command) error {
format := c.String("format") + "\n"

client, err := internal.NewClient(ctx, c)
if err != nil {
return err
}

Check warning on line 52 in cli/variable/variable_list.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable_list.go#L46-L52

Added lines #L46 - L52 were not covered by tests

global, orgID, repoID, err := parseTargetArgs(client, c)
if err != nil {
return err
}

Check warning on line 57 in cli/variable/variable_list.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable_list.go#L54-L57

Added lines #L54 - L57 were not covered by tests

var list []*woodpecker.Variable
switch {
case global:
list, err = client.GlobalVariableList()
if err != nil {
return err
}
case orgID != -1:
list, err = client.OrgVariableList(orgID)
if err != nil {
return err
}
default:
list, err = client.VariableList(repoID)
if err != nil {
return err
}

Check warning on line 75 in cli/variable/variable_list.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable_list.go#L59-L75

Added lines #L59 - L75 were not covered by tests
}

tmpl, err := template.New("_").Funcs(variableFuncMap).Parse(format)
if err != nil {
return err
}
for _, registry := range list {
if err := tmpl.Execute(os.Stdout, registry); err != nil {
return err
}

Check warning on line 85 in cli/variable/variable_list.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable_list.go#L78-L85

Added lines #L78 - L85 were not covered by tests
}
return nil

Check warning on line 87 in cli/variable/variable_list.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable_list.go#L87

Added line #L87 was not covered by tests
}

// Template for variable list items.
var tmplVariableList = "\x1b[33m{{ .Name }} \x1b[0m" + `
Value: {{ .Value }}
`

var variableFuncMap = template.FuncMap{
"list": func(s []string) string {
return strings.Join(s, ", ")
},

Check warning on line 98 in cli/variable/variable_list.go

View check run for this annotation

Codecov / codecov/patch

cli/variable/variable_list.go#L96-L98

Added lines #L96 - L98 were not covered by tests
}
Loading