@@ -19,7 +19,10 @@ package plugin
1919import (
2020 "bufio"
2121 "context"
22+ "encoding/json"
2223 "fmt"
24+ "io"
25+ "net/http"
2326 "os"
2427 "os/exec"
2528 "runtime"
@@ -67,17 +70,32 @@ type DevOptions struct {
6770 KindNetwork string
6871}
6972
73+ // assetVersion is the version of the kube-bind backend assets used in dev mode
74+ var assetVersion = ""
75+
76+ // fallbackAssetVersion is used when unable to fetch the latest version
77+ var fallbackAssetVersion = "0.6.0"
78+
79+ // GitHubRelease represents a GitHub release response
80+ type GitHubRelease struct {
81+ TagName string `json:"tag_name"`
82+ }
83+
7084// NewDevOptions creates a new DevOptions
7185func NewDevOptions (streams genericclioptions.IOStreams ) * DevOptions {
7286 opts := base .NewOptions (streams )
87+ // Initialize assetVersion with fallback if not set
88+ if assetVersion == "" {
89+ assetVersion = fallbackAssetVersion
90+ }
7391 return & DevOptions {
7492 Options : opts ,
7593 Logs : logs .NewOptions (),
7694 Streams : streams ,
7795 ProviderClusterName : "kind-provider" ,
7896 ConsumerClusterName : "kind-consumer" ,
7997 ChartPath : "oci://ghcr.io/kube-bind/charts/backend" ,
80- ChartVersion : "v0.6.0" ,
98+ ChartVersion : assetVersion ,
8199 }
82100}
83101
@@ -92,15 +110,74 @@ func (o *DevOptions) AddCmdFlags(cmd *cobra.Command) {
92110 cmd .Flags ().StringVar (& o .ChartPath , "chart-path" , o .ChartPath , "Helm chart path or OCI registry URL" )
93111 cmd .Flags ().StringVar (& o .ChartVersion , "chart-version" , o .ChartVersion , "Helm chart version" )
94112 cmd .Flags ().StringVar (& o .Image , "image" , "ghcr.io/kube-bind/backend" , "kube-bind backend image to use in dev mode" )
95- cmd .Flags ().StringVar (& o .Tag , "tag" , "main" , "kube-bind backend image tag to use in dev mode" )
113+ cmd .Flags ().StringVar (& o .Tag , "tag" , "v" + assetVersion , "kube-bind backend image tag to use in dev mode" )
96114 cmd .Flags ().StringVar (& o .KindNetwork , "kind-network" , "kube-bind-dev" , "kind network to use in dev mode" )
97115}
98116
99117// Complete completes the options
100118func (o * DevOptions ) Complete (args []string ) error {
119+ // Only fetch the latest version if assetVersion is not set
120+ if assetVersion == "" {
121+ version , err := fetchLatestRelease ()
122+ if err != nil {
123+ // Log the error but continue with fallback version
124+ fmt .Fprintf (o .Streams .ErrOut , "Warning: Failed to fetch latest release version: %v. Using fallback version %s\n " , err , fallbackAssetVersion )
125+ assetVersion = fallbackAssetVersion
126+ } else {
127+ assetVersion = version
128+ }
129+
130+ // Update options with the resolved version
131+ if o .ChartVersion == "" || o .ChartVersion == fallbackAssetVersion {
132+ o .ChartVersion = assetVersion
133+ }
134+ if o .Tag == "" || o .Tag == "v" + fallbackAssetVersion {
135+ o .Tag = "v" + assetVersion
136+ }
137+ }
138+
101139 return nil
102140}
103141
142+ // fetchLatestRelease fetches the latest release version from GitHub
143+ func fetchLatestRelease () (string , error ) {
144+ ctx , cancel := context .WithTimeout (context .Background (), 10 * time .Second )
145+ defer cancel ()
146+
147+ req , err := http .NewRequestWithContext (ctx , http .MethodGet , "https://api.github.com/repos/kube-bind/kube-bind/releases/latest" , nil )
148+ if err != nil {
149+ return "" , fmt .Errorf ("failed to create request: %w" , err )
150+ }
151+
152+ resp , err := http .DefaultClient .Do (req )
153+ if err != nil {
154+ return "" , fmt .Errorf ("failed to fetch latest release: %w" , err )
155+ }
156+ defer resp .Body .Close ()
157+
158+ if resp .StatusCode != http .StatusOK {
159+ return "" , fmt .Errorf ("GitHub API returned status %d" , resp .StatusCode )
160+ }
161+
162+ body , err := io .ReadAll (resp .Body )
163+ if err != nil {
164+ return "" , fmt .Errorf ("failed to read response body: %w" , err )
165+ }
166+
167+ var release GitHubRelease
168+ if err := json .Unmarshal (body , & release ); err != nil {
169+ return "" , fmt .Errorf ("failed to parse release data: %w" , err )
170+ }
171+
172+ if release .TagName == "" {
173+ return "" , fmt .Errorf ("no tag name in release data" )
174+ }
175+
176+ // Remove 'v' prefix if present
177+ version := strings .TrimPrefix (release .TagName , "v" )
178+ return version , nil
179+ }
180+
104181// Validate validates the options
105182func (o * DevOptions ) Validate () error {
106183 return o .Options .Validate ()
0 commit comments