forked from gitea/gitea
165 lines
5.2 KiB
Go
165 lines
5.2 KiB
Go
// Copyright 2020 The go-github AUTHORS. All rights reserved.
|
|
//
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package github
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
)
|
|
|
|
// Artifact reprents a GitHub artifact. Artifacts allow sharing
|
|
// data between jobs in a workflow and provide storage for data
|
|
// once a workflow is complete.
|
|
//
|
|
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/
|
|
type Artifact struct {
|
|
ID *int64 `json:"id,omitempty"`
|
|
NodeID *string `json:"node_id,omitempty"`
|
|
Name *string `json:"name,omitempty"`
|
|
SizeInBytes *int64 `json:"size_in_bytes,omitempty"`
|
|
ArchiveDownloadURL *string `json:"archive_download_url,omitempty"`
|
|
Expired *bool `json:"expired,omitempty"`
|
|
CreatedAt *Timestamp `json:"created_at,omitempty"`
|
|
ExpiresAt *Timestamp `json:"expires_at,omitempty"`
|
|
}
|
|
|
|
// ArtifactList represents a list of GitHub artifacts.
|
|
//
|
|
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/
|
|
type ArtifactList struct {
|
|
TotalCount *int64 `json:"total_count,omitempty"`
|
|
Artifacts []*Artifact `json:"artifacts,omitempty"`
|
|
}
|
|
|
|
// ListArtifacts lists all artifacts that belong to a repository.
|
|
//
|
|
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#list-artifacts-for-a-repository
|
|
func (s *ActionsService) ListArtifacts(ctx context.Context, owner, repo string, opts *ListOptions) (*ArtifactList, *Response, error) {
|
|
u := fmt.Sprintf("repos/%v/%v/actions/artifacts", owner, repo)
|
|
u, err := addOptions(u, opts)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
req, err := s.client.NewRequest("GET", u, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
artifactList := new(ArtifactList)
|
|
resp, err := s.client.Do(ctx, req, artifactList)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return artifactList, resp, nil
|
|
}
|
|
|
|
// ListWorkflowRunArtifacts lists all artifacts that belong to a workflow run.
|
|
//
|
|
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#list-workflow-run-artifacts
|
|
func (s *ActionsService) ListWorkflowRunArtifacts(ctx context.Context, owner, repo string, runID int64, opts *ListOptions) (*ArtifactList, *Response, error) {
|
|
u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/artifacts", owner, repo, runID)
|
|
u, err := addOptions(u, opts)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
req, err := s.client.NewRequest("GET", u, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
artifactList := new(ArtifactList)
|
|
resp, err := s.client.Do(ctx, req, artifactList)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return artifactList, resp, nil
|
|
}
|
|
|
|
// GetArtifact gets a specific artifact for a workflow run.
|
|
//
|
|
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#get-an-artifact
|
|
func (s *ActionsService) GetArtifact(ctx context.Context, owner, repo string, artifactID int64) (*Artifact, *Response, error) {
|
|
u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v", owner, repo, artifactID)
|
|
|
|
req, err := s.client.NewRequest("GET", u, nil)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
artifact := new(Artifact)
|
|
resp, err := s.client.Do(ctx, req, artifact)
|
|
if err != nil {
|
|
return nil, resp, err
|
|
}
|
|
|
|
return artifact, resp, nil
|
|
}
|
|
|
|
// DownloadArtifact gets a redirect URL to download an archive for a repository.
|
|
//
|
|
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#download-an-artifact
|
|
func (s *ActionsService) DownloadArtifact(ctx context.Context, owner, repo string, artifactID int64, followRedirects bool) (*url.URL, *Response, error) {
|
|
u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v/zip", owner, repo, artifactID)
|
|
|
|
resp, err := s.getDownloadArtifactFromURL(ctx, u, followRedirects)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
if resp.StatusCode != http.StatusFound {
|
|
return nil, newResponse(resp), fmt.Errorf("unexpected status code: %s", resp.Status)
|
|
}
|
|
parsedURL, err := url.Parse(resp.Header.Get("Location"))
|
|
return parsedURL, newResponse(resp), nil
|
|
}
|
|
|
|
func (s *ActionsService) getDownloadArtifactFromURL(ctx context.Context, u string, followRedirects bool) (*http.Response, error) {
|
|
req, err := s.client.NewRequest("GET", u, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var resp *http.Response
|
|
// Use http.DefaultTransport if no custom Transport is configured
|
|
req = withContext(ctx, req)
|
|
if s.client.client.Transport == nil {
|
|
resp, err = http.DefaultTransport.RoundTrip(req)
|
|
} else {
|
|
resp, err = s.client.client.Transport.RoundTrip(req)
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
resp.Body.Close()
|
|
|
|
// If redirect response is returned, follow it
|
|
if followRedirects && resp.StatusCode == http.StatusMovedPermanently {
|
|
u = resp.Header.Get("Location")
|
|
resp, err = s.getDownloadArtifactFromURL(ctx, u, false)
|
|
}
|
|
return resp, err
|
|
}
|
|
|
|
// DeleteArtifact deletes a workflow run artifact.
|
|
//
|
|
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#delete-an-artifact
|
|
func (s *ActionsService) DeleteArtifact(ctx context.Context, owner, repo string, artifactID int64) (*Response, error) {
|
|
u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v", owner, repo, artifactID)
|
|
|
|
req, err := s.client.NewRequest("DELETE", u, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return s.client.Do(ctx, req, nil)
|
|
}
|