forked from mirrors/forgejo
[v14.0/forgejo] feat(ui): show cancel button until all jobs are finished (#10531)
**Backport:** https://codeberg.org/forgejo/forgejo/pulls/9261 Change that the Cancel button is shown until all jobs are finished and do not hide it, when the first job failed. Additionally the wrapping of the header was changed. Fixes #8922 Co-authored-by: Beowulf <beowulf@beocode.eu> Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10531 Reviewed-by: Beowulf <beowulf@beocode.eu> Reviewed-by: Mathieu Fenniak <mfenniak@noreply.codeberg.org> Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org> Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
This commit is contained in:
parent
83da3ae68c
commit
dd75d0957d
7 changed files with 255 additions and 10 deletions
|
|
@ -533,3 +533,43 @@
|
|||
updated: 1683636626
|
||||
need_approval: false
|
||||
approved_by: 0
|
||||
|
||||
-
|
||||
id: 895
|
||||
title: "job output"
|
||||
repo_id: 4
|
||||
owner_id: 1
|
||||
workflow_id: "test.yaml"
|
||||
index: 191
|
||||
trigger_user_id: 1
|
||||
ref: "refs/heads/master"
|
||||
commit_sha: "c2d72f548424103f01ee1dc02889c1e2bff816b0"
|
||||
event: "push"
|
||||
is_fork_pull_request: false
|
||||
status: 2
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
created: 1683636108
|
||||
updated: 1683636626
|
||||
need_approval: false
|
||||
approved_by: 0
|
||||
|
||||
-
|
||||
id: 896
|
||||
title: "job output"
|
||||
repo_id: 4
|
||||
owner_id: 1
|
||||
workflow_id: "test.yaml"
|
||||
index: 192
|
||||
trigger_user_id: 1
|
||||
ref: "refs/heads/master"
|
||||
commit_sha: "c2d72f548424103f01ee1dc02889c1e2bff816b0"
|
||||
event: "push"
|
||||
is_fork_pull_request: false
|
||||
status: 2
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
created: 1683636108
|
||||
updated: 1683636626
|
||||
need_approval: false
|
||||
approved_by: 0
|
||||
|
|
|
|||
|
|
@ -69,6 +69,66 @@
|
|||
status: 5
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
-
|
||||
id: 197
|
||||
run_id: 895
|
||||
repo_id: 4
|
||||
owner_id: 1
|
||||
commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
|
||||
is_fork_pull_request: false
|
||||
name: job1 (1)
|
||||
attempt: 0
|
||||
job_id: job1
|
||||
task_id: 54
|
||||
status: 2 # failure
|
||||
runs_on: '["postmarketOS"]'
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
-
|
||||
id: 198
|
||||
run_id: 895
|
||||
repo_id: 4
|
||||
owner_id: 1
|
||||
commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
|
||||
is_fork_pull_request: false
|
||||
name: job1 (2)
|
||||
attempt: 0
|
||||
job_id: job1
|
||||
task_id: 55
|
||||
status: 6 # running
|
||||
runs_on: '["postmarketOS"]'
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
-
|
||||
id: 199
|
||||
run_id: 896
|
||||
repo_id: 4
|
||||
owner_id: 1
|
||||
commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
|
||||
is_fork_pull_request: false
|
||||
name: job1 (1)
|
||||
attempt: 0
|
||||
job_id: job1
|
||||
task_id: 56
|
||||
status: 2 # failure
|
||||
runs_on: '["postmarketOS"]'
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
-
|
||||
id: 200
|
||||
run_id: 896
|
||||
repo_id: 4
|
||||
owner_id: 1
|
||||
commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
|
||||
is_fork_pull_request: false
|
||||
name: job1 (2)
|
||||
attempt: 0
|
||||
job_id: job1
|
||||
task_id: 57
|
||||
status: 1 # success
|
||||
runs_on: '["postmarketOS"]'
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
-
|
||||
id: 292
|
||||
run_id: 891
|
||||
|
|
|
|||
|
|
@ -157,3 +157,83 @@
|
|||
log_length: 707
|
||||
log_size: 90179
|
||||
log_expired: false
|
||||
-
|
||||
id: 54
|
||||
job_id: 197
|
||||
attempt: 0
|
||||
runner_id: 1
|
||||
status: 2 # failure
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
repo_id: 4
|
||||
owner_id: 1
|
||||
commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
|
||||
is_fork_pull_request: false
|
||||
token_hash: b8d3962425466b6709b9ac51446f93260c54afe8e7b6d3686e34f991fb8a8953822b0deed86fe41a103f34bc48dbc4784225
|
||||
token_salt: ffffffffff
|
||||
token_last_eight: ffffffff
|
||||
log_filename: artifact-test2/2f/47.log
|
||||
log_in_storage: true
|
||||
log_length: 707
|
||||
log_size: 90179
|
||||
log_expired: false
|
||||
-
|
||||
id: 55
|
||||
job_id: 198
|
||||
attempt: 0
|
||||
runner_id: 1
|
||||
status: 6 # running
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
repo_id: 4
|
||||
owner_id: 1
|
||||
commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
|
||||
is_fork_pull_request: false
|
||||
token_hash: b8d3962425466b6709b9ac51446f93260c54afe8e7b6d3686e34f991fb8a8953822b0deed86fe41a103f34bc48dbc4784226
|
||||
token_salt: ffffffffff
|
||||
token_last_eight: ffffffff
|
||||
log_filename: artifact-test2/2f/47.log
|
||||
log_in_storage: true
|
||||
log_length: 707
|
||||
log_size: 90179
|
||||
log_expired: false
|
||||
-
|
||||
id: 56
|
||||
job_id: 199
|
||||
attempt: 0
|
||||
runner_id: 1
|
||||
status: 2 # failure
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
repo_id: 4
|
||||
owner_id: 1
|
||||
commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
|
||||
is_fork_pull_request: false
|
||||
token_hash: b8d3962425466b6709b9ac51446f93260c54afe8e7b6d3686e34f991fb8a8953822b0deed86fe41a103f34bc48dbc4784227
|
||||
token_salt: ffffffffff
|
||||
token_last_eight: ffffffff
|
||||
log_filename: artifact-test2/2f/47.log
|
||||
log_in_storage: true
|
||||
log_length: 707
|
||||
log_size: 90179
|
||||
log_expired: false
|
||||
-
|
||||
id: 57
|
||||
job_id: 200
|
||||
attempt: 0
|
||||
runner_id: 1
|
||||
status: 1 # success
|
||||
started: 1683636528
|
||||
stopped: 1683636626
|
||||
repo_id: 4
|
||||
owner_id: 1
|
||||
commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
|
||||
is_fork_pull_request: false
|
||||
token_hash: b8d3962425466b6709b9ac51446f93260c54afe8e7b6d3686e34f991fb8a8953822b0deed86fe41a103f34bc48dbc4784228
|
||||
token_salt: ffffffffff
|
||||
token_last_eight: ffffffff
|
||||
log_filename: artifact-test2/2f/47.log
|
||||
log_in_storage: true
|
||||
log_length: 707
|
||||
log_size: 90179
|
||||
log_expired: false
|
||||
|
|
|
|||
|
|
@ -282,7 +282,6 @@ func getViewResponse(ctx *app_context.Context, req *ViewRequest, runIndex, jobIn
|
|||
resp.State.Run.Title = run.Title
|
||||
resp.State.Run.TitleHTML = templates.RenderCommitMessage(ctx, run.Title, metas)
|
||||
resp.State.Run.Link = run.Link()
|
||||
resp.State.Run.CanCancel = !run.Status.IsDone() && ctx.Repo.CanWrite(unit.TypeActions)
|
||||
resp.State.Run.CanApprove = run.NeedApproval && ctx.Repo.CanWrite(unit.TypeActions)
|
||||
resp.State.Run.CanRerun = run.Status.IsDone() && ctx.Repo.CanWrite(unit.TypeActions)
|
||||
resp.State.Run.CanDeleteArtifact = run.Status.IsDone() && ctx.Repo.CanWrite(unit.TypeActions)
|
||||
|
|
@ -310,6 +309,7 @@ func getViewResponse(ctx *app_context.Context, req *ViewRequest, runIndex, jobIn
|
|||
})
|
||||
}
|
||||
resp.State.Run.Done = done
|
||||
resp.State.Run.CanCancel = !done && ctx.Repo.CanWrite(unit.TypeActions)
|
||||
|
||||
pusher := ViewUser{
|
||||
DisplayName: run.TriggerUser.GetDisplayName(),
|
||||
|
|
|
|||
|
|
@ -382,6 +382,55 @@ func TestActionsViewViewPost(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestActionsViewCancelableUntilAllJobsFinished(t *testing.T) {
|
||||
unittest.PrepareTestEnv(t)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
runIndex int64
|
||||
assert func(*testing.T, *ViewResponse)
|
||||
}{
|
||||
{
|
||||
name: "failed and running",
|
||||
runIndex: 191,
|
||||
assert: func(t *testing.T, actual *ViewResponse) {
|
||||
assert.Equal(t, "failure", actual.State.Run.Jobs[0].Status)
|
||||
assert.Equal(t, "running", actual.State.Run.Jobs[1].Status)
|
||||
assert.True(t, actual.State.Run.CanCancel)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "failed and success",
|
||||
runIndex: 192,
|
||||
assert: func(t *testing.T, actual *ViewResponse) {
|
||||
assert.Equal(t, "failure", actual.State.Run.Jobs[0].Status)
|
||||
assert.Equal(t, "success", actual.State.Run.Jobs[1].Status)
|
||||
assert.False(t, actual.State.Run.CanCancel)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ctx, resp := contexttest.MockContext(t, "user2/repo1/actions/runs/0")
|
||||
contexttest.LoadUser(t, ctx, 1)
|
||||
contexttest.LoadRepo(t, ctx, 4)
|
||||
ctx.SetParams(":run", fmt.Sprintf("%d", tt.runIndex))
|
||||
ctx.SetParams(":attempt", fmt.Sprintf("%d", 0))
|
||||
web.SetForm(ctx, &ViewRequest{})
|
||||
|
||||
ViewPost(ctx)
|
||||
require.Equal(t, http.StatusOK, resp.Result().StatusCode, "failure in ViewPost(): %q", resp.Body.String())
|
||||
|
||||
var actual ViewResponse
|
||||
err := json.Unmarshal(resp.Body.Bytes(), &actual)
|
||||
require.NoError(t, err)
|
||||
|
||||
tt.assert(t, &actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestActionsViewRedirectToLatestAttempt(t *testing.T) {
|
||||
unittest.PrepareTestEnv(t)
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ func TestActionsAPISearchActionJobs_GlobalRunnerAllPendingJobs(t *testing.T) {
|
|||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
job196 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: 196})
|
||||
job198 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: 198})
|
||||
job393 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: 393})
|
||||
job394 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: 394})
|
||||
job395 := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: 395})
|
||||
|
|
@ -81,11 +82,12 @@ func TestActionsAPISearchActionJobs_GlobalRunnerAllPendingJobs(t *testing.T) {
|
|||
var jobs []*api.ActionRunJob
|
||||
DecodeJSON(t, res, &jobs)
|
||||
|
||||
assert.Len(t, jobs, 6)
|
||||
assert.Len(t, jobs, 7)
|
||||
assert.Equal(t, job397.ID, jobs[0].ID)
|
||||
assert.Equal(t, job396.ID, jobs[1].ID)
|
||||
assert.Equal(t, job395.ID, jobs[2].ID)
|
||||
assert.Equal(t, job394.ID, jobs[3].ID)
|
||||
assert.Equal(t, job393.ID, jobs[4].ID)
|
||||
assert.Equal(t, job196.ID, jobs[5].ID)
|
||||
assert.Equal(t, job198.ID, jobs[5].ID)
|
||||
assert.Equal(t, job196.ID, jobs[6].ID)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -472,12 +472,14 @@ export default {
|
|||
<button class="ui basic small compact button primary" @click="approveRun()" v-if="canApprove">
|
||||
{{ locale.approve }}
|
||||
</button>
|
||||
<button class="ui basic small compact button red" @click="cancelRun()" v-else-if="canCancel">
|
||||
{{ locale.cancel }}
|
||||
</button>
|
||||
<button class="ui basic small compact button tw-mr-0 tw-whitespace-nowrap link-action" :data-url="`${run.link}/rerun`" v-else-if="canRerun">
|
||||
{{ locale.rerun_all }}
|
||||
</button>
|
||||
<div class="action-info-summary-actions" v-else>
|
||||
<button class="ui basic small compact button red" @click="cancelRun()" v-if="canCancel">
|
||||
{{ locale.cancel }}
|
||||
</button>
|
||||
<button class="ui basic small compact button tw-mr-0 tw-whitespace-nowrap link-action" :data-url="`${run.link}/rerun`" v-if="canRerun">
|
||||
{{ locale.rerun_all }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="action-summary">
|
||||
{{ run.commit.localeCommit }}
|
||||
|
|
@ -629,9 +631,10 @@ export default {
|
|||
|
||||
.action-info-summary {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.action-info-summary-title {
|
||||
|
|
@ -640,6 +643,17 @@ export default {
|
|||
gap: 0.5em;
|
||||
}
|
||||
|
||||
.action-info-summary-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--button-spacing);
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.action-info-summary-actions > button {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.action-info-summary-title-text {
|
||||
font-size: 20px;
|
||||
margin: 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue