Implement tea actions commands to view workflow runs and logs using the Gitea 1.25 API endpoints directly. This adds: - `tea actions runs` - list workflow runs for a repository - `tea actions jobs <run-id>` - list jobs for a specific run - `tea actions logs <job-id>` - display logs for a specific job Also adds a new `modules/api` package for making raw authenticated HTTP requests to Gitea API endpoints not yet supported by the go-sdk. Closes #1 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
169 lines
2.9 KiB
Go
169 lines
2.9 KiB
Go
// Copyright 2024 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package print
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"code.gitea.io/sdk/gitea"
|
|
"code.gitea.io/tea/modules/api"
|
|
)
|
|
|
|
// ActionSecretsList prints a list of action secrets
|
|
func ActionSecretsList(secrets []*gitea.Secret, output string) {
|
|
t := table{
|
|
headers: []string{
|
|
"Name",
|
|
"Created",
|
|
},
|
|
}
|
|
|
|
for _, secret := range secrets {
|
|
t.addRow(
|
|
secret.Name,
|
|
FormatTime(secret.Created, output != ""),
|
|
)
|
|
}
|
|
|
|
if len(secrets) == 0 {
|
|
fmt.Printf("No secrets found\n")
|
|
return
|
|
}
|
|
|
|
t.sort(0, true)
|
|
t.print(output)
|
|
}
|
|
|
|
// ActionVariableDetails prints details of a specific action variable
|
|
func ActionVariableDetails(variable *gitea.RepoActionVariable) {
|
|
fmt.Printf("Name: %s\n", variable.Name)
|
|
fmt.Printf("Value: %s\n", variable.Value)
|
|
fmt.Printf("Repository ID: %d\n", variable.RepoID)
|
|
fmt.Printf("Owner ID: %d\n", variable.OwnerID)
|
|
}
|
|
|
|
// ActionVariablesList prints a list of action variables
|
|
func ActionVariablesList(variables []*gitea.RepoActionVariable, output string) {
|
|
t := table{
|
|
headers: []string{
|
|
"Name",
|
|
"Value",
|
|
"Repository ID",
|
|
},
|
|
}
|
|
|
|
for _, variable := range variables {
|
|
// Truncate long values for table display
|
|
value := variable.Value
|
|
if len(value) > 50 {
|
|
value = value[:47] + "..."
|
|
}
|
|
|
|
t.addRow(
|
|
variable.Name,
|
|
value,
|
|
fmt.Sprintf("%d", variable.RepoID),
|
|
)
|
|
}
|
|
|
|
if len(variables) == 0 {
|
|
fmt.Printf("No variables found\n")
|
|
return
|
|
}
|
|
|
|
t.sort(0, true)
|
|
t.print(output)
|
|
}
|
|
|
|
// ActionRunsList prints a list of workflow runs
|
|
func ActionRunsList(runs []*api.ActionRun, output string) {
|
|
t := table{
|
|
headers: []string{
|
|
"ID",
|
|
"Title",
|
|
"Status",
|
|
"Conclusion",
|
|
"Event",
|
|
"Branch",
|
|
"Started",
|
|
},
|
|
}
|
|
|
|
for _, run := range runs {
|
|
conclusion := run.Conclusion
|
|
if conclusion == "" {
|
|
conclusion = "-"
|
|
}
|
|
|
|
started := ""
|
|
if run.StartedAt != nil {
|
|
started = FormatTime(*run.StartedAt, output != "")
|
|
}
|
|
|
|
t.addRow(
|
|
fmt.Sprintf("%d", run.ID),
|
|
run.Title,
|
|
run.Status,
|
|
conclusion,
|
|
run.Event,
|
|
run.HeadBranch,
|
|
started,
|
|
)
|
|
}
|
|
|
|
if len(runs) == 0 {
|
|
fmt.Printf("No workflow runs found\n")
|
|
return
|
|
}
|
|
|
|
t.print(output)
|
|
}
|
|
|
|
// ActionJobsList prints a list of jobs
|
|
func ActionJobsList(jobs []*api.ActionJob, output string) {
|
|
t := table{
|
|
headers: []string{
|
|
"ID",
|
|
"Name",
|
|
"Status",
|
|
"Conclusion",
|
|
"Started",
|
|
"Completed",
|
|
},
|
|
}
|
|
|
|
for _, job := range jobs {
|
|
conclusion := job.Conclusion
|
|
if conclusion == "" {
|
|
conclusion = "-"
|
|
}
|
|
|
|
started := ""
|
|
if job.StartedAt != nil {
|
|
started = FormatTime(*job.StartedAt, output != "")
|
|
}
|
|
|
|
completed := ""
|
|
if job.CompletedAt != nil {
|
|
completed = FormatTime(*job.CompletedAt, output != "")
|
|
}
|
|
|
|
t.addRow(
|
|
fmt.Sprintf("%d", job.ID),
|
|
job.Name,
|
|
job.Status,
|
|
conclusion,
|
|
started,
|
|
completed,
|
|
)
|
|
}
|
|
|
|
if len(jobs) == 0 {
|
|
fmt.Printf("No jobs found\n")
|
|
return
|
|
}
|
|
|
|
t.print(output)
|
|
}
|