mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-10 05:24:18 +09:00
Pairs with https://gitea.com/gitea/runner/pulls/1143. Gitea depends on `gitea.com/gitea/runner` for exactly two packages: `act/model` and `act/exprparser`, the workflow model and the expression evaluator it needs to parse workflows and to build the task payload the runner consumes. Pulling the whole runner module in for that is heavy and puts shared code in the repository of one of the two consumers. Both packages now live in `gitea.dev/actionslib` (`pkg/model`, `pkg/exprparser`), the module Gitea and the runner already share for the runner API, so the dependency on the runner repository is dropped here. ### Changes - `gitea.com/gitea/runner/act/model` -> `gitea.dev/actionslib/pkg/model`, `.../act/exprparser` -> `gitea.dev/actionslib/pkg/exprparser` (22 files, import paths only). - `routers/api/actions/runner/interceptor.go` takes the `x-runner-uuid` / `x-runner-token` names from `gitea.dev/actionslib/pkg/protocol` instead of repeating the literals the runner also has. - `go.mod`: `gitea.com/gitea/runner` removed. --------- Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: Zettat123 <zettat123@gmail.com>
179 lines
5.6 KiB
Go
179 lines
5.6 KiB
Go
// Copyright 2025 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package integration
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
"testing"
|
|
"time"
|
|
|
|
runnerv1 "gitea.dev/actionslib/runner/v1"
|
|
actions_model "gitea.dev/models/actions"
|
|
auth_model "gitea.dev/models/auth"
|
|
"gitea.dev/models/unittest"
|
|
user_model "gitea.dev/models/user"
|
|
"gitea.dev/modules/json"
|
|
"gitea.dev/routers/web/repo/actions"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
|
)
|
|
|
|
func TestActionsDeleteRun(t *testing.T) {
|
|
now := time.Now()
|
|
testCase := struct {
|
|
treePath string
|
|
fileContent string
|
|
outcomes map[string]*mockTaskOutcome
|
|
expectedStatuses map[string]string
|
|
}{
|
|
treePath: ".gitea/workflows/test1.yml",
|
|
fileContent: `name: test1
|
|
on:
|
|
push:
|
|
paths:
|
|
- .gitea/workflows/test1.yml
|
|
jobs:
|
|
job1:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- run: echo job1
|
|
job2:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- run: echo job2
|
|
job3:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- run: echo job3
|
|
`,
|
|
outcomes: map[string]*mockTaskOutcome{
|
|
"job1": {
|
|
result: runnerv1.Result_RESULT_SUCCESS,
|
|
logRows: []*runnerv1.LogRow{
|
|
{
|
|
Time: timestamppb.New(now.Add(4 * time.Second)),
|
|
Content: " \U0001F433 docker create image",
|
|
},
|
|
{
|
|
Time: timestamppb.New(now.Add(5 * time.Second)),
|
|
Content: "job1",
|
|
},
|
|
{
|
|
Time: timestamppb.New(now.Add(6 * time.Second)),
|
|
Content: "\U0001F3C1 Job succeeded",
|
|
},
|
|
},
|
|
},
|
|
"job2": {
|
|
result: runnerv1.Result_RESULT_SUCCESS,
|
|
logRows: []*runnerv1.LogRow{
|
|
{
|
|
Time: timestamppb.New(now.Add(4 * time.Second)),
|
|
Content: " \U0001F433 docker create image",
|
|
},
|
|
{
|
|
Time: timestamppb.New(now.Add(5 * time.Second)),
|
|
Content: "job2",
|
|
},
|
|
{
|
|
Time: timestamppb.New(now.Add(6 * time.Second)),
|
|
Content: "\U0001F3C1 Job succeeded",
|
|
},
|
|
},
|
|
},
|
|
"job3": {
|
|
result: runnerv1.Result_RESULT_SUCCESS,
|
|
logRows: []*runnerv1.LogRow{
|
|
{
|
|
Time: timestamppb.New(now.Add(4 * time.Second)),
|
|
Content: " \U0001F433 docker create image",
|
|
},
|
|
{
|
|
Time: timestamppb.New(now.Add(5 * time.Second)),
|
|
Content: "job3",
|
|
},
|
|
{
|
|
Time: timestamppb.New(now.Add(6 * time.Second)),
|
|
Content: "\U0001F3C1 Job succeeded",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expectedStatuses: map[string]string{
|
|
"job1": actions_model.StatusSuccess.String(),
|
|
"job2": actions_model.StatusSuccess.String(),
|
|
"job3": actions_model.StatusSuccess.String(),
|
|
},
|
|
}
|
|
onGiteaRun(t, func(t *testing.T, u *url.URL) {
|
|
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
|
|
session := loginUser(t, user2.Name)
|
|
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
|
|
|
|
apiRepo := createActionsTestRepo(t, token, "actions-delete-run-test", false)
|
|
runner := newMockRunner()
|
|
runner.registerAsRepoRunner(t, user2.Name, apiRepo.Name, "mock-runner", []string{"ubuntu-latest"}, false)
|
|
|
|
opts := getWorkflowCreateFileOptions(user2, apiRepo.DefaultBranch, "create "+testCase.treePath, testCase.fileContent)
|
|
createWorkflowFile(t, token, user2.Name, apiRepo.Name, testCase.treePath, opts)
|
|
|
|
var runID int64
|
|
for i := 0; i < len(testCase.outcomes); i++ {
|
|
task := runner.fetchTask(t)
|
|
jobName := getTaskJobNameByTaskID(t, token, user2.Name, apiRepo.Name, task.Id)
|
|
outcome := testCase.outcomes[jobName]
|
|
assert.NotNil(t, outcome)
|
|
runner.execTask(t, task, outcome)
|
|
runIndex := task.Context.GetFields()["run_number"].GetStringValue()
|
|
parsedRunIndex, err := strconv.ParseInt(runIndex, 10, 64)
|
|
assert.NoError(t, err)
|
|
run := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{RepoID: apiRepo.ID, Index: parsedRunIndex})
|
|
runID = run.ID
|
|
}
|
|
|
|
jobs, err := actions_model.GetLatestAttemptJobsByRepoAndRunID(t.Context(), apiRepo.ID, runID)
|
|
assert.NoError(t, err)
|
|
|
|
for i := 0; i < len(testCase.outcomes); i++ {
|
|
jobID := jobs[i].ID
|
|
req := NewRequest(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/jobs/%d", user2.Name, apiRepo.Name, runID, jobID))
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
var listResp actions.ViewResponse
|
|
err := json.Unmarshal(resp.Body.Bytes(), &listResp)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, listResp.State.Run.Jobs, 3)
|
|
|
|
req = NewRequest(t, "GET", fmt.Sprintf("/%s/%s/actions/runs/%d/jobs/%d/logs", user2.Name, apiRepo.Name, runID, jobID)).
|
|
AddTokenAuth(token)
|
|
MakeRequest(t, req, http.StatusOK)
|
|
}
|
|
|
|
req := NewRequest(t, "GET", fmt.Sprintf("/%s/%s/actions/runs/%d", user2.Name, apiRepo.Name, runID))
|
|
session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
req = NewRequest(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/delete", user2.Name, apiRepo.Name, runID))
|
|
session.MakeRequest(t, req, http.StatusOK)
|
|
|
|
req = NewRequest(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/delete", user2.Name, apiRepo.Name, runID))
|
|
session.MakeRequest(t, req, http.StatusNotFound)
|
|
|
|
req = NewRequest(t, "GET", fmt.Sprintf("/%s/%s/actions/runs/%d", user2.Name, apiRepo.Name, runID))
|
|
session.MakeRequest(t, req, http.StatusNotFound)
|
|
|
|
for i := 0; i < len(testCase.outcomes); i++ {
|
|
jobID := jobs[i].ID
|
|
req := NewRequest(t, "POST", fmt.Sprintf("/%s/%s/actions/runs/%d/jobs/%d", user2.Name, apiRepo.Name, runID, jobID))
|
|
session.MakeRequest(t, req, http.StatusNotFound)
|
|
|
|
req = NewRequest(t, "GET", fmt.Sprintf("/%s/%s/actions/runs/%d/jobs/%d/logs", user2.Name, apiRepo.Name, runID, jobID)).
|
|
AddTokenAuth(token)
|
|
MakeRequest(t, req, http.StatusNotFound)
|
|
}
|
|
})
|
|
}
|