github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/run/shared/artifacts.go (about) 1 package shared 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "regexp" 8 9 "github.com/ungtb10d/cli/v2/api" 10 "github.com/ungtb10d/cli/v2/internal/ghinstance" 11 "github.com/ungtb10d/cli/v2/internal/ghrepo" 12 ) 13 14 type Artifact struct { 15 Name string `json:"name"` 16 Size uint64 `json:"size_in_bytes"` 17 DownloadURL string `json:"archive_download_url"` 18 Expired bool `json:"expired"` 19 } 20 21 type artifactsPayload struct { 22 Artifacts []Artifact 23 } 24 25 func ListArtifacts(httpClient *http.Client, repo ghrepo.Interface, runID string) ([]Artifact, error) { 26 var results []Artifact 27 28 perPage := 100 29 path := fmt.Sprintf("repos/%s/%s/actions/artifacts?per_page=%d", repo.RepoOwner(), repo.RepoName(), perPage) 30 if runID != "" { 31 path = fmt.Sprintf("repos/%s/%s/actions/runs/%s/artifacts?per_page=%d", repo.RepoOwner(), repo.RepoName(), runID, perPage) 32 } 33 34 url := fmt.Sprintf("%s%s", ghinstance.RESTPrefix(repo.RepoHost()), path) 35 36 for { 37 var payload artifactsPayload 38 nextURL, err := apiGet(httpClient, url, &payload) 39 if err != nil { 40 return nil, err 41 } 42 results = append(results, payload.Artifacts...) 43 44 if nextURL == "" { 45 break 46 } 47 url = nextURL 48 } 49 50 return results, nil 51 } 52 53 func apiGet(httpClient *http.Client, url string, data interface{}) (string, error) { 54 req, err := http.NewRequest("GET", url, nil) 55 if err != nil { 56 return "", err 57 } 58 59 resp, err := httpClient.Do(req) 60 if err != nil { 61 return "", err 62 } 63 defer resp.Body.Close() 64 65 if resp.StatusCode > 299 { 66 return "", api.HandleHTTPError(resp) 67 } 68 69 dec := json.NewDecoder(resp.Body) 70 if err := dec.Decode(data); err != nil { 71 return "", err 72 } 73 74 return findNextPage(resp), nil 75 } 76 77 var linkRE = regexp.MustCompile(`<([^>]+)>;\s*rel="([^"]+)"`) 78 79 func findNextPage(resp *http.Response) string { 80 for _, m := range linkRE.FindAllStringSubmatch(resp.Header.Get("Link"), -1) { 81 if len(m) > 2 && m[2] == "next" { 82 return m[1] 83 } 84 } 85 return "" 86 }