mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-11 04:55:34 +02:00
test
This commit is contained in:
parent
015eb7805c
commit
f4bbd1a2e0
@ -3790,6 +3790,8 @@
|
||||
"actions.workflow.from_ref": "Use workflow from",
|
||||
"actions.workflow.has_workflow_dispatch": "This workflow has a workflow_dispatch event trigger.",
|
||||
"actions.workflow.has_no_workflow_dispatch": "Workflow '%s' has no workflow_dispatch event trigger.",
|
||||
"actions.artifacts.preview_file_not_found": "The requested file is not present in this artifact.",
|
||||
"actions.artifacts.preview_file_too_large": "This file is too large to preview. Please download the artifact to view it.",
|
||||
"actions.need_approval_desc": "Need approval to run workflows for fork pull request.",
|
||||
"actions.approve_all_success": "All workflow runs are approved successfully.",
|
||||
"actions.variables": "Variables",
|
||||
|
||||
@ -505,7 +505,8 @@ func MockActionsArtifactPreview(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
selectedPath := actions.ChoosePreviewPath(mockArtifactFilePaths(files), actions.GetRequestedPreviewPath(ctx))
|
||||
requested := actions.GetRequestedPreviewPath(ctx)
|
||||
selectedPath := actions.ChoosePreviewPath(mockArtifactFilePaths(files), requested)
|
||||
previewFiles := make([]actions.ArtifactPreviewFile, 0, len(files))
|
||||
for _, file := range files {
|
||||
previewFiles = append(previewFiles, actions.ArtifactPreviewFile{
|
||||
@ -524,6 +525,9 @@ func MockActionsArtifactPreview(ctx *context.Context) {
|
||||
ctx.Data["PreviewRawURL"] = previewURL + "/raw"
|
||||
ctx.Data["DownloadURL"] = runURL + "/artifacts/" + url.PathEscape(artifactName)
|
||||
ctx.Data["SelectedPath"] = selectedPath
|
||||
ctx.Data["RequestedPathMissing"] = requested != "" && selectedPath == ""
|
||||
ctx.Data["AttemptQuery"] = ""
|
||||
ctx.Data["AttemptAmpQuery"] = ""
|
||||
ctx.HTML(http.StatusOK, "devtest/repo-action-artifact-preview")
|
||||
}
|
||||
|
||||
|
||||
@ -19,7 +19,6 @@ import (
|
||||
"time"
|
||||
|
||||
actions_model "code.gitea.io/gitea/models/actions"
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/modules/actions"
|
||||
"code.gitea.io/gitea/modules/httplib"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
@ -104,12 +103,17 @@ func getCurrentRunAndUploadedArtifacts(ctx *context_module.Context, artifactName
|
||||
return nil, nil, false
|
||||
}
|
||||
|
||||
artifacts, err := db.Find[actions_model.ActionArtifact](ctx, actions_model.FindArtifactsOptions{
|
||||
RunID: run.ID,
|
||||
ArtifactName: artifactName,
|
||||
})
|
||||
resolvedAttemptID, err := resolveArtifactAttemptIDFromQuery(ctx, run)
|
||||
if err != nil {
|
||||
ctx.ServerError("FindArtifacts", err)
|
||||
ctx.NotFoundOrServerError("resolveArtifactAttemptIDFromQuery", func(err error) bool {
|
||||
return errors.Is(err, util.ErrNotExist)
|
||||
}, err)
|
||||
return nil, nil, false
|
||||
}
|
||||
|
||||
artifacts, err := actions_model.GetArtifactsByRunAttemptAndName(ctx, run.ID, resolvedAttemptID, artifactName)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetArtifactsByRunAttemptAndName", err)
|
||||
return nil, nil, false
|
||||
}
|
||||
if len(artifacts) == 0 {
|
||||
@ -330,13 +334,21 @@ func WritePreviewRawError(ctx *context_module.Context, status int, msg string) {
|
||||
}
|
||||
|
||||
func previewArtifactByReader(ctx *context_module.Context, path string, reader io.Reader) {
|
||||
buf := filebuffer.New(int(setting.UI.MaxDisplayFileSize), "")
|
||||
maxSize := setting.UI.MaxDisplayFileSize
|
||||
buf := filebuffer.New(int(maxSize), "")
|
||||
defer buf.Close()
|
||||
if _, err := io.Copy(buf, io.LimitReader(reader, setting.UI.MaxDisplayFileSize)); err != nil {
|
||||
// Copy maxSize+1 bytes so we can detect truncation: if the reader still has
|
||||
// data after the limit, the file is too large to render in the preview.
|
||||
n, err := io.Copy(buf, io.LimitReader(reader, maxSize+1))
|
||||
if err != nil {
|
||||
log.Error("artifact preview io.Copy: %v", err)
|
||||
WritePreviewRawError(ctx, http.StatusInternalServerError, "failed to read artifact")
|
||||
return
|
||||
}
|
||||
if n > maxSize {
|
||||
WritePreviewRawError(ctx, http.StatusRequestEntityTooLarge, "file is too large to preview, please download the artifact instead")
|
||||
return
|
||||
}
|
||||
if _, err := buf.Seek(0, io.SeekStart); err != nil {
|
||||
log.Error("artifact preview Seek: %v", err)
|
||||
WritePreviewRawError(ctx, http.StatusInternalServerError, "failed to read artifact")
|
||||
@ -387,7 +399,8 @@ func ArtifactsPreviewView(ctx *context_module.Context) {
|
||||
ctx.ServerError("listPreviewPaths", err)
|
||||
return
|
||||
}
|
||||
selectedPath := ChoosePreviewPath(paths, GetRequestedPreviewPath(ctx))
|
||||
requested := GetRequestedPreviewPath(ctx)
|
||||
selectedPath := ChoosePreviewPath(paths, requested)
|
||||
|
||||
previewFiles := make([]ArtifactPreviewFile, 0, len(paths))
|
||||
for _, path := range paths {
|
||||
@ -400,6 +413,12 @@ func ArtifactsPreviewView(ctx *context_module.Context) {
|
||||
runURL := run.Link()
|
||||
artifactPath := url.PathEscape(artifactName)
|
||||
previewURL := runURL + "/artifacts/" + artifactPath + "/preview"
|
||||
downloadURL := runURL + "/artifacts/" + artifactPath
|
||||
attemptQuery, attemptAmpQuery := "", ""
|
||||
if attempt := ctx.FormString("attempt"); attempt != "" {
|
||||
attemptQuery = "?attempt=" + url.QueryEscape(attempt)
|
||||
attemptAmpQuery = "&attempt=" + url.QueryEscape(attempt)
|
||||
}
|
||||
|
||||
ctx.Data["Title"] = ctx.Tr("preview")
|
||||
ctx.Data["PageIsActions"] = true
|
||||
@ -407,8 +426,11 @@ func ArtifactsPreviewView(ctx *context_module.Context) {
|
||||
ctx.Data["ArtifactName"] = artifactName
|
||||
ctx.Data["PreviewURL"] = previewURL
|
||||
ctx.Data["PreviewRawURL"] = previewURL + "/raw"
|
||||
ctx.Data["DownloadURL"] = runURL + "/artifacts/" + artifactPath
|
||||
ctx.Data["DownloadURL"] = downloadURL + attemptQuery
|
||||
ctx.Data["AttemptQuery"] = attemptQuery
|
||||
ctx.Data["AttemptAmpQuery"] = attemptAmpQuery
|
||||
ctx.Data["SelectedPath"] = selectedPath
|
||||
ctx.Data["RequestedPathMissing"] = requested != "" && selectedPath == ""
|
||||
ctx.Data["PreviewFiles"] = previewFiles
|
||||
|
||||
ctx.HTML(http.StatusOK, tplArtifactPreviewAction)
|
||||
|
||||
@ -1,20 +1,3 @@
|
||||
<style>
|
||||
.artifact-preview-page {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.artifact-preview-title {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.artifact-preview-frame {
|
||||
width: 100%;
|
||||
min-height: 70vh;
|
||||
border: 1px solid var(--color-secondary);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="ui top attached header tw-flex tw-items-center tw-justify-between">
|
||||
<div class="artifact-preview-title">
|
||||
<span class="tw-text-base tw-font-semibold">{{ctx.Locale.Tr "preview"}}: <span class="gt-ellipsis">{{.ArtifactName}}</span></span>
|
||||
@ -39,7 +22,7 @@
|
||||
<b>{{ctx.Locale.Tr "files"}}</b>
|
||||
</div>
|
||||
{{range .PreviewFiles}}
|
||||
<a class="item gt-ellipsis {{if .Selected}}active{{end}}" href="{{$.PreviewURL}}?path={{QueryEscape .Path}}" title="{{.Path}}">
|
||||
<a class="item gt-ellipsis {{if .Selected}}active{{end}}" href="{{$.PreviewURL}}?path={{QueryEscape .Path}}{{$.AttemptAmpQuery}}" title="{{.Path}}">
|
||||
{{.Path}}
|
||||
</a>
|
||||
{{else}}
|
||||
@ -51,7 +34,9 @@
|
||||
{{if .SelectedPath}}
|
||||
{{/* sandbox="allow-scripts": scripts execute but in a null/opaque origin (no allow-same-origin), so they cannot
|
||||
access Gitea cookies or the parent frame. The response CSP reinforces this and blocks connect-src. */}}
|
||||
<iframe class="artifact-preview-frame" src="{{.PreviewRawURL}}/{{PathEscapeSegments .SelectedPath}}" sandbox="allow-scripts" referrerpolicy="no-referrer"></iframe>
|
||||
<iframe class="artifact-preview-frame" src="{{.PreviewRawURL}}/{{PathEscapeSegments .SelectedPath}}{{.AttemptQuery}}" sandbox="allow-scripts" referrerpolicy="no-referrer"></iframe>
|
||||
{{else if .RequestedPathMissing}}
|
||||
<div class="ui attached warning message">{{ctx.Locale.Tr "actions.artifacts.preview_file_not_found"}}</div>
|
||||
{{else}}
|
||||
<div class="ui attached segment">{{ctx.Locale.Tr "none"}}</div>
|
||||
{{end}}
|
||||
|
||||
14
web_src/css/features/actions-artifact-preview.css
Normal file
14
web_src/css/features/actions-artifact-preview.css
Normal file
@ -0,0 +1,14 @@
|
||||
.artifact-preview-page {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.artifact-preview-title {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.artifact-preview-frame {
|
||||
width: 100%;
|
||||
min-height: 70vh;
|
||||
border: 1px solid var(--color-secondary);
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
@ -48,6 +48,7 @@
|
||||
@import "./features/cropper.css";
|
||||
@import "./features/console.css";
|
||||
@import "./features/captcha.css";
|
||||
@import "./features/actions-artifact-preview.css";
|
||||
|
||||
@import "./markup/content.css";
|
||||
@import "./markup/codeblock.css";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user