0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-01-18 20:51:43 +01:00

Merge 24c38e54065bfc5606dee9f46b831160e9ff49d3 into 393c854f7bf2ae91262f8ce111c26c4e08451e17

This commit is contained in:
Semenets V. Pavel 2026-01-16 13:28:32 -08:00 committed by GitHub
commit 10ebe6fee7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 1301 additions and 35 deletions

View File

@ -161,6 +161,7 @@ type ActionWorkflowStep struct {
// ActionWorkflowJob represents a WorkflowJob
type ActionWorkflowJob struct {
ID int64 `json:"id"`
JobID string `json:"job_id,omitempty"`
URL string `json:"url"`
HTMLURL string `json:"html_url"`
RunID int64 `json:"run_id"`
@ -175,6 +176,7 @@ type ActionWorkflowJob struct {
RunnerID int64 `json:"runner_id,omitempty"`
RunnerName string `json:"runner_name,omitempty"`
Steps []*ActionWorkflowStep `json:"steps"`
Needs []string `json:"needs,omitempty"`
// swagger:strfmt date-time
CreatedAt time.Time `json:"created_at"`
// swagger:strfmt date-time

View File

@ -142,11 +142,13 @@ type ViewResponse struct {
}
type ViewJob struct {
ID int64 `json:"id"`
Name string `json:"name"`
Status string `json:"status"`
CanRerun bool `json:"canRerun"`
Duration string `json:"duration"`
ID int64 `json:"id"`
JobID string `json:"job_id,omitempty"`
Name string `json:"name"`
Status string `json:"status"`
CanRerun bool `json:"canRerun"`
Duration string `json:"duration"`
Needs []string `json:"needs,omitempty"`
}
type ViewCommit struct {
@ -247,10 +249,12 @@ func ViewPost(ctx *context_module.Context) {
for _, v := range jobs {
resp.State.Run.Jobs = append(resp.State.Run.Jobs, &ViewJob{
ID: v.ID,
JobID: v.JobID,
Name: v.Name,
Status: v.Status.String(),
CanRerun: resp.State.Run.CanRerun,
Duration: v.Duration().String(),
Needs: v.Needs,
})
}

View File

@ -367,7 +367,8 @@ func ToActionWorkflowJob(ctx context.Context, repo *repo_model.Repository, task
}
return &api.ActionWorkflowJob{
ID: job.ID,
ID: job.ID,
JobID: job.JobID,
// missing api endpoint for this location
URL: fmt.Sprintf("%s/actions/jobs/%d", repo.APIURL(), job.ID),
HTMLURL: fmt.Sprintf("%s/jobs/%d", job.Run.HTMLURL(), jobIndex),
@ -384,6 +385,7 @@ func ToActionWorkflowJob(ctx context.Context, repo *repo_model.Repository, task
RunnerID: runnerID,
RunnerName: runnerName,
Steps: steps,
Needs: job.Needs,
CreatedAt: job.Created.AsTime().UTC(),
StartedAt: job.Started.AsTime().UTC(),
CompletedAt: job.Stopped.AsTime().UTC(),

View File

@ -21332,6 +21332,10 @@
"format": "int64",
"x-go-name": "ID"
},
"job_id": {
"type": "string",
"x-go-name": "JobID"
},
"labels": {
"type": "array",
"items": {
@ -21343,6 +21347,13 @@
"type": "string",
"x-go-name": "Name"
},
"needs": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "Needs"
},
"run_attempt": {
"type": "integer",
"format": "int64",

View File

@ -8,6 +8,7 @@ import {renderAnsi} from '../render/ansi.ts';
import {POST, DELETE} from '../modules/fetch.ts';
import type {IntervalId} from '../types.ts';
import {toggleFullScreen} from '../utils.ts';
import WorkflowGraph from './WorkflowGraph.vue'
// see "models/actions/status.go", if it needs to be used somewhere else, move it to a shared file like "types/actions.ts"
type RunStatus = 'unknown' | 'waiting' | 'running' | 'success' | 'failure' | 'cancelled' | 'skipped' | 'blocked';
@ -28,9 +29,11 @@ type LogLineCommand = {
type Job = {
id: number;
job_id: string;
name: string;
status: RunStatus;
canRerun: boolean;
needs?: string[];
duration: string;
}
@ -85,6 +88,7 @@ export default defineComponent({
components: {
SvgIcon,
ActionRunStatus,
WorkflowGraph
},
props: {
runIndex: {
@ -115,6 +119,7 @@ export default defineComponent({
artifacts: [] as Array<Record<string, any>>,
menuVisible: false,
isFullScreen: false,
showSummary: true,
timeVisible: {
'log-time-stamp': false,
'log-time-seconds': false,
@ -512,6 +517,16 @@ export default defineComponent({
</div>
<div class="action-view-body">
<div class="action-view-left">
<div class="summary-toggle">
<button
class="ui basic small button"
@click="showSummary = !showSummary"
:class="{ active: showSummary }"
>
<SvgIcon :name="showSummary ? 'octicon-chevron-down' : 'octicon-chevron-right'"/>
Summary
</button>
</div>
<div class="job-group-section">
<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">
@ -554,7 +569,16 @@ export default defineComponent({
</div>
<div class="action-view-right">
<div class="job-info-header">
<WorkflowGraph
v-if="showSummary && run.jobs.length > 1"
:jobs="run.jobs"
:current-job-id="parseInt(jobIndex)"
class="workflow-graph-container"
/>
<div
class="job-info-header"
>
<div class="job-info-header-left gt-ellipsis">
<h3 class="job-info-header-title gt-ellipsis">
{{ currentJob.title }}
@ -602,7 +626,11 @@ export default defineComponent({
</div>
</div>
<!-- always create the node because we have our own event listeners on it, don't use "v-if" -->
<div class="job-step-container" ref="stepsContainer" v-show="currentJob.steps.length">
<div
class="job-step-container"
ref="stepsContainer"
v-show="currentJob.steps.length"
>
<div class="job-step-section" v-for="(jobStep, i) in currentJob.steps" :key="i">
<div class="job-step-summary" @click.stop="isExpandable(jobStep.status) && toggleStepLogs(i)" :class="[currentJobStepsStates[i].expanded ? 'selected' : '', isExpandable(jobStep.status) && 'step-expandable']">
<!-- If the job is done and the job step log is loaded for the first time, show the loading icon
@ -660,6 +688,34 @@ export default defineComponent({
overflow-wrap: anywhere;
}
.summary-toggle {
margin: 16px 0 8px;
padding-bottom: 12px;
border-bottom: 1px solid var(--color-secondary);
}
.summary-toggle .ui.button {
padding: 6px 12px;
border: 1px solid var(--color-secondary);
border-radius: 6px;
background: transparent;
color: var(--color-text);
display: flex;
align-items: center;
gap: 6px;
}
.summary-toggle .ui.button:hover {
background: var(--color-hover);
border-color: var(--color-secondary);
}
.summary-toggle .ui.button.active {
background: var(--color-secondary-alpha-10);
border-color: var(--color-primary);
color: var(--color-primary);
}
.action-info-summary .ui.button {
margin: 0;
white-space: nowrap;
@ -780,14 +836,14 @@ export default defineComponent({
.action-view-right {
flex: 1;
color: var(--color-console-fg-subtle);
color: var(--color-text);
max-height: 100%;
width: 70%;
display: flex;
flex-direction: column;
border: 1px solid var(--color-console-border);
border: 1px solid var(--color-secondary);
border-radius: var(--border-radius);
background: var(--color-console-bg);
background: var(--color-body);
align-self: flex-start;
}
@ -796,17 +852,17 @@ export default defineComponent({
.action-view-right .ui.button,
.action-view-right .ui.button:focus {
background: transparent;
color: var(--color-console-fg-subtle);
color: var(--color-text);
}
.action-view-right .ui.button:hover {
background: var(--color-console-hover-bg);
color: var(--color-console-fg);
background: var(--color-hover);
color: var(--color-text);
}
.action-view-right .ui.button:active {
background: var(--color-console-active-bg);
color: var(--color-console-fg);
background: var(--color-active);
color: var(--color-text);
}
/* end fomantic button overrides */
@ -814,31 +870,31 @@ export default defineComponent({
/* begin fomantic dropdown menu overrides */
.action-view-right .ui.dropdown .menu {
background: var(--color-console-menu-bg);
border-color: var(--color-console-menu-border);
background: var(--color-menu);
border-color: var(--color-secondary);
}
.action-view-right .ui.dropdown .menu > .item {
color: var(--color-console-fg);
color: var(--color-text);
}
.action-view-right .ui.dropdown .menu > .item:hover {
color: var(--color-console-fg);
background: var(--color-console-hover-bg);
color: var(--color-text);
background: var(--color-hover);
}
.action-view-right .ui.dropdown .menu > .item:active {
color: var(--color-console-fg);
background: var(--color-console-active-bg);
color: var(--color-text);
background: var(--color-active);
}
.action-view-right .ui.dropdown .menu > .divider {
border-top-color: var(--color-console-menu-border);
border-top-color: var(--color-secondary-alpha-30);
}
.action-view-right .ui.pointing.dropdown > .menu:not(.hidden)::after {
background: var(--color-console-menu-bg);
box-shadow: -1px -1px 0 0 var(--color-console-menu-border);
background: var(--color-menu);
box-shadow: -1px -1px 0 0 var(--color-secondary);
}
/* end fomantic dropdown menu overrides */
@ -852,7 +908,7 @@ export default defineComponent({
top: 0;
height: 60px;
z-index: 1; /* above .job-step-container */
background: var(--color-console-bg);
background: var(--color-body);
border-radius: 3px;
}
@ -861,13 +917,13 @@ export default defineComponent({
}
.job-info-header .job-info-header-title {
color: var(--color-console-fg);
color: var(--color-text);
font-size: 16px;
margin: 0;
}
.job-info-header .job-info-header-detail {
color: var(--color-console-fg-subtle);
color: var(--color-text);
font-size: 12px;
}
@ -878,7 +934,7 @@ export default defineComponent({
.job-step-container {
max-height: 100%;
border-radius: 0 0 var(--border-radius) var(--border-radius);
border-top: 1px solid var(--color-console-border);
border-top: 1px solid var(--color-secondary);
z-index: 0;
}
@ -894,8 +950,8 @@ export default defineComponent({
}
.job-step-container .job-step-summary.step-expandable:hover {
color: var(--color-console-fg);
background: var(--color-console-hover-bg);
color: var(--color-text);
background: var(--color-hover);
}
.job-step-container .job-step-summary .step-summary-msg {
@ -907,8 +963,8 @@ export default defineComponent({
}
.job-step-container .job-step-summary.selected {
color: var(--color-console-fg);
background-color: var(--color-console-active-bg);
color: var(--color-text);
background-color: var(--color-active);
position: sticky;
top: 60px;
}
@ -944,7 +1000,7 @@ export default defineComponent({
.job-log-line:hover,
.job-log-line:target {
background-color: var(--color-console-hover-bg);
background-color: var(--color-hover);
}
.job-log-line:target {

File diff suppressed because it is too large Load Diff