From c9e6fea07feb969e7aa3a328331b3f6c2fc872b3 Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Tue, 4 Jun 2024 14:46:17 -0400 Subject: [PATCH 1/9] enhance: add support for args and aliases to credential tools Signed-off-by: Grant Linville --- docs/docs/03-tools/04-credentials.md | 59 +++++++++-- pkg/parser/parser.go | 2 +- pkg/runner/runner.go | 53 +++++++--- pkg/types/credential_test.go | 153 +++++++++++++++++++++++++++ pkg/types/tool.go | 124 ++++++++++++++++++++-- 5 files changed, 360 insertions(+), 31 deletions(-) create mode 100644 pkg/types/credential_test.go diff --git a/docs/docs/03-tools/04-credentials.md b/docs/docs/03-tools/04-credentials.md index d84ee930..15d41a6e 100644 --- a/docs/docs/03-tools/04-credentials.md +++ b/docs/docs/03-tools/04-credentials.md @@ -8,7 +8,6 @@ directly from user input) and conveniently set them in the environment before ru A credential provider tool looks just like any other GPTScript, with the following caveats: - It cannot call the LLM and must run a command. - It must print contents to stdout in the format `{"env":{"ENV_VAR_1":"value1","ENV_VAR_2":"value2"}}`. -- Any args defined on the tool will be ignored. Here is a simple example of a credential provider tool that uses the builtin `sys.prompt` to ask the user for some input: @@ -50,6 +49,30 @@ credentials: credential-tool-1.gpt, credential-tool-2.gpt (tool stuff here) ``` +## Credential Tool Arguments + +A credential tool may define arguments. Here is an example: + +```yaml +name: my-credential-tool +args: env: the environment variable to set +args: val: the value to set it to + +#!/usr/bin/env bash + +echo "{\"env\":{\"$ENV\":\"$VAL\"}}" +``` + +When you reference this credential tool in another file, you can use syntax like this to set both arguments: + +```yaml +credential: my-credential-tool.gpt with MY_ENV_VAR as env and "my value" as val + +(tool stuff here) +``` + +In this example, the tool's output would be `{"env":{"MY_ENV_VAR":"my value"}}` + ## Storing Credentials By default, credentials are automatically stored in a config file at `$XDG_CONFIG_HOME/gptscript/config.json`. @@ -67,16 +90,30 @@ is called `gptscript-credential-wincred.exe`.) There will likely be support added for other credential stores in the future. :::note -Credentials received from credential provider tools that are not on GitHub (such as a local file) will not be stored -in the credentials store. +Credentials received from credential provider tools that are not on GitHub (such as a local file) and do not have an alias +will not be stored in the credentials store. ::: +## Credential Aliases + +When you reference a credential tool in your script, you can give it an alias using the `as` keyword like this: + +```yaml +credentials: my-credential-tool.gpt as myAlias + +(tool stuff here) +``` + +This will store the resulting credential with the name `myAlias`. +This is useful when you want to reference the same credential tool in scripts that need to handle different credentials, +or when you want to store credentials that were provided by a tool that is not on GitHub. + ## Credential Contexts -Each stored credential is uniquely identified by the name of its provider tool and the name of its context. A credential -context is basically a namespace for credentials. If you have multiple credentials from the same provider tool, you can -switch between them by defining them in different credential contexts. The default context is called `default`, and this -is used if none is specified. +Each stored credential is uniquely identified by the name of its provider tool (or alias, if one was specified) and the name of its context. +A credential context is basically a namespace for credentials. If you have multiple credentials from the same provider tool, +you can switch between them by defining them in different credential contexts. The default context is called `default`, +and this is used if none is specified. You can set the credential context to use with the `--credential-context` flag when running GPTScript. For example: @@ -97,13 +134,17 @@ credentials in all contexts with `--all-contexts`. You can delete a credential by running the following command: ```bash -gptscript credential delete --credential-context +gptscript credential delete --credential-context ``` The `--show-env-vars` argument will also display the names of the environment variables that are set by the credential. This is useful when working with credential overrides. -## Credential Overrides +## Credential Overrides (Advanced) + +:::note +The syntax for this will change at some point in the future. +::: You can bypass credential tools and stored credentials by setting the `--credential-override` argument (or the `GPTSCRIPT_CREDENTIAL_OVERRIDE` environment variable) when running GPTScript. To set up a credential override, you diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index d0d1585f..8950b54e 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -138,7 +138,7 @@ func isParam(line string, tool *types.Tool) (_ bool, err error) { return false, err } case "credentials", "creds", "credential", "cred": - tool.Parameters.Credentials = append(tool.Parameters.Credentials, csv(strings.ToLower(value))...) + tool.Parameters.Credentials = append(tool.Parameters.Credentials, csv(value)...) default: return false, nil } diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index b881247b..90c589f4 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -816,17 +816,27 @@ func (r *Runner) handleCredentials(callCtx engine.Context, monitor Monitor, env continue } + toolName, credentialAlias, args, err := types.ParseCredentialArgs(credToolName, callCtx.Input) + if err != nil { + return nil, fmt.Errorf("failed to parse credential tool %q: %w", credToolName, err) + } + var ( cred *credentials.Credential exists bool - err error ) - // Only try to look up the cred if the tool is on GitHub. - if isGitHubTool(credToolName) { - cred, exists, err = store.Get(credToolName) + // Only try to look up the cred if the tool is on GitHub or has an alias. + // If it is a GitHub tool and has an alias, the alias overrides the tool name, so we use it as the credential name. + if isGitHubTool(toolName) && credentialAlias == "" { + cred, exists, err = store.Get(toolName) if err != nil { - return nil, fmt.Errorf("failed to get credentials for tool %s: %w", credToolName, err) + return nil, fmt.Errorf("failed to get credentials for tool %s: %w", toolName, err) + } + } else if credentialAlias != "" { + cred, exists, err = store.Get(credentialAlias) + if err != nil { + return nil, fmt.Errorf("failed to get credentials for tool %s: %w", credentialAlias, err) } } @@ -838,12 +848,21 @@ func (r *Runner) handleCredentials(callCtx engine.Context, monitor Monitor, env return nil, fmt.Errorf("failed to find ID for tool %s", credToolName) } - subCtx, err := callCtx.SubCall(callCtx.Ctx, "", credToolRefs[0].ToolID, "", engine.CredentialToolCategory) // leaving callID as "" will cause it to be set by the engine + input := "" + if args != nil { + inputBytes, err := json.Marshal(args) + if err != nil { + return nil, fmt.Errorf("failed to marshal args for tool %s: %w", credToolName, err) + } + input = string(inputBytes) + } + + subCtx, err := callCtx.SubCall(callCtx.Ctx, input, credToolRefs[0].ToolID, "", engine.CredentialToolCategory) // leaving callID as "" will cause it to be set by the engine if err != nil { return nil, fmt.Errorf("failed to create subcall context for tool %s: %w", credToolName, err) } - res, err := r.call(subCtx, monitor, env, "") + res, err := r.call(subCtx, monitor, env, input) if err != nil { return nil, fmt.Errorf("failed to run credential tool %s: %w", credToolName, err) } @@ -860,9 +879,13 @@ func (r *Runner) handleCredentials(callCtx engine.Context, monitor Monitor, env } cred = &credentials.Credential{ - ToolName: credToolName, - Type: credentials.CredentialTypeTool, - Env: envMap.Env, + Type: credentials.CredentialTypeTool, + Env: envMap.Env, + } + if credentialAlias != "" { + cred.ToolName = credentialAlias + } else { + cred.ToolName = toolName } isEmpty := true @@ -873,15 +896,15 @@ func (r *Runner) handleCredentials(callCtx engine.Context, monitor Monitor, env } } - // Only store the credential if the tool is on GitHub, and the credential is non-empty. - if isGitHubTool(credToolName) && callCtx.Program.ToolSet[credToolRefs[0].ToolID].Source.Repo != nil { + // Only store the credential if the tool is on GitHub or has an alias, and the credential is non-empty. + if (isGitHubTool(toolName) && callCtx.Program.ToolSet[credToolRefs[0].ToolID].Source.Repo != nil) || credentialAlias != "" { if isEmpty { - log.Warnf("Not saving empty credential for tool %s", credToolName) + log.Warnf("Not saving empty credential for tool %s", toolName) } else if err := store.Add(*cred); err != nil { - return nil, fmt.Errorf("failed to add credential for tool %s: %w", credToolName, err) + return nil, fmt.Errorf("failed to add credential for tool %s: %w", toolName, err) } } else { - log.Warnf("Not saving credential for local tool %s - credentials will only be saved for tools from GitHub.", credToolName) + log.Warnf("Not saving credential for tool %s - credentials will only be saved for tools from GitHub, or tools that use aliases.", toolName) } } diff --git a/pkg/types/credential_test.go b/pkg/types/credential_test.go new file mode 100644 index 00000000..95cc7f1b --- /dev/null +++ b/pkg/types/credential_test.go @@ -0,0 +1,153 @@ +package types + +import "testing" + +func TestParseCredentialArgs(t *testing.T) { + tests := []struct { + name string + toolName string + input string + expectedName string + expectedAlias string + expectedArgs map[string]string + wantErr bool + }{ + { + name: "empty", + toolName: "", + expectedName: "", + expectedAlias: "", + }, + { + name: "tool name only", + toolName: "myCredentialTool", + expectedName: "myCredentialTool", + expectedAlias: "", + }, + { + name: "tool name and alias", + toolName: "myCredentialTool as myAlias", + expectedName: "myCredentialTool", + expectedAlias: "myAlias", + }, + { + name: "tool name with one arg", + toolName: "myCredentialTool with value1 as arg1", + expectedName: "myCredentialTool", + expectedAlias: "", + expectedArgs: map[string]string{ + "arg1": "value1", + }, + }, + { + name: "tool name with two args", + toolName: "myCredentialTool with value1 as arg1 and value2 as arg2", + expectedName: "myCredentialTool", + expectedAlias: "", + expectedArgs: map[string]string{ + "arg1": "value1", + "arg2": "value2", + }, + }, + { + name: "tool name with alias and one arg", + toolName: "myCredentialTool as myAlias with value1 as arg1", + expectedName: "myCredentialTool", + expectedAlias: "myAlias", + expectedArgs: map[string]string{ + "arg1": "value1", + }, + }, + { + name: "tool name with alias and two args", + toolName: "myCredentialTool as myAlias with value1 as arg1 and value2 as arg2", + expectedName: "myCredentialTool", + expectedAlias: "myAlias", + expectedArgs: map[string]string{ + "arg1": "value1", + "arg2": "value2", + }, + }, + { + name: "tool name with quoted args", + toolName: `myCredentialTool with "value one" as arg1 and "value two" as arg2`, + expectedName: "myCredentialTool", + expectedAlias: "", + expectedArgs: map[string]string{ + "arg1": "value one", + "arg2": "value two", + }, + }, + { + name: "tool name with arg references", + toolName: `myCredentialTool with ${var1} as arg1 and ${var2} as arg2`, + input: `{"var1": "value1", "var2": "value2"}`, + expectedName: "myCredentialTool", + expectedAlias: "", + expectedArgs: map[string]string{ + "arg1": "value1", + "arg2": "value2", + }, + }, + { + name: "tool name with alias but no 'as' (invalid)", + toolName: "myCredentialTool myAlias", + wantErr: true, + }, + { + name: "tool name with 'as' but no alias (invalid)", + toolName: "myCredentialTool as", + wantErr: true, + }, + { + name: "tool with 'with' but no args (invalid)", + toolName: "myCredentialTool with", + wantErr: true, + }, + { + name: "tool with args but no 'with' (invalid)", + toolName: "myCredentialTool value1 as arg1", + wantErr: true, + }, + { + name: "tool with trailing 'and' (invalid)", + toolName: "myCredentialTool with value1 as arg1 and", + wantErr: true, + }, + { + name: "tool with quoted arg but the quote is unterminated (invalid)", + toolName: `myCredentialTool with "value one" as arg1 and "value two as arg2`, + wantErr: true, + }, + { + name: "invalid input", + toolName: "myCredentialTool", + input: `{"asdf":"asdf"`, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + originalName, alias, args, err := ParseCredentialArgs(tt.toolName, tt.input) + if (err != nil) != tt.wantErr { + t.Errorf("ParseCredentialArgs() error = %v, wantErr %v", err, tt.wantErr) + return + } + if originalName != tt.expectedName { + t.Errorf("ParseCredentialArgs() originalName = %v, expectedName %v", originalName, tt.expectedName) + } + if alias != tt.expectedAlias { + t.Errorf("ParseCredentialArgs() alias = %v, expectedAlias %v", alias, tt.expectedAlias) + } + if len(args) != len(tt.expectedArgs) { + t.Errorf("ParseCredentialArgs() args = %v, expectedArgs %v", args, tt.expectedArgs) + } + for k, v := range tt.expectedArgs { + if args[k] != v { + t.Errorf("ParseCredentialArgs() args[%s] = %v, expectedArgs[%s] %v", k, args[k], k, v) + } + } + }) + } +} diff --git a/pkg/types/tool.go b/pkg/types/tool.go index ab921279..2c218e2c 100644 --- a/pkg/types/tool.go +++ b/pkg/types/tool.go @@ -2,6 +2,7 @@ package types import ( "context" + "encoding/json" "fmt" "path/filepath" "slices" @@ -9,6 +10,7 @@ import ( "strings" "github.com/getkin/kin-openapi/openapi3" + "github.com/google/shlex" "github.com/gptscript-ai/gptscript/pkg/system" "golang.org/x/exp/maps" ) @@ -193,14 +195,20 @@ func (t *Tool) AddToolMapping(name string, tool Tool) { }) } +// SplitArg splits a tool string into the tool name and arguments, and discards the alias if there is one. +// Examples: +// toolName => toolName, "" +// toolName as myAlias => toolName, "" +// toolName with value1 as arg1 and value2 as arg2 => toolName, "value1 as arg1 and value2 as arg2" +// toolName as myAlias with value1 as arg1 and value2 as arg2 => toolName, "value1 as arg1 and value2 as arg2" func SplitArg(hasArg string) (prefix, arg string) { var ( - fields = strings.Fields(hasArg) - idx = slices.Index(fields, "with") - asIdx = slices.Index(fields, "as") + fields = strings.Fields(hasArg) + withIdx = slices.Index(fields, "with") + asIdx = slices.Index(fields, "as") ) - if idx == -1 { + if withIdx == -1 { if asIdx != -1 { return strings.Join(fields[:asIdx], " "), strings.Join(fields[asIdx:], " ") @@ -208,8 +216,112 @@ func SplitArg(hasArg string) (prefix, arg string) { return strings.TrimSpace(hasArg), "" } - return strings.Join(fields[:idx], " "), - strings.Join(fields[idx+1:], " ") + if asIdx != -1 && asIdx < withIdx { + return strings.Join(fields[:asIdx], " "), + strings.Join(fields[withIdx+1:], " ") + } + + return strings.Join(fields[:withIdx], " "), + strings.Join(fields[withIdx+1:], " ") +} + +// ParseCredentialArgs parses a credential tool name + args into a tool alias (if there is one) and a map of args. +// Example: "toolName as myCredential with value1 as arg1 and value2 as arg2" -> toolName, myCredential, map[string]any{"arg1": "value1", "arg2": "value2"}, nil +// +// Arg references will be resolved based on the input. +// Example: +// - toolName: "toolName with ${var1} as arg1 and ${var2} as arg2" +// - input: `{"var1": "value1", "var2": "value2"}` +// result: toolName, "", map[string]any{"arg1": "value1", "arg2": "value2"}, nil +func ParseCredentialArgs(toolName string, input string) (string, string, map[string]any, error) { + if toolName == "" { + return "", "", nil, nil + } + + inputMap := make(map[string]any) + if input != "" { + err := json.Unmarshal([]byte(input), &inputMap) + if err != nil { + return "", "", nil, fmt.Errorf("failed to unmarshal input: %w", err) + } + } + + fields, err := shlex.Split(toolName) + if err != nil { + return "", "", nil, err + } + + // If it's just the tool name, return it + if len(fields) == 1 { + return toolName, "", nil, nil + } + + // Next field is "as" if there is an alias, otherwise it should be "with" + originalName := fields[0] + alias := "" + fields = fields[1:] + if fields[0] == "as" { + if len(fields) < 2 { + return "", "", nil, fmt.Errorf("expected alias after 'as'") + } + alias = fields[1] + fields = fields[2:] + } + + if len(fields) == 0 { // Nothing left, so just return + return originalName, alias, nil, nil + } + + // Next we should have "with" followed by the args + if fields[0] != "with" { + return "", "", nil, fmt.Errorf("expected 'with' but got %s", fields[0]) + } + fields = fields[1:] + + // If there are no args, return an error + if len(fields) == 0 { + return "", "", nil, fmt.Errorf("expected args after 'with'") + } + + args := make(map[string]any) + prev := "none" // "none", "value", "as", "name", or "and" + argValue := "" + for _, field := range fields { + switch prev { + case "none", "and": + argValue = field + prev = "value" + case "value": + if field != "as" { + return "", "", nil, fmt.Errorf("expected 'as' but got %s", field) + } + prev = "as" + case "as": + args[field] = argValue + prev = "name" + case "name": + if field != "and" { + return "", "", nil, fmt.Errorf("expected 'and' but got %s", field) + } + prev = "and" + } + } + + if prev == "and" { + return "", "", nil, fmt.Errorf("expected arg name after 'and'") + } + + // Check and see if any of the arg values are references to an input + for k, v := range args { + if strings.HasPrefix(v.(string), "${") && strings.HasSuffix(v.(string), "}") { + key := strings.TrimSuffix(strings.TrimPrefix(v.(string), "${"), "}") + if val, ok := inputMap[key]; ok { + args[k] = val.(string) + } + } + } + + return originalName, alias, args, nil } func (t Tool) GetToolRefsFromNames(names []string) (result []ToolReference, _ error) { From fe56699094630677b82db37e52b4e8fbaa785894 Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Thu, 6 Jun 2024 11:45:32 -0400 Subject: [PATCH 2/9] PR feedback Signed-off-by: Grant Linville --- pkg/runner/runner.go | 2 +- pkg/types/credential_test.go | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 90c589f4..01d90bde 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -848,7 +848,7 @@ func (r *Runner) handleCredentials(callCtx engine.Context, monitor Monitor, env return nil, fmt.Errorf("failed to find ID for tool %s", credToolName) } - input := "" + var input string if args != nil { inputBytes, err := json.Marshal(args) if err != nil { diff --git a/pkg/types/credential_test.go b/pkg/types/credential_test.go index 95cc7f1b..74e74e55 100644 --- a/pkg/types/credential_test.go +++ b/pkg/types/credential_test.go @@ -1,6 +1,11 @@ package types -import "testing" +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) func TestParseCredentialArgs(t *testing.T) { tests := []struct { @@ -130,23 +135,18 @@ func TestParseCredentialArgs(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { originalName, alias, args, err := ParseCredentialArgs(tt.toolName, tt.input) - if (err != nil) != tt.wantErr { - t.Errorf("ParseCredentialArgs() error = %v, wantErr %v", err, tt.wantErr) + if tt.wantErr { + require.Error(t, err, "expected an error but got none") return } - if originalName != tt.expectedName { - t.Errorf("ParseCredentialArgs() originalName = %v, expectedName %v", originalName, tt.expectedName) - } - if alias != tt.expectedAlias { - t.Errorf("ParseCredentialArgs() alias = %v, expectedAlias %v", alias, tt.expectedAlias) - } - if len(args) != len(tt.expectedArgs) { - t.Errorf("ParseCredentialArgs() args = %v, expectedArgs %v", args, tt.expectedArgs) - } + + require.NoError(t, err, "did not expect an error but got one") + require.Equal(t, tt.expectedName, originalName, "unexpected original name") + require.Equal(t, tt.expectedAlias, alias, "unexpected alias") + require.Equal(t, len(tt.expectedArgs), len(args), "unexpected number of args") + for k, v := range tt.expectedArgs { - if args[k] != v { - t.Errorf("ParseCredentialArgs() args[%s] = %v, expectedArgs[%s] %v", k, args[k], k, v) - } + assert.Equal(t, v, args[k], "unexpected value for args[%s]", k) } }) } From a7e0ee752a90a24530085ab52812c38731901ce5 Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Thu, 6 Jun 2024 12:16:46 -0400 Subject: [PATCH 3/9] don't parse creds as comma separated Signed-off-by: Grant Linville --- docs/docs/03-tools/04-credentials.md | 5 +++-- pkg/parser/parser.go | 2 +- test.gpt | 4 ++++ 3 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 test.gpt diff --git a/docs/docs/03-tools/04-credentials.md b/docs/docs/03-tools/04-credentials.md index 15d41a6e..a984db8e 100644 --- a/docs/docs/03-tools/04-credentials.md +++ b/docs/docs/03-tools/04-credentials.md @@ -41,10 +41,11 @@ LLM about it or even tell the LLM about the tool. If GPTScript has called the credential provider tool in the same context (more on that later), then it will use the stored credential instead of fetching it again. -You can also specify multiple credential tools for the same script: +You can also specify multiple credential tools for the same script, but they must be on separate lines: ```yaml -credentials: credential-tool-1.gpt, credential-tool-2.gpt +credentials: credential-tool-1.gpt +credentials: credential-tool-2.gpt (tool stuff here) ``` diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index 8950b54e..6ffc96de 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -138,7 +138,7 @@ func isParam(line string, tool *types.Tool) (_ bool, err error) { return false, err } case "credentials", "creds", "credential", "cred": - tool.Parameters.Credentials = append(tool.Parameters.Credentials, csv(value)...) + tool.Parameters.Credentials = append(tool.Parameters.Credentials, value) default: return false, nil } diff --git a/test.gpt b/test.gpt new file mode 100644 index 00000000..7ebec07b --- /dev/null +++ b/test.gpt @@ -0,0 +1,4 @@ +cred: github.com/g-linville/credential as mycred1 with hey as message and hey as field and HEY as env +cred: github.com/g-linville/credential as mycred2 with yo as message and yo as field and YO as env + +echo hello From c68506ae348ff09c7f0fc05d5dac14b1167a0fe9 Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Thu, 6 Jun 2024 12:26:00 -0400 Subject: [PATCH 4/9] bump golangci-lint version Signed-off-by: Grant Linville --- Makefile | 2 +- test.gpt | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) delete mode 100644 test.gpt diff --git a/Makefile b/Makefile index 409b4752..ba773c21 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ tidy: test: go test -v ./... -GOLANGCI_LINT_VERSION ?= v1.56.1 +GOLANGCI_LINT_VERSION ?= v1.59.0 lint: if ! command -v golangci-lint &> /dev/null; then \ echo "Could not find golangci-lint, installing version $(GOLANGCI_LINT_VERSION)."; \ diff --git a/test.gpt b/test.gpt deleted file mode 100644 index 7ebec07b..00000000 --- a/test.gpt +++ /dev/null @@ -1,4 +0,0 @@ -cred: github.com/g-linville/credential as mycred1 with hey as message and hey as field and HEY as env -cred: github.com/g-linville/credential as mycred2 with yo as message and yo as field and YO as env - -echo hello From e8ac8062ebd44c88b6a05c77ad7051ae2446b828 Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Thu, 6 Jun 2024 12:42:09 -0400 Subject: [PATCH 5/9] update golangci config Signed-off-by: Grant Linville --- .golangci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index d6c2eedc..0446f9f8 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -3,7 +3,7 @@ run: output: formats: - - github-actions + - format: github-actions linters: disable-all: true From b480699c51c0a35425768ffeba19949d8c64f88c Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Thu, 6 Jun 2024 12:43:34 -0400 Subject: [PATCH 6/9] update golangci config Signed-off-by: Grant Linville --- .golangci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index 0446f9f8..e91a9ccc 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -3,7 +3,7 @@ run: output: formats: - - format: github-actions + - format: colored-line-number linters: disable-all: true From f22fcbe165d3a9fe933021925a0753cb3ecc0419 Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Thu, 6 Jun 2024 12:48:30 -0400 Subject: [PATCH 7/9] skip make validate on windows Signed-off-by: Grant Linville --- .github/workflows/test.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 039d8d4d..9eeb7c91 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -33,7 +33,10 @@ jobs: fi shell: bash - name: Validate - run: make validate + run: | + if [ ${{ matrix.os }} != 'windows-latest' ]; then + make validate + fi - name: Build run: make build - name: Run Tests From dd2936b6619d8a77474d5ff8dd67bb95c6483812 Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Thu, 6 Jun 2024 12:51:10 -0400 Subject: [PATCH 8/9] fix GH workflow Signed-off-by: Grant Linville --- .github/workflows/test.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 9eeb7c91..9d361404 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -33,10 +33,8 @@ jobs: fi shell: bash - name: Validate - run: | - if [ ${{ matrix.os }} != 'windows-latest' ]; then - make validate - fi + if: matrix.os == 'ubuntu-22.04' + run: make validate - name: Build run: make build - name: Run Tests From be307ebc489eab32b8c5fbf5cabe56a5a0fbd612 Mon Sep 17 00:00:00 2001 From: Grant Linville Date: Thu, 6 Jun 2024 12:53:03 -0400 Subject: [PATCH 9/9] fix GH workflow Signed-off-by: Grant Linville --- .github/workflows/test.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 9d361404..1d5c1470 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -27,10 +27,8 @@ jobs: cache: false go-version: "1.21" - name: Build UI - run: | - if [ ${{ matrix.os }} != 'windows-latest' ]; then - make build-ui - fi + if: matrix.os == 'ubuntu-22.04' + run: make build-ui shell: bash - name: Validate if: matrix.os == 'ubuntu-22.04'