diff options
author | FuXiaoHei <fuxiaohei@vip.qq.com> | 2023-05-19 21:37:57 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-19 21:37:57 +0800 |
commit | c757765a9e5c2d4f73b1a7c3debe3548c735bd54 (patch) | |
tree | ffed7692321760ea4f9c72670ed31437b52ff0e0 /routers/web/repo/actions/view.go | |
parent | 7985cde84df5ee93bfb37b20681d69e67d3f32fc (diff) | |
download | gitea-c757765a9e5c2d4f73b1a7c3debe3548c735bd54.tar.gz gitea-c757765a9e5c2d4f73b1a7c3debe3548c735bd54.zip |
Implement actions artifacts (#22738)
Implement action artifacts server api.
This change is used for supporting
https://github.com/actions/upload-artifact and
https://github.com/actions/download-artifact in gitea actions. It can
run sample workflow from doc
https://docs.github.com/en/actions/using-workflows/storing-workflow-data-as-artifacts.
The api design is inspired by
https://github.com/nektos/act/blob/master/pkg/artifacts/server.go and
includes some changes from gitea internal structs and methods.
Actions artifacts contains two parts:
- Gitea server api and storage (this pr implement basic design without
some complex cases supports)
- Runner communicate with gitea server api (in comming)
Old pr https://github.com/go-gitea/gitea/pull/22345 is outdated after
actions merged. I create new pr from main branch.
![897f7694-3e0f-4f7c-bb4b-9936624ead45](https://user-images.githubusercontent.com/2142787/219382371-eb3cf810-e4e0-456b-a8ff-aecc2b1a1032.jpeg)
Add artifacts list in actions workflow page.
Diffstat (limited to 'routers/web/repo/actions/view.go')
-rw-r--r-- | routers/web/repo/actions/view.go | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index c64b0fac39..2114338612 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -16,6 +16,7 @@ import ( "code.gitea.io/gitea/modules/actions" "code.gitea.io/gitea/modules/base" context_module "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" @@ -418,3 +419,80 @@ func getRunJobs(ctx *context_module.Context, runIndex, jobIndex int64) (*actions } return jobs[0], jobs } + +type ArtifactsViewResponse struct { + Artifacts []*ArtifactsViewItem `json:"artifacts"` +} + +type ArtifactsViewItem struct { + Name string `json:"name"` + Size int64 `json:"size"` + ID int64 `json:"id"` +} + +func ArtifactsView(ctx *context_module.Context) { + runIndex := ctx.ParamsInt64("run") + run, err := actions_model.GetRunByIndex(ctx, ctx.Repo.Repository.ID, runIndex) + if err != nil { + if errors.Is(err, util.ErrNotExist) { + ctx.Error(http.StatusNotFound, err.Error()) + return + } + ctx.Error(http.StatusInternalServerError, err.Error()) + return + } + artifacts, err := actions_model.ListUploadedArtifactsByRunID(ctx, run.ID) + if err != nil { + ctx.Error(http.StatusInternalServerError, err.Error()) + return + } + artifactsResponse := ArtifactsViewResponse{ + Artifacts: make([]*ArtifactsViewItem, 0, len(artifacts)), + } + for _, art := range artifacts { + artifactsResponse.Artifacts = append(artifactsResponse.Artifacts, &ArtifactsViewItem{ + Name: art.ArtifactName, + Size: art.FileSize, + ID: art.ID, + }) + } + ctx.JSON(http.StatusOK, artifactsResponse) +} + +func ArtifactsDownloadView(ctx *context_module.Context) { + runIndex := ctx.ParamsInt64("run") + artifactID := ctx.ParamsInt64("id") + + artifact, err := actions_model.GetArtifactByID(ctx, artifactID) + if errors.Is(err, util.ErrNotExist) { + ctx.Error(http.StatusNotFound, err.Error()) + } else if err != nil { + ctx.Error(http.StatusInternalServerError, err.Error()) + return + } + run, err := actions_model.GetRunByIndex(ctx, ctx.Repo.Repository.ID, runIndex) + if err != nil { + if errors.Is(err, util.ErrNotExist) { + ctx.Error(http.StatusNotFound, err.Error()) + return + } + ctx.Error(http.StatusInternalServerError, err.Error()) + return + } + if artifact.RunID != run.ID { + ctx.Error(http.StatusNotFound, "artifact not found") + return + } + + f, err := storage.ActionsArtifacts.Open(artifact.StoragePath) + if err != nil { + ctx.Error(http.StatusInternalServerError, err.Error()) + return + } + defer f.Close() + + ctx.ServeContent(f, &context_module.ServeHeaderOptions{ + Filename: artifact.ArtifactName, + LastModified: artifact.CreatedUnix.AsLocalTime(), + }) +} |