@@ -19,6 +19,7 @@ package cluster
19
19
import (
20
20
"context"
21
21
"encoding/base64"
22
+ "fmt"
22
23
"io"
23
24
"net/http"
24
25
"net/url"
@@ -180,37 +181,58 @@ func (t *templateClient) getGitHubFileContent(rURL *url.URL) ([]byte, error) {
180
181
urlSplit := strings .Split (strings .TrimPrefix (rURL .Path , "/" ), "/" )
181
182
if len (urlSplit ) < 5 {
182
183
return nil , errors .Errorf (
183
- "invalid GitHub url %q: a GitHub url should be in the form https://github.com/{owner}/{repository}/blob/{branch}/{path-to-file}" , rURL ,
184
+ "invalid GitHub url %q: a GitHub url should be in on of these the forms\n " +
185
+ "- https://github.com/{owner}/{repository}/blob/{branch}/{path-to-file}\n " +
186
+ "- https://github.com/{owner}/{repository}/releases/download/{tag}/{asset-file-name}" , rURL ,
184
187
)
185
188
}
186
189
187
190
// Extract all the info from url split.
188
191
owner := urlSplit [0 ]
189
- repository := urlSplit [1 ]
190
- branch := urlSplit [3 ]
191
- path := strings .Join (urlSplit [4 :], "/" )
192
+ repo := urlSplit [1 ]
193
+ linkType := urlSplit [2 ]
192
194
193
195
// gets the GitHub client
194
- client , err := t .gitHubClientFactory (t .configClient .Variables ())
196
+ ghClient , err := t .gitHubClientFactory (t .configClient .Variables ())
195
197
if err != nil {
196
198
return nil , err
197
199
}
198
200
199
201
// gets the file from GiHub
200
- fileContent , _ , _ , err := client .Repositories .GetContents (context .TODO (), owner , repository , path , & github.RepositoryContentGetOptions {Ref : branch })
202
+ switch linkType {
203
+ case "blob" : // get file from a code in a github repo
204
+ branch := urlSplit [3 ]
205
+ path := strings .Join (urlSplit [4 :], "/" )
206
+
207
+ return getGithubFileContentFromCode (ghClient , rURL .Path , owner , repo , path , branch )
208
+
209
+ case "releases" : // get a github release asset
210
+ if urlSplit [3 ] != "download" {
211
+ break
212
+ }
213
+ tag := urlSplit [4 ]
214
+ assetName := urlSplit [5 ]
215
+
216
+ return getGithubAssetFromRelease (ghClient , rURL .Path , owner , repo , tag , assetName )
217
+ }
218
+
219
+ return nil , fmt .Errorf ("unknown github URL: %v" , rURL )
220
+ }
221
+
222
+ func getGithubFileContentFromCode (ghClient * github.Client , fullPath string , owner string , repo string , path string , branch string ) ([]byte , error ) {
223
+ fileContent , _ , _ , err := ghClient .Repositories .GetContents (ctx , owner , repo , path , & github.RepositoryContentGetOptions {Ref : branch })
201
224
if err != nil {
202
- return nil , handleGithubErr (err , "failed to get %q" , rURL . Path )
225
+ return nil , handleGithubErr (err , "failed to get %q" , fullPath )
203
226
}
204
227
if fileContent == nil {
205
- return nil , errors .Errorf ("%q does not return a valid file content" , rURL . Path )
228
+ return nil , errors .Errorf ("%q does not return a valid file content" , fullPath )
206
229
}
207
230
if fileContent .Encoding == nil || * fileContent .Encoding != "base64" {
208
- return nil , errors .Errorf ("invalid encoding detected for %q. Only base64 encoding supported" , rURL . Path )
231
+ return nil , errors .Errorf ("invalid encoding detected for %q. Only base64 encoding supported" , fullPath )
209
232
}
210
-
211
233
content , err := base64 .StdEncoding .DecodeString (* fileContent .Content )
212
234
if err != nil {
213
- return nil , errors .Wrapf (err , "failed to decode file %q" , rURL . Path )
235
+ return nil , errors .Wrapf (err , "failed to decode file %q" , fullPath )
214
236
}
215
237
return content , nil
216
238
}
@@ -239,6 +261,36 @@ func (t *templateClient) getRawURLFileContent(rURL string) ([]byte, error) {
239
261
return content , nil
240
262
}
241
263
264
+ func getGithubAssetFromRelease (ghClient * github.Client , path string , owner string , repo string , tag string , assetName string ) ([]byte , error ) {
265
+ release , _ , err := ghClient .Repositories .GetReleaseByTag (ctx , owner , repo , tag )
266
+ if err != nil {
267
+ return nil , handleGithubErr (err , "failed to get release '%s' from %s/%s repository" , tag , owner , repo )
268
+ }
269
+
270
+ if release == nil {
271
+ return nil , fmt .Errorf ("can't find release '%s' in %s/%s repository" , tag , owner , repo )
272
+ }
273
+
274
+ var rc io.ReadCloser
275
+ for _ , asset := range release .Assets {
276
+ if asset .GetName () == assetName {
277
+ rc , _ , err = ghClient .Repositories .DownloadReleaseAsset (ctx , owner , repo , asset .GetID (), ghClient .Client ())
278
+ if err != nil {
279
+ return nil , errors .Wrapf (err , "failed to download file %q" , path )
280
+ }
281
+ break
282
+ }
283
+ }
284
+
285
+ if rc == nil {
286
+ return nil , fmt .Errorf ("failed to download the file %q" , path )
287
+ }
288
+
289
+ defer func () { _ = rc .Close () }()
290
+
291
+ return io .ReadAll (rc )
292
+ }
293
+
242
294
func getGitHubClient (configVariablesClient config.VariablesClient ) (* github.Client , error ) {
243
295
var authenticatingHTTPClient * http.Client
244
296
if token , err := configVariablesClient .Get (config .GitHubTokenVariable ); err == nil {
0 commit comments