diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..103028a --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,31 @@ +name: goreleaser + +on: + pull_request: + push: + +permissions: + contents: write + +jobs: + goreleaser: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - + name: Set up Go + uses: actions/setup-go@v3 + - + name: Run GoReleaser + uses: goreleaser/goreleaser-action@v4 + with: + # either 'goreleaser' (default) or 'goreleaser-pro' + distribution: goreleaser + version: latest + args: release --clean + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index b279ca5..ed76427 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ k8sgpt* -*.vscode \ No newline at end of file +*.vscode +dist/ diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..a65edfe --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,45 @@ +# This is an example .goreleaser.yml file with some sensible defaults. +# Make sure to check the documentation at https://goreleaser.com +before: + hooks: + # You may remove this if you don't use go modules. + - go mod tidy + # you may remove this if you don't need go generate + - go generate ./... +builds: + - env: + - CGO_ENABLED=0 + goos: + - linux + - windows + - darwin + +archives: + - format: tar.gz + # this name template makes the OS and Arch compatible with the results of uname. + name_template: >- + {{ .ProjectName }}_ + {{- title .Os }}_ + {{- if eq .Arch "amd64" }}x86_64 + {{- else if eq .Arch "386" }}i386 + {{- else }}{{ .Arch }}{{ end }} + {{- if .Arm }}v{{ .Arm }}{{ end }} + # use zip for windows archives + format_overrides: + - goos: windows + format: zip +checksum: + name_template: 'checksums.txt' +snapshot: + name_template: "{{ incpatch .Version }}-next" +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' + +# The lines beneath this are called `modelines`. See `:help modeline` +# Feel free to remove those if you don't want/use them. +# yaml-language-server: $schema=https://goreleaser.com/static/schema.json +# vim: set ts=2 sw=2 tw=0 fo=cnqoj diff --git a/README.md b/README.md index b3eb4f8..d24e73a 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,8 @@ It reduces the mystery of kubernetes and makes it easy to understand what is goi ``` k8sgpt auth key -k8sgpt scan +k8sgpt find problems --explain + ``` diff --git a/cmd/find/problems.go b/cmd/find/problems.go index 13f80f3..62d0e5e 100644 --- a/cmd/find/problems.go +++ b/cmd/find/problems.go @@ -14,7 +14,6 @@ import ( "github.com/cloud-native-skunkworks/k8sgpt/pkg/client" "github.com/cloud-native-skunkworks/k8sgpt/pkg/openai" "github.com/fatih/color" - ai "github.com/sashabaranov/go-openai" "github.com/spf13/cobra" "github.com/spf13/viper" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -74,22 +73,15 @@ var problemsCmd = &cobra.Command{ if explain { s := spinner.New(spinner.CharSets[35], 100*time.Millisecond) // Build our new spinner s.Start() - resp, err := openAIClient.GetClient().CreateChatCompletion(ctx, ai.ChatCompletionRequest{ - Model: ai.GPT3Dot5Turbo, - Messages: []ai.ChatCompletionMessage{ - { - Role: "user", - Content: "Simplify the following Kubernetes error message and provide a solution: " + strings.Join(value, " "), - }, - }, - }) + + response, err := openAIClient.GetCompletion(ctx, strings.Join(value, " ")) s.Stop() if err != nil { color.Red("Error: %v", err) return } - color.Green(resp.Choices[0].Message.Content) + color.Green(response) } } diff --git a/go.mod b/go.mod index db45cb9..6029b30 100644 --- a/go.mod +++ b/go.mod @@ -3,15 +3,17 @@ module github.com/cloud-native-skunkworks/k8sgpt go 1.20 require ( + github.com/briandowns/spinner v1.23.0 github.com/fatih/color v1.15.0 + github.com/sashabaranov/go-openai v1.5.4 github.com/spf13/cobra v1.6.1 github.com/spf13/viper v1.15.0 golang.org/x/term v0.6.0 + k8s.io/apimachinery v0.26.3 k8s.io/client-go v0.26.3 ) require ( - github.com/briandowns/spinner v1.23.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect @@ -38,7 +40,6 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect - github.com/sashabaranov/go-openai v1.5.4 // indirect github.com/spf13/afero v1.9.3 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect @@ -56,7 +57,6 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/api v0.26.3 // indirect - k8s.io/apimachinery v0.26.3 // indirect k8s.io/klog/v2 v2.80.1 // indirect k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect k8s.io/utils v0.0.0-20221107191617-1a15be271d1d // indirect diff --git a/pkg/openai/openai.go b/pkg/openai/openai.go index 819aaed..30cd69e 100644 --- a/pkg/openai/openai.go +++ b/pkg/openai/openai.go @@ -1,6 +1,7 @@ package openai import ( + "context" "fmt" "github.com/sashabaranov/go-openai" @@ -14,6 +15,7 @@ type Client struct { func (c *Client) GetClient() *openai.Client { return c.client } + func NewClient() (*Client, error) { // get the token with viper @@ -28,3 +30,20 @@ func NewClient() (*Client, error) { client: client, }, nil } + +func (c *Client) GetCompletion(ctx context.Context, prompt string) (string, error) { + // Create a completion request + resp, err := c.client.CreateChatCompletion(ctx, openai.ChatCompletionRequest{ + Model: openai.GPT3Dot5Turbo, + Messages: []openai.ChatCompletionMessage{ + { + Role: "user", + Content: "Simplify the following Kubernetes error message and provide a solution: " + prompt, + }, + }, + }) + if err != nil { + return "", err + } + return resp.Choices[0].Message.Content, nil +}