Skip to content

Commit

Permalink
release (#23)
Browse files Browse the repository at this point in the history
* added goreleaser

* makefile

* working on lint errs

* lint

* added lint workflow

* update workflow

* ignoring preflight for now

* lint

* lint again

* reverse that lint lol
  • Loading branch information
ishandhanani authored Sep 26, 2024
1 parent d3c7752 commit e41ce2c
Show file tree
Hide file tree
Showing 16 changed files with 241 additions and 84 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: lint

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version-file: go.mod

- name: Install dependencies
run: go mod download

- name: Install deps
run: make deps-lint

- name: lint
run: make lint
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
nvcf
deploy.yaml

dist/
3 changes: 3 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
run:
skip-files:
- "preflight/containerutil/container_smoketest_grpc.go"
55 changes: 55 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com

# The lines below are called `modelines`. See `:help modeline`
# Feel free to remove those if you don't want/need to use them.
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj

version: 2

before:
hooks:
- go mod tidy

builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin

brews:
- name: nvcf
homepage: https://github.com/brevdev/nvcf
description: CLI tool for working with NVIDIA cloud functions
repository:
name: tap
owner: brevdev
name: homebrew-nvcf
commit_author:
name: github-actions
email: 41898282+github-actions[bot]@users.noreply.github.com

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

changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,11 @@ docs:
cleandocs:
rm -rf ./docs

dry-release:
goreleaser release --snapshot --clean

release:
goreleaser release

.PHONY: all build clean test check fmt vet lint q deps-lint help

92 changes: 48 additions & 44 deletions cmd/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,50 +46,45 @@ func authLoginCmd() *cobra.Command {
return &cobra.Command{
Use: "login",
Short: "Authenticate with NVIDIA Cloud",
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
apiKey := output.Prompt("Enter your NVIDIA Cloud API key: ", true)

err := config.SetAPIKey(apiKey)
if err != nil {
output.Error(cmd, "Error saving API key", err)
return
return output.Error(cmd, "Error saving API key", err)
}

// Use the API key to get the first org
client := api.NewClient(apiKey)
orgsInfo := map[string]interface{}{}
err = client.Get(cmd.Context(), "/v2/orgs", nil, &orgsInfo)
if err != nil {
output.Error(cmd, "Failed to fetch organization information", err)
return
return output.Error(cmd, "Failed to fetch organization information", err)
}

organizations, ok := orgsInfo["organizations"].([]interface{})
if !ok || len(organizations) == 0 {
output.Error(cmd, "No organizations found", nil)
return
return output.Error(cmd, "No organizations found", nil)
}

firstOrg, ok := organizations[0].(map[string]interface{})
if !ok {
output.Error(cmd, "Failed to parse organization information", nil)
return
return output.Error(cmd, "Failed to parse organization information", nil)
}

orgID, ok := firstOrg["name"].(string)
if !ok {
output.Error(cmd, "Organization ID not found", nil)
return
return output.Error(cmd, "Organization ID not found", nil)
}

err = config.SetOrgID(orgID)
if err != nil {
output.Error(cmd, "Error saving Org ID", err)
return
return output.Error(cmd, "Error saving Org ID", err)
}

output.PrintASCIIArt(cmd)
output.Success(cmd, fmt.Sprintf("Authentication successful. You are now authenticated with organization ID: %s", orgID))
return nil
},
}
}
Expand All @@ -98,29 +93,27 @@ func authConfigureDockerCmd() *cobra.Command {
return &cobra.Command{
Use: "configure-docker",
Short: "Configure Docker to use NGC API key for nvcr.io",
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
apiKey := config.GetAPIKey()
if apiKey == "" {
output.Error(cmd, "NGC API key not found. Please run 'nvcf auth login' first.", nil)
return
return output.Error(cmd, "NGC API key not found. Please run 'nvcf auth login' first.", nil)
}
// Check if Docker is installed
_, err := exec.LookPath("docker")
if err != nil {
output.Error(cmd, "Docker is not installed or not in the system PATH", err)
return
return output.Error(cmd, "Docker is not installed or not in the system PATH", err)
}
// TODO: check for existing nvcr.io config?
dockerCmd := exec.Command("docker", "login", "nvcr.io", "-u", "$oauthtoken", "--password-stdin")
dockerCmd.Stdin = strings.NewReader(apiKey)
out, err := dockerCmd.CombinedOutput()
if err != nil {
output.Error(cmd, "Failed to configure Docker", err)
cmd.Println(string(out))
return
return output.Error(cmd, "Failed to configure Docker", err)
}
output.Success(cmd, "Docker configured successfully for nvcr.io")
cmd.Println(string(out))
return nil
},
}
}
Expand Down Expand Up @@ -165,13 +158,22 @@ func authLogoutCmd() *cobra.Command {
return &cobra.Command{
Use: "logout",
Short: "Logout from NVIDIA Cloud",
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
if !config.IsAuthenticated() {
output.Info(cmd, "You are currently not logged in")
return
return nil
}
err := config.ClearAPIKey()
if err != nil {
return output.Error(cmd, "Failed to clear API key", err)
}
err = config.ClearOrgID()
if err != nil {

return output.Error(cmd, "Failed to clear Org ID", err)
}
config.ClearAPIKey()
output.Success(cmd, "Logged out successfully")
return nil
},
}
}
Expand All @@ -182,19 +184,21 @@ func authWhoAmICmd() *cobra.Command {
return &cobra.Command{
Use: "whoami",
Short: "Display information about the authenticated user",
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
client := api.NewClient(config.GetAPIKey())
whoamiInfo := map[string]any{}
err := client.Get(cmd.Context(), whoamiURL, nil, &whoamiInfo)
if err != nil {
output.Error(cmd, "Failed to fetch user information", err)
return
return output.Error(cmd, "Failed to fetch user information", err)
}

jsonMode, _ := cmd.Flags().GetBool("json")
if jsonMode {
json.NewEncoder(cmd.OutOrStdout()).Encode(whoamiInfo)
return
err = json.NewEncoder(cmd.OutOrStdout()).Encode(whoamiInfo)
if err != nil {
return output.Error(cmd, "Failed to encode user information", err)
}
return nil
}
userInfo, _ := whoamiInfo["user"].(map[string]any)
table := tablewriter.NewWriter(cmd.OutOrStdout())
Expand All @@ -205,6 +209,7 @@ func authWhoAmICmd() *cobra.Command {
userInfo["name"].(string),
})
table.Render()
return nil
},
}
}
Expand All @@ -213,23 +218,24 @@ func authOrgsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "orgs",
Short: "Display organization and team information for the authenticated user",
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
client := api.NewClient(config.GetAPIKey())
userInfo := map[string]interface{}{}
err := client.Get(cmd.Context(), "/v2/users/me", nil, &userInfo)
if err != nil {
output.Error(cmd, "Failed to fetch user information", err)
return
return output.Error(cmd, "Failed to fetch user information", err)
}
jsonMode, _ := cmd.Flags().GetBool("json")
if jsonMode {
json.NewEncoder(cmd.OutOrStdout()).Encode(userInfo)
return
err = json.NewEncoder(cmd.OutOrStdout()).Encode(userInfo)
if err != nil {
return output.Error(cmd, "Failed to encode user information", err)
}
return nil
}
userRoles, ok := userInfo["userRoles"].([]interface{})
if !ok {
output.Error(cmd, "Failed to parse user roles information", nil)
return
return output.Error(cmd, "Failed to parse user roles information", nil)
}
type OrgTeamInfo struct {
OrgName string
Expand Down Expand Up @@ -287,6 +293,7 @@ func authOrgsCmd() *cobra.Command {
}
}
table.Render()
return nil
},
}

