mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-21 04:45:02 +02:00
Merge branch 'main' into workflow_job_webhook_bp
This commit is contained in:
commit
ab8bab918a
4
.github/workflows/release-tag-version.yml
vendored
4
.github/workflows/release-tag-version.yml
vendored
@ -88,9 +88,9 @@ jobs:
|
|||||||
# 1.2
|
# 1.2
|
||||||
# 1.2.3
|
# 1.2.3
|
||||||
tags: |
|
tags: |
|
||||||
|
type=semver,pattern={{version}}
|
||||||
type=semver,pattern={{major}}
|
type=semver,pattern={{major}}
|
||||||
type=semver,pattern={{major}}.{{minor}}
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
type=semver,pattern={{version}}
|
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
@ -126,9 +126,9 @@ jobs:
|
|||||||
# 1.2
|
# 1.2
|
||||||
# 1.2.3
|
# 1.2.3
|
||||||
tags: |
|
tags: |
|
||||||
|
type=semver,pattern={{version}}
|
||||||
type=semver,pattern={{major}}
|
type=semver,pattern={{major}}
|
||||||
type=semver,pattern={{major}}.{{minor}}
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
type=semver,pattern={{version}}
|
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
|
4
go.mod
4
go.mod
@ -117,10 +117,10 @@ require (
|
|||||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
|
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
|
||||||
github.com/yuin/goldmark-meta v1.1.0
|
github.com/yuin/goldmark-meta v1.1.0
|
||||||
gitlab.com/gitlab-org/api/client-go v0.123.0
|
gitlab.com/gitlab-org/api/client-go v0.123.0
|
||||||
golang.org/x/crypto v0.33.0
|
golang.org/x/crypto v0.35.0
|
||||||
golang.org/x/image v0.24.0
|
golang.org/x/image v0.24.0
|
||||||
golang.org/x/net v0.35.0
|
golang.org/x/net v0.35.0
|
||||||
golang.org/x/oauth2 v0.26.0
|
golang.org/x/oauth2 v0.27.0
|
||||||
golang.org/x/sync v0.11.0
|
golang.org/x/sync v0.11.0
|
||||||
golang.org/x/sys v0.30.0
|
golang.org/x/sys v0.30.0
|
||||||
golang.org/x/text v0.22.0
|
golang.org/x/text v0.22.0
|
||||||
|
7
go.sum
7
go.sum
@ -831,8 +831,9 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
|
|||||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
|
|
||||||
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
|
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
|
||||||
|
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||||
|
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||||
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4=
|
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4=
|
||||||
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk=
|
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk=
|
||||||
golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ=
|
golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ=
|
||||||
@ -868,8 +869,8 @@ golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
|||||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||||
golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE=
|
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
|
||||||
golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
@ -454,6 +454,24 @@ func ActivityReadable(user, doer *user_model.User) bool {
|
|||||||
doer != nil && (doer.IsAdmin || user.ID == doer.ID)
|
doer != nil && (doer.IsAdmin || user.ID == doer.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FeedDateCond(opts GetFeedsOptions) builder.Cond {
|
||||||
|
cond := builder.NewCond()
|
||||||
|
if opts.Date == "" {
|
||||||
|
return cond
|
||||||
|
}
|
||||||
|
|
||||||
|
dateLow, err := time.ParseInLocation("2006-01-02", opts.Date, setting.DefaultUILocation)
|
||||||
|
if err != nil {
|
||||||
|
log.Warn("Unable to parse %s, filter not applied: %v", opts.Date, err)
|
||||||
|
} else {
|
||||||
|
dateHigh := dateLow.Add(86399000000000) // 23h59m59s
|
||||||
|
|
||||||
|
cond = cond.And(builder.Gte{"`action`.created_unix": dateLow.Unix()})
|
||||||
|
cond = cond.And(builder.Lte{"`action`.created_unix": dateHigh.Unix()})
|
||||||
|
}
|
||||||
|
return cond
|
||||||
|
}
|
||||||
|
|
||||||
func ActivityQueryCondition(ctx context.Context, opts GetFeedsOptions) (builder.Cond, error) {
|
func ActivityQueryCondition(ctx context.Context, opts GetFeedsOptions) (builder.Cond, error) {
|
||||||
cond := builder.NewCond()
|
cond := builder.NewCond()
|
||||||
|
|
||||||
@ -534,17 +552,7 @@ func ActivityQueryCondition(ctx context.Context, opts GetFeedsOptions) (builder.
|
|||||||
cond = cond.And(builder.Eq{"is_deleted": false})
|
cond = cond.And(builder.Eq{"is_deleted": false})
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Date != "" {
|
cond = cond.And(FeedDateCond(opts))
|
||||||
dateLow, err := time.ParseInLocation("2006-01-02", opts.Date, setting.DefaultUILocation)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("Unable to parse %s, filter not applied: %v", opts.Date, err)
|
|
||||||
} else {
|
|
||||||
dateHigh := dateLow.Add(86399000000000) // 23h59m59s
|
|
||||||
|
|
||||||
cond = cond.And(builder.Gte{"`action`.created_unix": dateLow.Unix()})
|
|
||||||
cond = cond.And(builder.Lte{"`action`.created_unix": dateHigh.Unix()})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cond, nil
|
return cond, nil
|
||||||
}
|
}
|
||||||
|
@ -208,9 +208,31 @@ func GetFeeds(ctx context.Context, opts GetFeedsOptions) (ActionList, int64, err
|
|||||||
return nil, 0, fmt.Errorf("need at least one of these filters: RequestedUser, RequestedTeam, RequestedRepo")
|
return nil, 0, fmt.Errorf("need at least one of these filters: RequestedUser, RequestedTeam, RequestedRepo")
|
||||||
}
|
}
|
||||||
|
|
||||||
cond, err := ActivityQueryCondition(ctx, opts)
|
var err error
|
||||||
if err != nil {
|
var cond builder.Cond
|
||||||
return nil, 0, err
|
// if the actor is the requested user or is an administrator, we can skip the ActivityQueryCondition
|
||||||
|
if opts.Actor != nil && opts.RequestedUser != nil && (opts.Actor.IsAdmin || opts.Actor.ID == opts.RequestedUser.ID) {
|
||||||
|
cond = builder.Eq{
|
||||||
|
"user_id": opts.RequestedUser.ID,
|
||||||
|
}.And(
|
||||||
|
FeedDateCond(opts),
|
||||||
|
)
|
||||||
|
|
||||||
|
if !opts.IncludeDeleted {
|
||||||
|
cond = cond.And(builder.Eq{"is_deleted": false})
|
||||||
|
}
|
||||||
|
|
||||||
|
if !opts.IncludePrivate {
|
||||||
|
cond = cond.And(builder.Eq{"is_private": false})
|
||||||
|
}
|
||||||
|
if opts.OnlyPerformedBy {
|
||||||
|
cond = cond.And(builder.Eq{"act_user_id": opts.RequestedUser.ID})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cond, err = ActivityQueryCondition(ctx, opts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
actions := make([]*Action, 0, opts.PageSize)
|
actions := make([]*Action, 0, opts.PageSize)
|
||||||
|
@ -1465,6 +1465,8 @@ issues.filter_milestones = Filter Milestone
|
|||||||
issues.filter_projects = Filter Project
|
issues.filter_projects = Filter Project
|
||||||
issues.filter_labels = Filter Label
|
issues.filter_labels = Filter Label
|
||||||
issues.filter_reviewers = Filter Reviewer
|
issues.filter_reviewers = Filter Reviewer
|
||||||
|
issues.filter_no_results = No results
|
||||||
|
issues.filter_no_results_placeholder = Try adjusting your search filters.
|
||||||
issues.new = New Issue
|
issues.new = New Issue
|
||||||
issues.new.title_empty = Title cannot be empty
|
issues.new.title_empty = Title cannot be empty
|
||||||
issues.new.labels = Labels
|
issues.new.labels = Labels
|
||||||
|
@ -52,13 +52,22 @@ func generateMockStepsLog(logCur actions.LogCursor) (stepsLog []*actions.ViewSte
|
|||||||
return stepsLog
|
return stepsLog
|
||||||
}
|
}
|
||||||
|
|
||||||
func MockActionsRunsJobs(ctx *context.Context) {
|
func MockActionsView(ctx *context.Context) {
|
||||||
req := web.GetForm(ctx).(*actions.ViewRequest)
|
ctx.Data["RunID"] = ctx.PathParam("run")
|
||||||
|
ctx.Data["JobID"] = ctx.PathParam("job")
|
||||||
|
ctx.HTML(http.StatusOK, "devtest/repo-action-view")
|
||||||
|
}
|
||||||
|
|
||||||
|
func MockActionsRunsJobs(ctx *context.Context) {
|
||||||
|
runID := ctx.PathParamInt64("run")
|
||||||
|
|
||||||
|
req := web.GetForm(ctx).(*actions.ViewRequest)
|
||||||
resp := &actions.ViewResponse{}
|
resp := &actions.ViewResponse{}
|
||||||
resp.State.Run.TitleHTML = `mock run title <a href="/">link</a>`
|
resp.State.Run.TitleHTML = `mock run title <a href="/">link</a>`
|
||||||
resp.State.Run.Status = actions_model.StatusRunning.String()
|
resp.State.Run.Status = actions_model.StatusRunning.String()
|
||||||
resp.State.Run.CanCancel = true
|
resp.State.Run.CanCancel = runID == 10
|
||||||
|
resp.State.Run.CanApprove = runID == 20
|
||||||
|
resp.State.Run.CanRerun = runID == 30
|
||||||
resp.State.Run.CanDeleteArtifact = true
|
resp.State.Run.CanDeleteArtifact = true
|
||||||
resp.State.Run.WorkflowID = "workflow-id"
|
resp.State.Run.WorkflowID = "workflow-id"
|
||||||
resp.State.Run.WorkflowLink = "./workflow-link"
|
resp.State.Run.WorkflowLink = "./workflow-link"
|
||||||
@ -85,6 +94,29 @@ func MockActionsRunsJobs(ctx *context.Context) {
|
|||||||
Size: 1024 * 1024,
|
Size: 1024 * 1024,
|
||||||
Status: "completed",
|
Status: "completed",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
resp.State.Run.Jobs = append(resp.State.Run.Jobs, &actions.ViewJob{
|
||||||
|
ID: runID * 10,
|
||||||
|
Name: "job 100",
|
||||||
|
Status: actions_model.StatusRunning.String(),
|
||||||
|
CanRerun: true,
|
||||||
|
Duration: "1h",
|
||||||
|
})
|
||||||
|
resp.State.Run.Jobs = append(resp.State.Run.Jobs, &actions.ViewJob{
|
||||||
|
ID: runID*10 + 1,
|
||||||
|
Name: "job 101",
|
||||||
|
Status: actions_model.StatusWaiting.String(),
|
||||||
|
CanRerun: false,
|
||||||
|
Duration: "2h",
|
||||||
|
})
|
||||||
|
resp.State.Run.Jobs = append(resp.State.Run.Jobs, &actions.ViewJob{
|
||||||
|
ID: runID*10 + 2,
|
||||||
|
Name: "job 102",
|
||||||
|
Status: actions_model.StatusFailure.String(),
|
||||||
|
CanRerun: false,
|
||||||
|
Duration: "3h",
|
||||||
|
})
|
||||||
|
|
||||||
resp.State.CurrentJob.Steps = append(resp.State.CurrentJob.Steps, &actions.ViewJobStep{
|
resp.State.CurrentJob.Steps = append(resp.State.CurrentJob.Steps, &actions.ViewJobStep{
|
||||||
Summary: "step 0 (mock slow)",
|
Summary: "step 0 (mock slow)",
|
||||||
Duration: time.Hour.String(),
|
Duration: time.Hour.String(),
|
||||||
|
@ -78,7 +78,7 @@ func httpBase(ctx *context.Context) *serviceHandler {
|
|||||||
strings.HasSuffix(ctx.Req.URL.Path, "git-upload-archive") {
|
strings.HasSuffix(ctx.Req.URL.Path, "git-upload-archive") {
|
||||||
isPull = true
|
isPull = true
|
||||||
} else {
|
} else {
|
||||||
isPull = ctx.Req.Method == "GET"
|
isPull = ctx.Req.Method == "HEAD" || ctx.Req.Method == "GET"
|
||||||
}
|
}
|
||||||
|
|
||||||
var accessMode perm.AccessMode
|
var accessMode perm.AccessMode
|
||||||
|
@ -1634,6 +1634,7 @@ func registerRoutes(m *web.Router) {
|
|||||||
m.Any("", devtest.List)
|
m.Any("", devtest.List)
|
||||||
m.Any("/fetch-action-test", devtest.FetchActionTest)
|
m.Any("/fetch-action-test", devtest.FetchActionTest)
|
||||||
m.Any("/{sub}", devtest.Tmpl)
|
m.Any("/{sub}", devtest.Tmpl)
|
||||||
|
m.Get("/repo-action-view/{run}/{job}", devtest.MockActionsView)
|
||||||
m.Post("/actions-mock/runs/{run}/jobs/{job}", web.Bind(actions.ViewRequest{}), devtest.MockActionsRunsJobs)
|
m.Post("/actions-mock/runs/{run}/jobs/{job}", web.Bind(actions.ViewRequest{}), devtest.MockActionsRunsJobs)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -291,6 +291,11 @@ func RepoRefForAPI(next http.Handler) http.Handler {
|
|||||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||||
ctx := GetAPIContext(req)
|
ctx := GetAPIContext(req)
|
||||||
|
|
||||||
|
if ctx.Repo.Repository.IsEmpty {
|
||||||
|
ctx.APIErrorNotFound("repository is empty")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if ctx.Repo.GitRepo == nil {
|
if ctx.Repo.GitRepo == nil {
|
||||||
ctx.APIErrorInternal(fmt.Errorf("no open git repo"))
|
ctx.APIErrorInternal(fmt.Errorf("no open git repo"))
|
||||||
return
|
return
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
{{template "base/head" .}}
|
{{template "base/head" .}}
|
||||||
<div class="page-content">
|
<div class="page-content">
|
||||||
|
<div class="tw-flex tw-justify-center tw-items-center tw-gap-5">
|
||||||
|
<a href="/devtest/repo-action-view/10/100">Run:CanCancel</a>
|
||||||
|
<a href="/devtest/repo-action-view/20/200">Run:CanApprove</a>
|
||||||
|
<a href="/devtest/repo-action-view/30/300">Run:CanRerun</a>
|
||||||
|
</div>
|
||||||
{{template "repo/actions/view_component" (dict
|
{{template "repo/actions/view_component" (dict
|
||||||
"RunIndex" 1
|
"RunIndex" (or .RunID 10)
|
||||||
"JobIndex" 2
|
"JobIndex" (or .JobID 100)
|
||||||
"ActionsURL" (print AppSubUrl "/devtest/actions-mock")
|
"ActionsURL" (print AppSubUrl "/devtest/actions-mock")
|
||||||
)}}
|
)}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -153,6 +153,11 @@
|
|||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="tw-text-center tw-p-8">
|
||||||
|
<h3 class="tw-my-4">{{ctx.Locale.Tr "repo.issues.filter_no_results"}}</h3>
|
||||||
|
<p class="tw-text-placeholder-text">{{ctx.Locale.Tr "repo.issues.filter_no_results_placeholder"}}</p>
|
||||||
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{if .IssueIndexerUnavailable}}
|
{{if .IssueIndexerUnavailable}}
|
||||||
<div class="ui error message">
|
<div class="ui error message">
|
||||||
|
@ -60,12 +60,20 @@ func TestEmptyRepoAddFile(t *testing.T) {
|
|||||||
defer tests.PrepareTestEnv(t)()
|
defer tests.PrepareTestEnv(t)()
|
||||||
|
|
||||||
session := loginUser(t, "user30")
|
session := loginUser(t, "user30")
|
||||||
|
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository)
|
||||||
|
|
||||||
|
// test web page
|
||||||
req := NewRequest(t, "GET", "/user30/empty")
|
req := NewRequest(t, "GET", "/user30/empty")
|
||||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||||
bodyString := resp.Body.String()
|
bodyString := resp.Body.String()
|
||||||
assert.Contains(t, bodyString, "empty-repo-guide")
|
assert.Contains(t, bodyString, "empty-repo-guide")
|
||||||
assert.True(t, test.IsNormalPageCompleted(bodyString))
|
assert.True(t, test.IsNormalPageCompleted(bodyString))
|
||||||
|
|
||||||
|
// test api
|
||||||
|
req = NewRequest(t, "GET", "/api/v1/repos/user30/empty/raw/main/README.md").AddTokenAuth(token)
|
||||||
|
session.MakeRequest(t, req, http.StatusNotFound)
|
||||||
|
|
||||||
|
// create a new file
|
||||||
req = NewRequest(t, "GET", "/user30/empty/_new/"+setting.Repository.DefaultBranch)
|
req = NewRequest(t, "GET", "/user30/empty/_new/"+setting.Repository.DefaultBranch)
|
||||||
resp = session.MakeRequest(t, req, http.StatusOK)
|
resp = session.MakeRequest(t, req, http.StatusOK)
|
||||||
doc := NewHTMLParser(t, resp.Body).Find(`input[name="commit_choice"]`)
|
doc := NewHTMLParser(t, resp.Body).Find(`input[name="commit_choice"]`)
|
||||||
|
@ -9,7 +9,10 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGitSmartHTTP(t *testing.T) {
|
func TestGitSmartHTTP(t *testing.T) {
|
||||||
@ -18,51 +21,55 @@ func TestGitSmartHTTP(t *testing.T) {
|
|||||||
|
|
||||||
func testGitSmartHTTP(t *testing.T, u *url.URL) {
|
func testGitSmartHTTP(t *testing.T, u *url.URL) {
|
||||||
kases := []struct {
|
kases := []struct {
|
||||||
p string
|
method, path string
|
||||||
code int
|
code int
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
p: "user2/repo1/info/refs",
|
path: "user2/repo1/info/refs",
|
||||||
code: http.StatusOK,
|
code: http.StatusOK,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
p: "user2/repo1/HEAD",
|
method: "HEAD",
|
||||||
|
path: "user2/repo1/info/refs",
|
||||||
|
code: http.StatusOK,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "user2/repo1/HEAD",
|
||||||
code: http.StatusOK,
|
code: http.StatusOK,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
p: "user2/repo1/objects/info/alternates",
|
path: "user2/repo1/objects/info/alternates",
|
||||||
code: http.StatusNotFound,
|
code: http.StatusNotFound,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
p: "user2/repo1/objects/info/http-alternates",
|
path: "user2/repo1/objects/info/http-alternates",
|
||||||
code: http.StatusNotFound,
|
code: http.StatusNotFound,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
p: "user2/repo1/../../custom/conf/app.ini",
|
path: "user2/repo1/../../custom/conf/app.ini",
|
||||||
code: http.StatusNotFound,
|
code: http.StatusNotFound,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
p: "user2/repo1/objects/info/../../../../custom/conf/app.ini",
|
path: "user2/repo1/objects/info/../../../../custom/conf/app.ini",
|
||||||
code: http.StatusNotFound,
|
code: http.StatusNotFound,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
p: `user2/repo1/objects/info/..\..\..\..\custom\conf\app.ini`,
|
path: `user2/repo1/objects/info/..\..\..\..\custom\conf\app.ini`,
|
||||||
code: http.StatusBadRequest,
|
code: http.StatusBadRequest,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, kase := range kases {
|
for _, kase := range kases {
|
||||||
t.Run(kase.p, func(t *testing.T) {
|
t.Run(kase.path, func(t *testing.T) {
|
||||||
p := u.String() + kase.p
|
req, err := http.NewRequest(util.IfZero(kase.method, "GET"), u.String()+kase.path, nil)
|
||||||
req, err := http.NewRequest("GET", p, nil)
|
require.NoError(t, err)
|
||||||
assert.NoError(t, err)
|
|
||||||
req.SetBasicAuth("user2", userPassword)
|
req.SetBasicAuth("user2", userPassword)
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
assert.EqualValues(t, kase.code, resp.StatusCode)
|
assert.EqualValues(t, kase.code, resp.StatusCode)
|
||||||
_, err = io.ReadAll(resp.Body)
|
_, err = io.ReadAll(resp.Body)
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,6 @@ export default defineComponent({
|
|||||||
intervalID: null as IntervalId | null,
|
intervalID: null as IntervalId | null,
|
||||||
currentJobStepsStates: [] as Array<Record<string, any>>,
|
currentJobStepsStates: [] as Array<Record<string, any>>,
|
||||||
artifacts: [] as Array<Record<string, any>>,
|
artifacts: [] as Array<Record<string, any>>,
|
||||||
onHoverRerunIndex: -1,
|
|
||||||
menuVisible: false,
|
menuVisible: false,
|
||||||
isFullScreen: false,
|
isFullScreen: false,
|
||||||
timeVisible: {
|
timeVisible: {
|
||||||
@ -120,7 +119,7 @@ export default defineComponent({
|
|||||||
link: '',
|
link: '',
|
||||||
title: '',
|
title: '',
|
||||||
titleHTML: '',
|
titleHTML: '',
|
||||||
status: 'unknown' as RunStatus,
|
status: '' as RunStatus, // do not show the status before initialized, otherwise it would show an incorrect "error" icon
|
||||||
canCancel: false,
|
canCancel: false,
|
||||||
canApprove: false,
|
canApprove: false,
|
||||||
canRerun: false,
|
canRerun: false,
|
||||||
@ -492,13 +491,13 @@ export default defineComponent({
|
|||||||
<div class="action-view-left">
|
<div class="action-view-left">
|
||||||
<div class="job-group-section">
|
<div class="job-group-section">
|
||||||
<div class="job-brief-list">
|
<div class="job-brief-list">
|
||||||
<a class="job-brief-item" :href="run.link+'/jobs/'+index" :class="parseInt(jobIndex) === index ? 'selected' : ''" v-for="(job, index) in run.jobs" :key="job.id" @mouseenter="onHoverRerunIndex = job.id" @mouseleave="onHoverRerunIndex = -1">
|
<a class="job-brief-item" :href="run.link+'/jobs/'+index" :class="parseInt(jobIndex) === index ? 'selected' : ''" v-for="(job, index) in run.jobs" :key="job.id">
|
||||||
<div class="job-brief-item-left">
|
<div class="job-brief-item-left">
|
||||||
<ActionRunStatus :locale-status="locale.status[job.status]" :status="job.status"/>
|
<ActionRunStatus :locale-status="locale.status[job.status]" :status="job.status"/>
|
||||||
<span class="job-brief-name tw-mx-2 gt-ellipsis">{{ job.name }}</span>
|
<span class="job-brief-name tw-mx-2 gt-ellipsis">{{ job.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="job-brief-item-right">
|
<span class="job-brief-item-right">
|
||||||
<SvgIcon name="octicon-sync" role="button" :data-tooltip-content="locale.rerun" class="job-brief-rerun tw-mx-2 link-action" :data-url="`${run.link}/jobs/${index}/rerun`" v-if="job.canRerun && onHoverRerunIndex === job.id"/>
|
<SvgIcon name="octicon-sync" role="button" :data-tooltip-content="locale.rerun" class="job-brief-rerun tw-mx-2 link-action" :data-url="`${run.link}/jobs/${index}/rerun`" v-if="job.canRerun"/>
|
||||||
<span class="step-summary-duration">{{ job.duration }}</span>
|
<span class="step-summary-duration">{{ job.duration }}</span>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
@ -721,11 +720,6 @@ export default defineComponent({
|
|||||||
|
|
||||||
.job-brief-item .job-brief-rerun {
|
.job-brief-item .job-brief-rerun {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: transform 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.job-brief-item .job-brief-rerun:hover {
|
|
||||||
transform: scale(130%);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.job-brief-item .job-brief-item-left {
|
.job-brief-item .job-brief-item-left {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user