Add godoc comments to exported symbols in pkg/cmd/run
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
34d1fb3e63
commit
844963ca61
14 changed files with 122 additions and 17 deletions
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// CancelOptions holds the options for the cancel command.
|
||||
type CancelOptions struct {
|
||||
HttpClient func() (*http.Client, error)
|
||||
IO *iostreams.IOStreams
|
||||
|
|
@ -26,6 +27,7 @@ type CancelOptions struct {
|
|||
Force bool
|
||||
}
|
||||
|
||||
// NewCmdCancel creates the cancel command.
|
||||
func NewCmdCancel(f *cmdutil.Factory, runF func(*CancelOptions) error) *cobra.Command {
|
||||
opts := &CancelOptions{
|
||||
IO: f.IOStreams,
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ const (
|
|||
defaultRunGetLimit = 10
|
||||
)
|
||||
|
||||
// DeleteOptions holds the options for the delete command.
|
||||
type DeleteOptions struct {
|
||||
HttpClient func() (*http.Client, error)
|
||||
IO *iostreams.IOStreams
|
||||
|
|
@ -28,6 +29,7 @@ type DeleteOptions struct {
|
|||
RunID string
|
||||
}
|
||||
|
||||
// NewCmdDelete creates the delete command.
|
||||
func NewCmdDelete(f *cmdutil.Factory, runF func(*DeleteOptions) error) *cobra.Command {
|
||||
opts := &DeleteOptions{
|
||||
IO: f.IOStreams,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// DownloadOptions holds the options for the download command.
|
||||
type DownloadOptions struct {
|
||||
IO *iostreams.IOStreams
|
||||
Platform platform
|
||||
|
|
@ -35,6 +36,7 @@ type iprompter interface {
|
|||
MultiSelect(string, []string, []string) ([]int, error)
|
||||
}
|
||||
|
||||
// NewCmdDownload creates the download command.
|
||||
func NewCmdDownload(f *cmdutil.Factory, runF func(*DownloadOptions) error) *cobra.Command {
|
||||
opts := &DownloadOptions{
|
||||
IO: f.IOStreams,
|
||||
|
|
|
|||
|
|
@ -19,10 +19,12 @@ type apiPlatform struct {
|
|||
repo ghrepo.Interface
|
||||
}
|
||||
|
||||
// List returns all artifacts for the given run.
|
||||
func (p *apiPlatform) List(runID string) ([]shared.Artifact, error) {
|
||||
return shared.ListArtifacts(p.client, p.repo, runID)
|
||||
}
|
||||
|
||||
// Download fetches and extracts an artifact to the given directory.
|
||||
func (p *apiPlatform) Download(url string, dir safepaths.Absolute) error {
|
||||
return downloadArtifact(p.client, url, dir)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ const (
|
|||
defaultLimit = 20
|
||||
)
|
||||
|
||||
// ListOptions holds the options for the list command.
|
||||
type ListOptions struct {
|
||||
IO *iostreams.IOStreams
|
||||
HttpClient func() (*http.Client, error)
|
||||
|
|
@ -46,6 +47,7 @@ type iprompter interface {
|
|||
Select(string, string, []string) (int, error)
|
||||
}
|
||||
|
||||
// NewCmdList creates the list command.
|
||||
func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Command {
|
||||
opts := &ListOptions{
|
||||
IO: f.IOStreams,
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// RerunOptions holds the options for the rerun command.
|
||||
type RerunOptions struct {
|
||||
HttpClient func() (*http.Client, error)
|
||||
IO *iostreams.IOStreams
|
||||
|
|
@ -31,6 +32,7 @@ type RerunOptions struct {
|
|||
Prompt bool
|
||||
}
|
||||
|
||||
// NewCmdRerun creates the rerun command.
|
||||
func NewCmdRerun(f *cmdutil.Factory, runF func(*RerunOptions) error) *cobra.Command {
|
||||
opts := &RerunOptions{
|
||||
IO: f.IOStreams,
|
||||
|
|
@ -228,6 +230,7 @@ func rerunJob(client *api.Client, repo ghrepo.Interface, job *shared.Job, debug
|
|||
return nil
|
||||
}
|
||||
|
||||
// RerunPayload is the request body for rerunning a workflow.
|
||||
type RerunPayload struct {
|
||||
Debug bool `json:"enable_debug_logging"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// NewCmdRun creates the run command group.
|
||||
func NewCmdRun(f *cmdutil.Factory) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "run <command>",
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/cli/cli/v2/internal/ghrepo"
|
||||
)
|
||||
|
||||
// Artifact represents a GitHub Actions workflow run artifact.
|
||||
type Artifact struct {
|
||||
Name string `json:"name"`
|
||||
Size uint64 `json:"size_in_bytes"`
|
||||
|
|
@ -22,6 +23,7 @@ type artifactsPayload struct {
|
|||
Artifacts []Artifact
|
||||
}
|
||||
|
||||
// ListArtifacts fetches all artifacts for a repository or a specific run.
|
||||
func ListArtifacts(httpClient *http.Client, repo ghrepo.Interface, runID string) ([]Artifact, error) {
|
||||
var results []Artifact
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/cli/cli/v2/pkg/iostreams"
|
||||
)
|
||||
|
||||
// RenderRunHeader renders a header string for a workflow run.
|
||||
func RenderRunHeader(cs *iostreams.ColorScheme, run Run, ago, prNumber string, attempt uint64) string {
|
||||
title := fmt.Sprintf("%s %s%s",
|
||||
cs.Bold(run.HeadBranch), run.WorkflowName(), prNumber)
|
||||
|
|
@ -25,6 +26,7 @@ func RenderRunHeader(cs *iostreams.ColorScheme, run Run, ago, prNumber string, a
|
|||
return header
|
||||
}
|
||||
|
||||
// RenderJobs renders a list of jobs with their status and steps.
|
||||
func RenderJobs(cs *iostreams.ColorScheme, jobs []Job, verbose bool) string {
|
||||
lines := []string{}
|
||||
for _, job := range jobs {
|
||||
|
|
@ -47,6 +49,7 @@ func RenderJobs(cs *iostreams.ColorScheme, jobs []Job, verbose bool) string {
|
|||
return strings.Join(lines, "\n")
|
||||
}
|
||||
|
||||
// RenderJobsCompact renders a compact list of jobs showing only relevant steps.
|
||||
func RenderJobsCompact(cs *iostreams.ColorScheme, jobs []Job) string {
|
||||
lines := []string{}
|
||||
for _, job := range jobs {
|
||||
|
|
@ -89,6 +92,7 @@ func RenderJobsCompact(cs *iostreams.ColorScheme, jobs []Job) string {
|
|||
return strings.Join(lines, "\n")
|
||||
}
|
||||
|
||||
// RenderAnnotations renders a list of annotations with symbols and messages.
|
||||
func RenderAnnotations(cs *iostreams.ColorScheme, annotations []Annotation) string {
|
||||
lines := []string{}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,38 +15,60 @@ import (
|
|||
"github.com/cli/cli/v2/pkg/iostreams"
|
||||
)
|
||||
|
||||
// Prompter provides interactive selection prompts.
|
||||
type Prompter interface {
|
||||
Select(string, string, []string) (int, error)
|
||||
}
|
||||
|
||||
const (
|
||||
// Run statuses
|
||||
Queued Status = "queued"
|
||||
Completed Status = "completed"
|
||||
// Queued indicates a workflow run is queued.
|
||||
Queued Status = "queued"
|
||||
// Completed indicates a workflow run has finished.
|
||||
Completed Status = "completed"
|
||||
// InProgress indicates a workflow run is currently executing.
|
||||
InProgress Status = "in_progress"
|
||||
Requested Status = "requested"
|
||||
Waiting Status = "waiting"
|
||||
Pending Status = "pending"
|
||||
// Requested indicates a workflow run has been requested.
|
||||
Requested Status = "requested"
|
||||
// Waiting indicates a workflow run is waiting to be processed.
|
||||
Waiting Status = "waiting"
|
||||
// Pending indicates a workflow run is pending.
|
||||
Pending Status = "pending"
|
||||
|
||||
// Run conclusions
|
||||
// ActionRequired indicates a workflow run requires action.
|
||||
ActionRequired Conclusion = "action_required"
|
||||
Cancelled Conclusion = "cancelled"
|
||||
Failure Conclusion = "failure"
|
||||
Neutral Conclusion = "neutral"
|
||||
Skipped Conclusion = "skipped"
|
||||
Stale Conclusion = "stale"
|
||||
// Cancelled indicates a workflow run was cancelled.
|
||||
Cancelled Conclusion = "cancelled"
|
||||
// Failure indicates a workflow run failed.
|
||||
Failure Conclusion = "failure"
|
||||
// Neutral indicates a workflow run completed with a neutral result.
|
||||
Neutral Conclusion = "neutral"
|
||||
// Skipped indicates a workflow run was skipped.
|
||||
Skipped Conclusion = "skipped"
|
||||
// Stale indicates a workflow run became stale.
|
||||
Stale Conclusion = "stale"
|
||||
// StartupFailure indicates a workflow run failed during startup.
|
||||
StartupFailure Conclusion = "startup_failure"
|
||||
Success Conclusion = "success"
|
||||
TimedOut Conclusion = "timed_out"
|
||||
// Success indicates a workflow run completed successfully.
|
||||
Success Conclusion = "success"
|
||||
// TimedOut indicates a workflow run exceeded its time limit.
|
||||
TimedOut Conclusion = "timed_out"
|
||||
|
||||
// AnnotationFailure represents a failure-level annotation.
|
||||
AnnotationFailure Level = "failure"
|
||||
// AnnotationWarning represents a warning-level annotation.
|
||||
AnnotationWarning Level = "warning"
|
||||
)
|
||||
|
||||
// Status represents the status of a workflow run or job.
|
||||
type Status string
|
||||
|
||||
// Conclusion represents the conclusion of a workflow run or job.
|
||||
type Conclusion string
|
||||
|
||||
// Level represents the severity level of an annotation.
|
||||
type Level string
|
||||
|
||||
// AllStatuses contains all valid workflow run status and conclusion values.
|
||||
var AllStatuses = []string{
|
||||
"queued",
|
||||
"completed",
|
||||
|
|
@ -65,6 +87,7 @@ var AllStatuses = []string{
|
|||
"timed_out",
|
||||
}
|
||||
|
||||
// RunFields lists the available fields for exporting workflow run data.
|
||||
var RunFields = []string{
|
||||
"name",
|
||||
"displayTitle",
|
||||
|
|
@ -84,8 +107,10 @@ var RunFields = []string{
|
|||
"url",
|
||||
}
|
||||
|
||||
// SingleRunFields extends RunFields with additional fields available for a single run.
|
||||
var SingleRunFields = append(RunFields, "jobs")
|
||||
|
||||
// Run represents a GitHub Actions workflow run.
|
||||
type Run struct {
|
||||
Name string `json:"name"` // the semantics of this field are unclear
|
||||
DisplayTitle string `json:"display_title"`
|
||||
|
|
@ -109,6 +134,7 @@ type Run struct {
|
|||
Jobs []Job `json:"-"` // populated by GetJobs
|
||||
}
|
||||
|
||||
// StartedTime returns the effective start time, falling back to CreatedAt.
|
||||
func (r *Run) StartedTime() time.Time {
|
||||
if r.StartedAt.IsZero() {
|
||||
return r.CreatedAt
|
||||
|
|
@ -116,6 +142,7 @@ func (r *Run) StartedTime() time.Time {
|
|||
return r.StartedAt
|
||||
}
|
||||
|
||||
// Duration returns the elapsed duration of the run.
|
||||
func (r *Run) Duration(now time.Time) time.Duration {
|
||||
endTime := r.UpdatedAt
|
||||
if r.Status != Completed {
|
||||
|
|
@ -128,6 +155,7 @@ func (r *Run) Duration(now time.Time) time.Duration {
|
|||
return d.Round(time.Second)
|
||||
}
|
||||
|
||||
// Repo represents a repository reference within a workflow run.
|
||||
type Repo struct {
|
||||
Owner struct {
|
||||
Login string
|
||||
|
|
@ -135,6 +163,7 @@ type Repo struct {
|
|||
Name string
|
||||
}
|
||||
|
||||
// Commit represents a Git commit associated with a workflow run.
|
||||
type Commit struct {
|
||||
Message string
|
||||
}
|
||||
|
|
@ -159,6 +188,7 @@ func (r Run) WorkflowName() string {
|
|||
return r.workflowName
|
||||
}
|
||||
|
||||
// ExportData returns the run data as a map for the given fields.
|
||||
func (r *Run) ExportData(fields []string) map[string]interface{} {
|
||||
v := reflect.ValueOf(r).Elem()
|
||||
fieldByName := func(v reflect.Value, field string) reflect.Value {
|
||||
|
|
@ -219,6 +249,7 @@ func (r *Run) ExportData(fields []string) map[string]interface{} {
|
|||
return data
|
||||
}
|
||||
|
||||
// Job represents a job within a GitHub Actions workflow run.
|
||||
type Job struct {
|
||||
ID int64
|
||||
Status Status
|
||||
|
|
@ -231,6 +262,7 @@ type Job struct {
|
|||
RunID int64 `json:"run_id"`
|
||||
}
|
||||
|
||||
// Step represents a step within a workflow job.
|
||||
type Step struct {
|
||||
Name string
|
||||
Status Status
|
||||
|
|
@ -240,12 +272,19 @@ type Step struct {
|
|||
CompletedAt time.Time `json:"completed_at"`
|
||||
}
|
||||
|
||||
// Steps is a sortable slice of Step values.
|
||||
type Steps []Step
|
||||
|
||||
func (s Steps) Len() int { return len(s) }
|
||||
func (s Steps) Less(i, j int) bool { return s[i].Number < s[j].Number }
|
||||
func (s Steps) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
// Len returns the number of steps.
|
||||
func (s Steps) Len() int { return len(s) }
|
||||
|
||||
// Less reports whether step i should sort before step j.
|
||||
func (s Steps) Less(i, j int) bool { return s[i].Number < s[j].Number }
|
||||
|
||||
// Swap exchanges steps at indices i and j.
|
||||
func (s Steps) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// Annotation represents a check run annotation.
|
||||
type Annotation struct {
|
||||
JobName string
|
||||
Message string
|
||||
|
|
@ -254,6 +293,7 @@ type Annotation struct {
|
|||
StartLine int `json:"start_line"`
|
||||
}
|
||||
|
||||
// AnnotationSymbol returns the display symbol for an annotation based on its level.
|
||||
func AnnotationSymbol(cs *iostreams.ColorScheme, a Annotation) string {
|
||||
switch a.Level {
|
||||
case AnnotationFailure:
|
||||
|
|
@ -265,10 +305,12 @@ func AnnotationSymbol(cs *iostreams.ColorScheme, a Annotation) string {
|
|||
}
|
||||
}
|
||||
|
||||
// CheckRun represents a GitHub check run.
|
||||
type CheckRun struct {
|
||||
ID int64
|
||||
}
|
||||
|
||||
// ErrMissingAnnotationsPermissions is returned when the token lacks permission to read annotations.
|
||||
var ErrMissingAnnotationsPermissions = errors.New("missing annotations permissions error")
|
||||
|
||||
// GetAnnotations fetches annotations from the REST API.
|
||||
|
|
@ -310,6 +352,7 @@ func GetAnnotations(client *api.Client, repo ghrepo.Interface, job Job) ([]Annot
|
|||
return out, nil
|
||||
}
|
||||
|
||||
// IsFailureState reports whether the conclusion represents a failure.
|
||||
func IsFailureState(c Conclusion) bool {
|
||||
switch c {
|
||||
case ActionRequired, Failure, StartupFailure, TimedOut:
|
||||
|
|
@ -319,15 +362,18 @@ func IsFailureState(c Conclusion) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// IsSkipped reports whether the conclusion is skipped.
|
||||
func IsSkipped(c Conclusion) bool {
|
||||
return c == Skipped
|
||||
}
|
||||
|
||||
// RunsPayload is the API response for listing workflow runs.
|
||||
type RunsPayload struct {
|
||||
TotalCount int `json:"total_count"`
|
||||
WorkflowRuns []Run `json:"workflow_runs"`
|
||||
}
|
||||
|
||||
// FilterOptions specifies filters for querying workflow runs.
|
||||
type FilterOptions struct {
|
||||
Branch string
|
||||
Actor string
|
||||
|
|
@ -360,6 +406,7 @@ func GetRunsWithFilter(client *api.Client, repo ghrepo.Interface, opts *FilterOp
|
|||
return filtered, nil
|
||||
}
|
||||
|
||||
// GetRuns fetches workflow runs from the API with the given filters and limit.
|
||||
func GetRuns(client *api.Client, repo ghrepo.Interface, opts *FilterOptions, limit int) (*RunsPayload, error) {
|
||||
path := fmt.Sprintf("repos/%s/actions/runs", ghrepo.FullName(repo))
|
||||
if opts != nil && opts.WorkflowID > 0 {
|
||||
|
|
@ -470,11 +517,13 @@ func preloadWorkflowNames(client *api.Client, repo ghrepo.Interface, runs []Run)
|
|||
return nil
|
||||
}
|
||||
|
||||
// JobsPayload is the API response for listing workflow jobs.
|
||||
type JobsPayload struct {
|
||||
TotalCount int `json:"total_count"`
|
||||
Jobs []Job
|
||||
}
|
||||
|
||||
// GetJobs fetches the jobs for a workflow run.
|
||||
func GetJobs(client *api.Client, repo ghrepo.Interface, run *Run, attempt uint64) ([]Job, error) {
|
||||
if run.Jobs != nil {
|
||||
return run.Jobs, nil
|
||||
|
|
@ -502,6 +551,7 @@ func GetJobs(client *api.Client, repo ghrepo.Interface, run *Run, attempt uint64
|
|||
return run.Jobs, nil
|
||||
}
|
||||
|
||||
// GetJob fetches a single job by its ID.
|
||||
func GetJob(client *api.Client, repo ghrepo.Interface, jobID string) (*Job, error) {
|
||||
path := fmt.Sprintf("repos/%s/actions/jobs/%s", ghrepo.FullName(repo), jobID)
|
||||
|
||||
|
|
@ -536,6 +586,7 @@ func SelectRun(p Prompter, cs *iostreams.ColorScheme, runs []Run) (string, error
|
|||
return fmt.Sprintf("%d", runs[selected].ID), nil
|
||||
}
|
||||
|
||||
// GetRun fetches a single workflow run by its ID and optional attempt number.
|
||||
func GetRun(client *api.Client, repo ghrepo.Interface, runID string, attempt uint64) (*Run, error) {
|
||||
var result Run
|
||||
|
||||
|
|
@ -570,6 +621,7 @@ func GetRun(client *api.Client, repo ghrepo.Interface, runID string, attempt uin
|
|||
|
||||
type colorFunc func(string) string
|
||||
|
||||
// Symbol returns a display symbol and color function for a given status and conclusion.
|
||||
func Symbol(cs *iostreams.ColorScheme, status Status, conclusion Conclusion) (string, colorFunc) {
|
||||
noColor := func(s string) string { return s }
|
||||
if status == Completed {
|
||||
|
|
@ -586,6 +638,7 @@ func Symbol(cs *iostreams.ColorScheme, status Status, conclusion Conclusion) (st
|
|||
return "*", cs.Yellow
|
||||
}
|
||||
|
||||
// PullRequestForRun finds the pull request number associated with a workflow run.
|
||||
func PullRequestForRun(client *api.Client, repo ghrepo.Interface, run Run) (int, error) {
|
||||
type response struct {
|
||||
Repository struct {
|
||||
|
|
|
|||
|
|
@ -8,20 +8,25 @@ import (
|
|||
"github.com/cli/cli/v2/pkg/iostreams"
|
||||
)
|
||||
|
||||
// TestRunStartTime is the default start time used for test runs.
|
||||
var TestRunStartTime, _ = time.Parse("2006-01-02 15:04:05", "2021-02-23 04:51:00")
|
||||
|
||||
// TestRun creates a Run with the given ID, status, and conclusion for testing.
|
||||
func TestRun(id int64, s Status, c Conclusion) Run {
|
||||
return TestRunWithCommit(id, s, c, "cool commit")
|
||||
}
|
||||
|
||||
// TestRunWithCommit creates a test Run with a specified commit message.
|
||||
func TestRunWithCommit(id int64, s Status, c Conclusion, commit string) Run {
|
||||
return TestRunWithWorkflowAndCommit(123, id, s, c, commit)
|
||||
}
|
||||
|
||||
// TestRunWithOrgRequiredWorkflow creates a test Run for an organization required workflow.
|
||||
func TestRunWithOrgRequiredWorkflow(id int64, s Status, c Conclusion, commit string) Run {
|
||||
return TestRunWithWorkflowAndCommit(456, id, s, c, commit)
|
||||
}
|
||||
|
||||
// TestRunWithWorkflowAndCommit creates a test Run with a specific workflow ID and commit.
|
||||
func TestRunWithWorkflowAndCommit(workflowId, runId int64, s Status, c Conclusion, commit string) Run {
|
||||
return Run{
|
||||
WorkflowID: workflowId,
|
||||
|
|
@ -45,9 +50,13 @@ func TestRunWithWorkflowAndCommit(workflowId, runId int64, s Status, c Conclusio
|
|||
}
|
||||
}
|
||||
|
||||
// SuccessfulRun is a test Run that completed successfully.
|
||||
var SuccessfulRun Run = TestRun(3, Completed, Success)
|
||||
|
||||
// FailedRun is a test Run that completed with a failure.
|
||||
var FailedRun Run = TestRun(1234, Completed, Failure)
|
||||
|
||||
// TestRuns is a collection of test runs covering various statuses and conclusions.
|
||||
var TestRuns []Run = []Run{
|
||||
TestRun(1, Completed, TimedOut),
|
||||
TestRun(2, InProgress, ""),
|
||||
|
|
@ -61,6 +70,7 @@ var TestRuns []Run = []Run{
|
|||
TestRun(10, Completed, Stale),
|
||||
}
|
||||
|
||||
// TestRunsWithOrgRequiredWorkflows is a collection of test runs including org required workflows.
|
||||
var TestRunsWithOrgRequiredWorkflows []Run = []Run{
|
||||
TestRunWithOrgRequiredWorkflow(1, Completed, TimedOut, "cool commit"),
|
||||
TestRunWithOrgRequiredWorkflow(2, InProgress, "", "cool commit"),
|
||||
|
|
@ -73,12 +83,14 @@ var TestRunsWithOrgRequiredWorkflows []Run = []Run{
|
|||
TestRun(9, Queued, ""),
|
||||
}
|
||||
|
||||
// WorkflowRuns is a subset of test runs for workflow-specific testing.
|
||||
var WorkflowRuns []Run = []Run{
|
||||
TestRun(2, InProgress, ""),
|
||||
SuccessfulRun,
|
||||
FailedRun,
|
||||
}
|
||||
|
||||
// SuccessfulJob is a test Job that completed successfully.
|
||||
var SuccessfulJob Job = Job{
|
||||
ID: 10,
|
||||
Status: Completed,
|
||||
|
|
@ -158,6 +170,7 @@ var LegacySuccessfulJobWithoutStepLogs Job = Job{
|
|||
},
|
||||
}
|
||||
|
||||
// SkippedJob is a test Job that was skipped.
|
||||
var SkippedJob Job = Job{
|
||||
ID: 13,
|
||||
Status: Completed,
|
||||
|
|
@ -170,6 +183,7 @@ var SkippedJob Job = Job{
|
|||
Steps: []Step{},
|
||||
}
|
||||
|
||||
// FailedJob is a test Job that completed with a failure.
|
||||
var FailedJob Job = Job{
|
||||
ID: 20,
|
||||
Status: Completed,
|
||||
|
|
@ -249,6 +263,7 @@ var LegacyFailedJobWithoutStepLogs Job = Job{
|
|||
},
|
||||
}
|
||||
|
||||
// SuccessfulJobAnnotations contains test annotations for a successful job.
|
||||
var SuccessfulJobAnnotations []Annotation = []Annotation{
|
||||
{
|
||||
JobName: "cool job",
|
||||
|
|
@ -259,6 +274,7 @@ var SuccessfulJobAnnotations []Annotation = []Annotation{
|
|||
},
|
||||
}
|
||||
|
||||
// FailedJobAnnotations contains test annotations for a failed job.
|
||||
var FailedJobAnnotations []Annotation = []Annotation{
|
||||
{
|
||||
JobName: "sad job",
|
||||
|
|
@ -269,24 +285,29 @@ var FailedJobAnnotations []Annotation = []Annotation{
|
|||
},
|
||||
}
|
||||
|
||||
// TestWorkflow is a test Workflow used in test fixtures.
|
||||
var TestWorkflow workflowShared.Workflow = workflowShared.Workflow{
|
||||
Name: "CI",
|
||||
ID: 123,
|
||||
}
|
||||
|
||||
// TestExporter is a mock exporter for testing data export functionality.
|
||||
type TestExporter struct {
|
||||
fields []string
|
||||
writeHandler func(io *iostreams.IOStreams, data interface{}) error
|
||||
}
|
||||
|
||||
// MakeTestExporter creates a TestExporter with the given fields and write handler.
|
||||
func MakeTestExporter(fields []string, wh func(io *iostreams.IOStreams, data interface{}) error) *TestExporter {
|
||||
return &TestExporter{fields: fields, writeHandler: wh}
|
||||
}
|
||||
|
||||
// Fields returns the export field names.
|
||||
func (t *TestExporter) Fields() []string {
|
||||
return t.fields
|
||||
}
|
||||
|
||||
// Write writes the exported data using the configured handler.
|
||||
func (t *TestExporter) Write(io *iostreams.IOStreams, data interface{}) error {
|
||||
return t.writeHandler(io, data)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ type zipLogFetcher struct {
|
|||
File *zip.File
|
||||
}
|
||||
|
||||
// GetLog opens and returns the log contents from the ZIP file entry.
|
||||
func (f *zipLogFetcher) GetLog() (io.ReadCloser, error) {
|
||||
return f.File.Open()
|
||||
}
|
||||
|
|
@ -37,6 +38,7 @@ type apiLogFetcher struct {
|
|||
jobID int64
|
||||
}
|
||||
|
||||
// GetLog fetches the log contents from the GitHub Actions API.
|
||||
func (f *apiLogFetcher) GetLog() (io.ReadCloser, error) {
|
||||
logURL := fmt.Sprintf("%srepos/%s/actions/jobs/%d/logs",
|
||||
ghinstance.RESTPrefix(f.repo.RepoHost()), ghrepo.FullName(f.repo), f.jobID)
|
||||
|
|
@ -235,6 +237,7 @@ func getZipLogMap(rlz *zip.Reader, jobs []shared.Job) *zipLogMap {
|
|||
return zlm
|
||||
}
|
||||
|
||||
// JOB_NAME_MAX_LENGTH is the maximum length of a job name in log filenames.
|
||||
const JOB_NAME_MAX_LENGTH = 90
|
||||
|
||||
func getJobNameForLogFilename(name string) string {
|
||||
|
|
|
|||
|
|
@ -25,10 +25,12 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// RunLogCache provides caching for workflow run log ZIP archives.
|
||||
type RunLogCache struct {
|
||||
cacheDir string
|
||||
}
|
||||
|
||||
// Exists reports whether a cache entry with the given key exists.
|
||||
func (c RunLogCache) Exists(key string) (bool, error) {
|
||||
_, err := os.Stat(c.filepath(key))
|
||||
if err == nil {
|
||||
|
|
@ -42,6 +44,7 @@ func (c RunLogCache) Exists(key string) (bool, error) {
|
|||
return false, fmt.Errorf("checking cache entry: %v", err)
|
||||
}
|
||||
|
||||
// Create stores content in the cache under the given key.
|
||||
func (c RunLogCache) Create(key string, content io.Reader) error {
|
||||
if err := os.MkdirAll(c.cacheDir, 0755); err != nil {
|
||||
return fmt.Errorf("creating cache directory: %v", err)
|
||||
|
|
@ -61,6 +64,7 @@ func (c RunLogCache) Create(key string, content io.Reader) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Open returns the cached ZIP archive for the given key.
|
||||
func (c RunLogCache) Open(key string) (*zip.ReadCloser, error) {
|
||||
r, err := zip.OpenReader(c.filepath(key))
|
||||
if err != nil {
|
||||
|
|
@ -74,6 +78,7 @@ func (c RunLogCache) filepath(key string) string {
|
|||
return filepath.Join(c.cacheDir, fmt.Sprintf("run-log-%s.zip", key))
|
||||
}
|
||||
|
||||
// ViewOptions holds the options for the view command.
|
||||
type ViewOptions struct {
|
||||
HttpClient func() (*http.Client, error)
|
||||
IO *iostreams.IOStreams
|
||||
|
|
@ -97,6 +102,7 @@ type ViewOptions struct {
|
|||
Now func() time.Time
|
||||
}
|
||||
|
||||
// NewCmdView creates the view command.
|
||||
func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Command {
|
||||
opts := &ViewOptions{
|
||||
IO: f.IOStreams,
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import (
|
|||
|
||||
const defaultInterval int = 3
|
||||
|
||||
// WatchOptions holds the options for the watch command.
|
||||
type WatchOptions struct {
|
||||
IO *iostreams.IOStreams
|
||||
HttpClient func() (*http.Client, error)
|
||||
|
|
@ -35,6 +36,7 @@ type WatchOptions struct {
|
|||
Now func() time.Time
|
||||
}
|
||||
|
||||
// NewCmdWatch creates the watch command.
|
||||
func NewCmdWatch(f *cmdutil.Factory, runF func(*WatchOptions) error) *cobra.Command {
|
||||
opts := &WatchOptions{
|
||||
IO: f.IOStreams,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue