mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 19:11:25 +01:00
feat(run): show runs like gh, watch them live, and download artifacts
run list prints a table with a status icon, the workflow name, title, branch, event, elapsed time and age, and the total from the server; runs carry workflow, workflow_path and run_number in JSON. run view shows the run's state and trigger, its jobs with their steps and durations, the next steps and the run's URL; --json includes the jobs, --log prints their logs and --web opens the run. Run commands accept #N and run URLs, and ask for a recent run in a terminal when the argument is left out. run watch redraws the run on the alternate screen, then prints it with a summary; an expired --timeout names the run and suspects a missing runner when no job started. run cancel no longer asks for confirmation, rerun refuses unfinished runs up front, reruns a single job with --job and reports the new attempt, and delete names the run in its prompt. run logs follows several jobs with --follow, prefixing lines with the job's name, selects jobs by name or with --failed, and downloads the archive with --output or --dir. run download extracts the artifacts of a run by name, and artifact list shows sizes and expiry. Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
19 files changed
+2636
-646
No files matched your search
@@ -0,0 +1,40 @@
|
||||
// Copyright 2026 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package terminal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"charm.land/huh/v2"
|
||||
)
|
||||
|
||||
// Choice is one option of a selection prompt: Label is shown and Value returned.
|
||||
type Choice struct {
|
||||
Label, Value string
|
||||
}
|
||||
|
||||
// Chooser asks for one of several options. FormPrompter implements it; a Prompter without it
|
||||
// cannot offer a selection.
|
||||
type Chooser interface {
|
||||
// Choose asks for one of choices, starting at the one whose value is initial, else the first.
|
||||
Choose(ctx context.Context, title string, choices []Choice, initial string) (string, error)
|
||||
}
|
||||
|
||||
// Choose asks on stderr for one of choices and returns its value.
|
||||
func (p *FormPrompter) Choose(ctx context.Context, title string, choices []Choice, initial string) (string, error) {
|
||||
if len(choices) == 0 {
|
||||
return "", errors.New("nothing to choose from")
|
||||
}
|
||||
options := make([]huh.Option[string], len(choices))
|
||||
value := choices[0].Value
|
||||
for i, choice := range choices {
|
||||
options[i] = huh.NewOption(SafeLine(choice.Label), choice.Value)
|
||||
if choice.Value == initial {
|
||||
value = initial
|
||||
}
|
||||
}
|
||||
err := p.runForm(ctx, huh.NewForm(huh.NewGroup(huh.NewSelect[string]().Title(title).Options(options...).Height(min(len(choices), 10)+2).Value(&value))))
|
||||
return value, err
|
||||
}
|
||||
Reference in new issue
Block a user