0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-02-21 11:28:12 +01:00

Merge 45d3e146fff85e5fdfd9f5764f481b01bb37f31f into 3830d488d5570ee91e47e496c08218ba2edbce4d

This commit is contained in:
Semenets V. Pavel 2026-02-20 20:45:20 +03:00 committed by GitHub
commit 7a444e2613
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 1431 additions and 27 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

@ -3694,6 +3694,7 @@
"actions.runs.delete.description": "Are you sure you want to permanently delete this workflow run? This action cannot be undone.",
"actions.runs.not_done": "This workflow run is not done.",
"actions.runs.view_workflow_file": "View workflow file",
"actions.runs.dependency_graph": "Dependency Graph",
"actions.workflow.disable": "Disable Workflow",
"actions.workflow.disable_success": "Workflow '%s' disabled successfully.",
"actions.workflow.enable": "Enable Workflow",

View File

@ -143,11 +143,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 {
@ -248,10 +250,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

@ -376,7 +376,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),
@ -392,6 +393,7 @@ func ToActionWorkflowJob(ctx context.Context, repo *repo_model.Repository, task
Conclusion: conclusion,
RunnerID: runnerID,
RunnerName: runnerName,
Needs: job.Needs,
Steps: util.SliceNilAsEmpty(steps),
CreatedAt: job.Created.AsTime().UTC(),
StartedAt: job.Started.AsTime().UTC(),

View File

@ -10,6 +10,7 @@
data-locale-runs-scheduled="{{ctx.Locale.Tr "actions.runs.scheduled"}}"
data-locale-runs-commit="{{ctx.Locale.Tr "actions.runs.commit"}}"
data-locale-runs-pushed-by="{{ctx.Locale.Tr "actions.runs.pushed_by"}}"
data-locale-runs-dependency-graph="{{ctx.Locale.Tr "actions.runs.dependency_graph"}}"
data-locale-status-unknown="{{ctx.Locale.Tr "actions.status.unknown"}}"
data-locale-status-waiting="{{ctx.Locale.Tr "actions.status.waiting"}}"
data-locale-status-running="{{ctx.Locale.Tr "actions.status.running"}}"

View File

@ -21432,6 +21432,10 @@
"format": "int64",
"x-go-name": "ID"
},
"job_id": {
"type": "string",
"x-go-name": "JobID"
},
"labels": {
"type": "array",
"items": {
@ -21443,6 +21447,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

@ -66,14 +66,14 @@ gitea-theme-meta-info {
--color-secondary-hover: var(--color-secondary-dark-5);
--color-secondary-active: var(--color-secondary-dark-6);
/* console colors - used for actions console and console files */
--color-console-fg: #f7f8f9;
--color-console-fg-subtle: #bdc4cc;
--color-console-bg: #171b1e;
--color-console-border: #2e353b;
--color-console-hover-bg: #272d33;
--color-console-active-bg: #2e353b;
--color-console-menu-bg: #262b31;
--color-console-menu-border: #414b55;
--color-console-fg: #0d1117;
--color-console-fg-subtle: #40474d;
--color-console-bg: #ffffff;
--color-console-border: #d0d7de;
--color-console-hover-bg: #f1f3f5;
--color-console-active-bg: #d0d7de;
--color-console-menu-bg: #f8f9fb;
--color-console-menu-border: #d0d7de;
/* named colors */
--color-red: #db2828;
--color-orange: #f2711c;

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'
import {localUserSettings} from '../modules/user-settings.ts';
// see "models/actions/status.go", if it needs to be used somewhere else, move it to a shared file like "types/actions.ts"
@ -57,9 +58,11 @@ const LogLinePrefixCommandMap: Record<string, LogLineCommandName> = {
type Job = {
id: number;
job_id: string;
name: string;
status: RunStatus;
canRerun: boolean;
needs?: string[];
duration: string;
}
@ -107,6 +110,7 @@ function isLogElementInViewport(el: Element, {extraViewPortHeight}={extraViewPor
type LocaleStorageOptions = {
autoScroll: boolean;
expandRunning: boolean;
showSummary: boolean;
actionsLogShowSeconds: boolean;
actionsLogShowTimestamps: boolean;
};
@ -116,6 +120,7 @@ export default defineComponent({
components: {
SvgIcon,
ActionRunStatus,
WorkflowGraph
},
props: {
runIndex: {
@ -137,8 +142,8 @@ export default defineComponent({
},
data() {
const defaultViewOptions: LocaleStorageOptions = {autoScroll: true, expandRunning: false, actionsLogShowSeconds: false, actionsLogShowTimestamps: false};
const {autoScroll, expandRunning, actionsLogShowSeconds, actionsLogShowTimestamps} = localUserSettings.getJsonObject('actions-view-options', defaultViewOptions);
const defaultViewOptions: LocaleStorageOptions = {autoScroll: true, expandRunning: false, showSummary: false, actionsLogShowSeconds: false, actionsLogShowTimestamps: false};
const {autoScroll, expandRunning, showSummary, actionsLogShowSeconds, actionsLogShowTimestamps} = localUserSettings.getJsonObject('actions-view-options', defaultViewOptions);
return {
// internal state
loadingAbortController: null as AbortController | null,
@ -147,6 +152,7 @@ export default defineComponent({
artifacts: [] as Array<Record<string, any>>,
menuVisible: false,
isFullScreen: false,
showSummary: showSummary ?? false,
timeVisible: {
'log-time-stamp': actionsLogShowTimestamps,
'log-time-seconds': actionsLogShowSeconds,
@ -214,6 +220,9 @@ export default defineComponent({
optionAlwaysExpandRunning() {
this.saveLocaleStorageOptions();
},
showSummary() {
this.saveLocaleStorageOptions();
},
},
async mounted() {
@ -258,6 +267,7 @@ export default defineComponent({
const opts: LocaleStorageOptions = {
autoScroll: this.optionAlwaysAutoScroll,
expandRunning: this.optionAlwaysExpandRunning,
showSummary: this.showSummary,
actionsLogShowSeconds: this.timeVisible['log-time-seconds'],
actionsLogShowTimestamps: this.timeVisible['log-time-stamp'],
};
@ -514,15 +524,20 @@ export default defineComponent({
<!-- eslint-disable-next-line vue/no-v-html -->
<h2 class="action-info-summary-title-text" v-html="run.titleHTML"/>
</div>
<button class="ui basic small compact button primary" @click="approveRun()" v-if="run.canApprove">
{{ locale.approve }}
</button>
<button class="ui basic small compact button red" @click="cancelRun()" v-else-if="run.canCancel">
{{ locale.cancel }}
</button>
<button class="ui basic small compact button link-action tw-shrink-0" :data-url="`${run.link}/rerun`" v-else-if="run.canRerun">
{{ locale.rerun_all }}
</button>
<div class="tw-flex tw-space-x-2">
<button class="ui basic small compact button primary tw-shrink-0" @click="showSummary = !showSummary" :class="{ active: showSummary }" v-if="run.jobs.length > 1">
{{ locale.dependencyGraph }}
</button>
<button class="ui basic small compact button primary" @click="approveRun()" v-if="run.canApprove">
{{ locale.approve }}
</button>
<button class="ui basic small compact button red" @click="cancelRun()" v-else-if="run.canCancel">
{{ locale.cancel }}
</button>
<button class="ui basic small compact button link-action tw-shrink-0" :data-url="`${run.link}/rerun`" v-else-if="run.canRerun">
{{ locale.rerun_all }}
</button>
</div>
</div>
<div class="action-commit-summary">
<span><a class="muted" :href="run.workflowLink"><b>{{ run.workflowID }}</b></a>:</span>
@ -585,7 +600,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-idx="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 }}
@ -633,7 +657,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
@ -691,6 +719,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;

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,7 @@ export function initRepositoryActionView() {
scheduled: el.getAttribute('data-locale-runs-scheduled'),
commit: el.getAttribute('data-locale-runs-commit'),
pushedBy: el.getAttribute('data-locale-runs-pushed-by'),
dependencyGraph: el.getAttribute('data-locale-runs-dependency-graph'),
artifactsTitle: el.getAttribute('data-locale-artifacts-title'),
areYouSure: el.getAttribute('data-locale-are-you-sure'),
artifactExpired: el.getAttribute('data-locale-artifact-expired'),