Expand All @@ -298,34 +305,31 @@ func authOrgIDCmd() *cobra.Command {
return &cobra.Command{
Use: "org-id",
Short: "Display the name of the first organization",
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
client := api.NewClient(config.GetAPIKey())
orgsInfo := map[string]interface{}{}
err := client.Get(cmd.Context(), "/v2/orgs", nil, &orgsInfo)
if err != nil {
output.Error(cmd, "Failed to fetch organization information", err)
return
return output.Error(cmd, "Failed to fetch organization information", err)
}

organizations, ok := orgsInfo["organizations"].([]interface{})
if !ok || len(organizations) == 0 {
output.Error(cmd, "No organizations found", nil)
return
return output.Error(cmd, "No organizations found", nil)
}

firstOrg, ok := organizations[0].(map[string]interface{})
if !ok {
output.Error(cmd, "Failed to parse organization information", nil)
return
return output.Error(cmd, "Failed to parse organization information", nil)
}

name, ok := firstOrg["name"].(string)
if !ok {
output.Error(cmd, "Organization name not found", nil)
return
return output.Error(cmd, "Organization name not found", nil)
}

fmt.Println(name)
return nil
},
}
}
Expand Down
26 changes: 20 additions & 6 deletions cmd/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"os"

"github.com/brevdev/nvcf/output"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -52,18 +53,31 @@ PowerShell:
DisableFlagsInUseLine: true,
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
Hidden: true,
Args: cobra.ExactValidArgs(1),
Run: func(cmd *cobra.Command, args []string) {
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
switch args[0] {
case "bash":
cmd.Root().GenBashCompletion(os.Stdout)
err := cmd.Root().GenBashCompletion(os.Stdout)
if err != nil {
return output.Error(cmd, "Failed to generate bash completion", err)
}
case "zsh":
cmd.Root().GenZshCompletion(os.Stdout)
err := cmd.Root().GenZshCompletion(os.Stdout)
if err != nil {
return output.Error(cmd, "Failed to generate zsh completion", err)
}
case "fish":
cmd.Root().GenFishCompletion(os.Stdout, true)
err := cmd.Root().GenFishCompletion(os.Stdout, true)
if err != nil {
return output.Error(cmd, "Failed to generate fish completion", err)
}
case "powershell":
cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)
err := cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)
if err != nil {
return output.Error(cmd, "Failed to generate powershell completion", err)
}
}
return nil
},
}

Expand Down
Loading

0 comments on commit e41ce2c

Please sign in to comment.