Files
gitea-tea/internal/app/actions_test.go
T
bircni 9f69a89537 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>
2026-10-11 23:46:26 +02:00

51 lines
2.2 KiB
Go

// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package app
import (
"context"
"net/http"
"testing"
"gitea.dev/tea/internal/clierr"
"github.com/stretchr/testify/require"
)
func TestWorkflowRunFollowStreamsFirstJobLogs(t *testing.T) {
jobPolls := 0
server := newAuthenticatedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch {
case r.Method == http.MethodPost && r.URL.Path == "/api/v1/repos/owner/repo/actions/workflows/ci.yml/dispatches":
require.Equal(t, "true", r.URL.Query().Get("return_run_details"))
_, _ = w.Write([]byte(`{"workflow_run_id":11,"html_url":"https://gitea.test/owner/repo/actions/runs/11"}`))
case r.URL.Path == "/api/v1/repos/owner/repo/actions/runs/11/jobs":
jobPolls++
if r.URL.Query().Get("page") != "" && r.URL.Query().Get("page") != "1" {
_, _ = w.Write([]byte(`{"jobs":[]}`))
return
}
_, _ = w.Write([]byte(`{"jobs":[{"id":21,"name":"build","status":"completed","conclusion":"success"}]}`))
case r.URL.Path == "/api/v1/repos/owner/repo/actions/jobs/21/logs":
_, _ = w.Write([]byte("hello from job\n"))
case r.URL.Path == "/api/v1/repos/owner/repo/actions/runs/11":
_, _ = w.Write([]byte(`{"id":11,"status":"completed","conclusion":"success","display_title":"ci"}`))
default:
t.Fatalf("unexpected %s %s", r.Method, r.URL.Path)
}
}))
defer server.Close()
deps, out, diagnostics := serverDeps(t, server.URL)
require.NoError(t, Execute(context.Background(), deps, []string{"workflow", "run", "ci.yml", "-R", "owner/repo", "--ref", "main", "--follow", "--no-input"}))
require.Contains(t, out.String(), "11\thttps://gitea.test/owner/repo/actions/runs/11")
require.Contains(t, out.String(), "hello from job\n")
require.Contains(t, diagnostics.String(), "Waiting for run 11 jobs")
require.Contains(t, diagnostics.String(), "Following job 21 (build)")
require.GreaterOrEqual(t, jobPolls, 1)
err := Execute(context.Background(), deps, []string{"workflow", "run", "ci.yml", "-R", "owner/repo", "--ref", "main", "--follow", "--json", "--no-input"})
require.Error(t, err)
require.Equal(t, clierr.Usage, clierr.ExitCode(err))
require.Contains(t, err.Error(), "--follow cannot be combined with --json")
}