Repository: cli/cli
File: pkg/cmd/run/shared/shared.go (Go)

Code before:

func preloadWorkflowNames(client *api.Client, repo ghrepo.Interface, runs []Run) error {
	workflows, err := workflowShared.GetWorkflows(client, repo, 0)
	if err != nil {
		return err
	}

	workflowMap := map[int64]string{}
	for _, wf := range workflows {
		workflowMap[wf.ID] = wf.Name
	}

	for i, run := range runs {
		if _, ok := workflowMap[run.WorkflowID]; !ok {
			// Look up workflow by ID because it may have been deleted
			workflow, err := workflowShared.GetWorkflow(client, repo, run.WorkflowID)
			// If the error is an httpError and it is a 404, this is likely a
			// organization or enterprise ruleset workflow. The user does not
			// have permissions to view the details of the workflow, so we cannot
			// look it up directly without receiving a 404, but it is nonetheless
			// in the workflow run list. To handle this, we set the workflow name
			// to an empty string.
			if httpErr, ok := err.(api.HTTPError); ok && httpErr.StatusCode == 404 {
				workflowMap[run.WorkflowID] = ""
				continue
			}
			if err != nil {
				return err
			}
			workflowMap[run.WorkflowID] = workflow.Name
		}
		runs[i].workflowName = workflowMap[run.WorkflowID]
	}
	return nil
}

type JobsPayload struct {
	TotalCount int `json:"total_count"`
	Jobs       []Job
}

func GetJobs(client *api.Client, repo ghrepo.Interface, run *Run, attempt uint64) ([]Job, error) {
	if run.Jobs != nil {
		return run.Jobs, nil
	}

	query := url.Values{}
	query.Set("per_page", "100")
	jobsPath := fmt.Sprintf("%s?%s", run.JobsURL, query.Encode())

	if attempt > 0 {

Review comment (bug):
**question:** should `workflowShared.GetWorkflow()` be responsible for dealing with this scenario? 🤔 

`gh run view` command also calls the same function to retrieve the workflow and fails when trying to view a ruleset workflow run.

https://github.com/cli/cli/blob/c6f574ccb19fa4d8819c3554e806eb07f87a7ebe/pkg/cmd/run/shared/shared.go#L556-L564

I'll defer to you whether this is a separate issue + PR or if the original issue expands to cover `gh run view`.

Code after:

func preloadWorkflowNames(client *api.Client, repo ghrepo.Interface, runs []Run) error {
	workflows, err := workflowShared.GetWorkflows(client, repo, 0)
	if err != nil {
		return err
	}

	workflowMap := map[int64]string{}
	for _, wf := range workflows {
		workflowMap[wf.ID] = wf.Name
	}

	for i, run := range runs {
		if _, ok := workflowMap[run.WorkflowID]; !ok {
			// Look up workflow by ID because it may have been deleted
			workflow, err := workflowShared.GetWorkflow(client, repo, run.WorkflowID)
			// If the error is an httpError and it is a 404, this is likely a
			// organization or enterprise ruleset workflow. The user does not
			// have permissions to view the details of the workflow, so we cannot
			// look it up directly without receiving a 404, but it is nonetheless
			// in the workflow run list. To handle this, we set the workflow name
			// to an empty string.
			// Deciding to put this here instead of in GetWorkflow to allow
			// the caller to decide what a 404 means.
			if httpErr, ok := err.(api.HTTPError); ok && httpErr.StatusCode == 404 {
				workflowMap[run.WorkflowID] = ""
				continue
			}
			if err != nil {
				return err
			}
			workflowMap[run.WorkflowID] = workflow.Name
		}
		runs[i].workflowName = workflowMap[run.WorkflowID]
	}
	return nil
}

type JobsPayload struct {
	TotalCount int `json:"total_count"`
	Jobs       []Job
}

func GetJobs(client *api.Client, repo ghrepo.Interface, run *Run, attempt uint64) ([]Job, error) {
	if run.Jobs != nil {
		return run.Jobs, nil
	}

	query := url.Values{}
	query.Set("per_page", "100")
	jobsPath := fmt.Sprintf("%s?%s", run.JobsURL, query.Encode())