refactor(actions): small cleanups across models, services and routers (#39722)

Collection of small, behaviour-preserving cleanups in the Actions code.

- Fix log and error prefixes that named non-existent or wrong functions,
and wrap errors with `%w` so `errors.Is` keeps working.
- Remove unused code.
- Rely on `ctx.ServerError` / `ctx.APIErrorAuto`, which already map
`util.ErrNotExist` and friends, instead of equivalent hand-written
switches.
- Load runs referenced by commit statuses with one query instead of one
per run (used on every PR view); the result order is now stable.
- Encode an event's payload once instead of up to three times.
- Share the duplicated runner-token "get or create" logic and the
"notify and emit" call pair.
- Simplify `ToActionArtifact` / `ToActionRunner` signatures.

---------

Signed-off-by: bircni <bircni@icloud.com>
Co-authored-by: delvh <dev.lh@web.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
authored and GitHub committed 2026-10-10 12:55:28 +00:00
1 parent c344004e53
commit c30ddc3e14
26 files changed
+113 -223

No files matched your search

+5 -5
View File
@@ -96,7 +96,7 @@ func saveUploadChunkV3(st storage.ObjectStorage, ctx *ArtifactContext, artifact
// save chunk to storage
writtenSize, err := st.Save(storagePath, r, contentSize)
if err != nil {
return 0, fmt.Errorf("save chunk to storage error: %v", err)
return 0, fmt.Errorf("save chunk to storage error: %w", err)
}
defer func() {
@@ -129,7 +129,7 @@ func saveUploadChunkV3GetTotalSize(st storage.ObjectStorage, ctx *ArtifactContex
contentRange := ctx.Req.Header.Get("Content-Range")
var start, end int64
if _, err := fmt.Sscanf(contentRange, "bytes %d-%d/%d", &start, &end, &totalSize); err != nil {
return 0, fmt.Errorf("parse content range error: %v", err)
return 0, fmt.Errorf("parse content range error: %w", err)
}
_, err := saveUploadChunkV3(st, ctx, artifact, runID, saveUploadChunkOptions{start: start, end: &end, checkMd5: true})
if err != nil {
@@ -289,7 +289,7 @@ func mergeChunksForRun(ctx *ArtifactContext, st storage.ObjectStorage, runID, ru
art.StoragePath = storagePath
art.Status = actions.ArtifactStatusUploadConfirmed
if err := actions.UpdateArtifact(ctx, art, "storage_path", "status"); err != nil {
return fmt.Errorf("update artifact error: %v", err)
return fmt.Errorf("update artifact error: %w", err)
}
}
return nil
@@ -342,7 +342,7 @@ func mergeChunksForArtifact(chunks []*chunkFileItem, st storage.ObjectStorage, a
var readCloser io.ReadCloser
var err error
if readCloser, err = st.Open(c.Path); err != nil {
return "", fmt.Errorf("open chunk error: %v, %s", err, c.Path)
return "", fmt.Errorf("open chunk error: %w, %s", err, c.Path)
}
readers = append(readers, readCloser)
}
@@ -362,7 +362,7 @@ func mergeChunksForArtifact(chunks []*chunkFileItem, st storage.ObjectStorage, a
storagePath := generateArtifactStoragePath(artifact)
written, err := st.Save(storagePath, mergedReader, artifact.FileCompressedSize)
if err != nil {
return "", fmt.Errorf("save merged file error: %v", err)
return "", fmt.Errorf("save merged file error: %w", err)
}
if written != artifact.FileCompressedSize {
return "", errors.New("merged file size is not equal to chunk length")
+11 -56
View File
@@ -238,11 +238,7 @@ func (Action) GetVariable(ctx *context.APIContext) {
Name: ctx.PathParam("variablename"),
})
if err != nil {
if errors.Is(err, util.ErrNotExist) {
ctx.APIError(http.StatusNotFound, err.Error())
} else {
ctx.APIErrorInternal(err)
}
ctx.APIErrorAuto(err)
return
}
@@ -939,11 +935,7 @@ func ActionsGetWorkflow(ctx *context.APIContext) {
workflowID := ctx.PathParam("workflow_id")
workflow, err := convert.GetActionWorkflow(ctx, ctx.Repo.GitRepo, ctx.Repo.Repository, workflowID)
if err != nil {
if errors.Is(err, util.ErrNotExist) {
ctx.APIError(http.StatusNotFound, err.Error())
} else {
ctx.APIErrorInternal(err)
}
ctx.APIErrorAuto(err)
return
}
@@ -1088,11 +1080,7 @@ func ActionsDisableWorkflow(ctx *context.APIContext) {
workflowID := ctx.PathParam("workflow_id")
err := actions_service.EnableOrDisableWorkflow(ctx, workflowID, false)
if err != nil {
if errors.Is(err, util.ErrNotExist) {
ctx.APIError(http.StatusNotFound, err.Error())
} else {
ctx.APIErrorInternal(err)
}
ctx.APIErrorAuto(err)
return
}
@@ -1241,11 +1229,7 @@ func ActionsEnableWorkflow(ctx *context.APIContext) {
workflowID := ctx.PathParam("workflow_id")
err := actions_service.EnableOrDisableWorkflow(ctx, workflowID, true)
if err != nil {
if errors.Is(err, util.ErrNotExist) {
ctx.APIError(http.StatusNotFound, err.Error())
} else {
ctx.APIErrorInternal(err)
}
ctx.APIErrorAuto(err)
return
}
@@ -1434,7 +1418,7 @@ func RerunWorkflowRun(ctx *context.APIContext) {
}
if _, err := actions_service.RerunWorkflowRunJobs(ctx, ctx.Repo.Repository, run, ctx.Doer, jobs); err != nil {
handleWorkflowRerunError(ctx, err)
ctx.APIErrorAuto(err)
return
}
@@ -1494,7 +1478,7 @@ func RerunFailedWorkflowRun(ctx *context.APIContext) {
}
if _, err := actions_service.RerunWorkflowRunJobs(ctx, ctx.Repo.Repository, run, ctx.Doer, failedJobs); err != nil {
handleWorkflowRerunError(ctx, err)
ctx.APIErrorAuto(err)
return
}
@@ -1558,7 +1542,7 @@ func RerunWorkflowJob(ctx *context.APIContext) {
targetJob := jobs[jobIdx]
newAttempt, err := actions_service.RerunWorkflowRunJobs(ctx, ctx.Repo.Repository, run, ctx.Doer, []*actions_model.ActionRunJob{targetJob})
if err != nil {
handleWorkflowRerunError(ctx, err)
ctx.APIErrorAuto(err)
return
}
@@ -1573,7 +1557,7 @@ func RerunWorkflowJob(ctx *context.APIContext) {
}
rerunJob, err := actions_model.GetRunJobByAttemptJobID(ctx, run.ID, newAttempt.ID, targetJob.AttemptJobID)
if err != nil {
handleWorkflowRerunError(ctx, err)
ctx.APIErrorAuto(err)
return
}
@@ -1585,20 +1569,6 @@ func RerunWorkflowJob(ctx *context.APIContext) {
ctx.JSON(http.StatusCreated, convertedJob)
}
func handleWorkflowRerunError(ctx *context.APIContext, err error) {
if errors.Is(err, util.ErrInvalidArgument) {
ctx.APIError(http.StatusBadRequest, err.Error())
return
} else if errors.Is(err, util.ErrAlreadyExist) {
ctx.APIError(http.StatusConflict, err.Error())
return
} else if errors.Is(err, util.ErrNotExist) {
ctx.APIError(http.StatusNotFound, err.Error())
return
}
ctx.APIErrorInternal(err)
}
// ListWorkflowRunJobs Lists all jobs for a workflow run.
func ListWorkflowRunJobs(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/actions/runs/{run}/jobs repository listWorkflowRunJobs
@@ -1835,12 +1805,7 @@ func GetArtifactsOfRun(ctx *context.APIContext) {
res.Entries = make([]*api.ActionArtifact, len(artifacts))
for i := range artifacts {
convertedArtifact, err := convert.ToActionArtifact(ctx.Repo.Repository, artifacts[i])
if err != nil {
ctx.APIErrorInternal(err)
return
}
res.Entries[i] = convertedArtifact
res.Entries[i] = convert.ToActionArtifact(ctx.Repo.Repository, artifacts[i])
}
ctx.JSON(http.StatusOK, &res)
@@ -1944,12 +1909,7 @@ func GetArtifacts(ctx *context.APIContext) {
res.Entries = make([]*api.ActionArtifact, len(artifacts))
for i := range artifacts {
convertedArtifact, err := convert.ToActionArtifact(ctx.Repo.Repository, artifacts[i])
if err != nil {
ctx.APIErrorInternal(err)
return
}
res.Entries[i] = convertedArtifact
res.Entries[i] = convert.ToActionArtifact(ctx.Repo.Repository, artifacts[i])
}
ctx.JSON(http.StatusOK, &res)
@@ -1992,12 +1952,7 @@ func GetArtifact(ctx *context.APIContext) {
}
if actions_service.IsArtifactV4(art) {
convertedArtifact, err := convert.ToActionArtifact(ctx.Repo.Repository, art)
if err != nil {
ctx.APIErrorInternal(err)
return
}
ctx.JSON(http.StatusOK, convertedArtifact)
ctx.JSON(http.StatusOK, convert.ToActionArtifact(ctx.Repo.Repository, art))
return
}
// v3 not supported due to not having one unique id
+3 -8
View File
@@ -4,14 +4,12 @@
package shared
import (
"errors"
"net/http"
actions_model "gitea.dev/models/actions"
"gitea.dev/models/db"
"gitea.dev/modules/setting"
api "gitea.dev/modules/structs"
"gitea.dev/modules/util"
"gitea.dev/modules/web"
"gitea.dev/routers/api/v1/utils"
"gitea.dev/services/context"
@@ -25,10 +23,7 @@ type RegistrationToken struct {
}
func GetRegistrationToken(ctx *context.APIContext, ownerID, repoID int64) {
token, err := actions_model.GetLatestRunnerToken(ctx, ownerID, repoID)
if errors.Is(err, util.ErrNotExist) || (token != nil && !token.IsActive) {
token, err = actions_model.NewRunnerToken(ctx, ownerID, repoID)
}
token, err := actions_model.GetOrCreateActiveRunnerToken(ctx, ownerID, repoID)
if err != nil {
ctx.APIErrorInternal(err)
return
@@ -64,7 +59,7 @@ func ListRunners(ctx *context.APIContext, ownerID, repoID int64) {
res.Entries = make([]*api.ActionRunner, len(runners))
for i, runner := range runners {
res.Entries[i] = convert.ToActionRunner(ctx, runner)
res.Entries[i] = convert.ToActionRunner(runner)
}
ctx.JSON(http.StatusOK, &res)
@@ -102,7 +97,7 @@ func GetRunner(ctx *context.APIContext, ownerID, repoID, runnerID int64) {
if !ok {
return
}
ctx.JSON(http.StatusOK, convert.ToActionRunner(ctx, runner))
ctx.JSON(http.StatusOK, convert.ToActionRunner(runner))
}
// DeleteRunner deletes the runner for api route validated ownerID and repoID