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