mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-20 14:48:30 +02:00
Merge 4350e0d51ee2b325044a454dd8b5a2cd6cfe3408 into 6599efb3b1400ac06d06e1c8b68ae6037fbb7952
This commit is contained in:
commit
05a31f9fa4
@ -186,6 +186,9 @@ func AggregateJobStatus(jobs []*ActionRunJob) Status {
|
||||
case hasCancelled:
|
||||
return StatusCancelled
|
||||
case hasRunning:
|
||||
if hasFailure {
|
||||
return StatusRunningWithFailure
|
||||
}
|
||||
return StatusRunning
|
||||
case hasFailure:
|
||||
return StatusFailure
|
||||
|
@ -65,7 +65,7 @@ func TestAggregateJobStatus(t *testing.T) {
|
||||
{[]Status{StatusFailure, StatusSkipped}, StatusFailure},
|
||||
{[]Status{StatusFailure, StatusCancelled}, StatusCancelled},
|
||||
{[]Status{StatusFailure, StatusWaiting}, StatusFailure},
|
||||
{[]Status{StatusFailure, StatusRunning}, StatusRunning},
|
||||
{[]Status{StatusFailure, StatusRunning}, StatusRunningWithFailure},
|
||||
{[]Status{StatusFailure, StatusBlocked}, StatusFailure},
|
||||
|
||||
// skipped with other status
|
||||
|
@ -15,25 +15,27 @@ import (
|
||||
type Status int
|
||||
|
||||
const (
|
||||
StatusUnknown Status = iota // 0, consistent with runnerv1.Result_RESULT_UNSPECIFIED
|
||||
StatusSuccess // 1, consistent with runnerv1.Result_RESULT_SUCCESS
|
||||
StatusFailure // 2, consistent with runnerv1.Result_RESULT_FAILURE
|
||||
StatusCancelled // 3, consistent with runnerv1.Result_RESULT_CANCELLED
|
||||
StatusSkipped // 4, consistent with runnerv1.Result_RESULT_SKIPPED
|
||||
StatusWaiting // 5, isn't a runnerv1.Result
|
||||
StatusRunning // 6, isn't a runnerv1.Result
|
||||
StatusBlocked // 7, isn't a runnerv1.Result
|
||||
StatusUnknown Status = iota // 0, consistent with runnerv1.Result_RESULT_UNSPECIFIED
|
||||
StatusSuccess // 1, consistent with runnerv1.Result_RESULT_SUCCESS
|
||||
StatusFailure // 2, consistent with runnerv1.Result_RESULT_FAILURE
|
||||
StatusCancelled // 3, consistent with runnerv1.Result_RESULT_CANCELLED
|
||||
StatusSkipped // 4, consistent with runnerv1.Result_RESULT_SKIPPED
|
||||
StatusWaiting // 5, isn't a runnerv1.Result
|
||||
StatusRunning // 6, isn't a runnerv1.Result
|
||||
StatusBlocked // 7, isn't a runnerv1.Result
|
||||
StatusRunningWithFailure // 8, isn't a runnerv1.Result, used for aggregated status
|
||||
)
|
||||
|
||||
var statusNames = map[Status]string{
|
||||
StatusUnknown: "unknown",
|
||||
StatusWaiting: "waiting",
|
||||
StatusRunning: "running",
|
||||
StatusSuccess: "success",
|
||||
StatusFailure: "failure",
|
||||
StatusCancelled: "cancelled",
|
||||
StatusSkipped: "skipped",
|
||||
StatusBlocked: "blocked",
|
||||
StatusUnknown: "unknown",
|
||||
StatusWaiting: "waiting",
|
||||
StatusRunning: "running",
|
||||
StatusSuccess: "success",
|
||||
StatusFailure: "failure",
|
||||
StatusCancelled: "cancelled",
|
||||
StatusSkipped: "skipped",
|
||||
StatusBlocked: "blocked",
|
||||
StatusRunningWithFailure: "running_with_failure",
|
||||
}
|
||||
|
||||
// String returns the string name of the Status
|
||||
@ -88,6 +90,10 @@ func (s Status) IsBlocked() bool {
|
||||
return s == StatusBlocked
|
||||
}
|
||||
|
||||
func (s Status) IsRunningWithFailure() bool {
|
||||
return s == StatusRunningWithFailure
|
||||
}
|
||||
|
||||
// In returns whether s is one of the given statuses
|
||||
func (s Status) In(statuses ...Status) bool {
|
||||
return slices.Contains(statuses, s)
|
||||
|
@ -20,6 +20,8 @@ const (
|
||||
CommitStatusWarning CommitStatusState = "warning"
|
||||
// CommitStatusSkipped is for when CommitStatus is Skipped
|
||||
CommitStatusSkipped CommitStatusState = "skipped"
|
||||
// CommitStatusRunningWithFailure is for only aggregated commit status
|
||||
CommitStatusRunningWithFailure CommitStatusState = "running_with_failure"
|
||||
)
|
||||
|
||||
func (css CommitStatusState) String() string {
|
||||
@ -56,20 +58,28 @@ func (css CommitStatusState) IsSkipped() bool {
|
||||
return css == CommitStatusSkipped
|
||||
}
|
||||
|
||||
// IsRunningWithFailure represents if commit status state is running with failure
|
||||
func (css CommitStatusState) IsRunningWithFailure() bool {
|
||||
return css == CommitStatusRunningWithFailure
|
||||
}
|
||||
|
||||
type CommitStatusStates []CommitStatusState //nolint:revive // export stutter
|
||||
|
||||
// According to https://docs.github.com/en/rest/commits/statuses?apiVersion=2022-11-28#get-the-combined-status-for-a-specific-reference
|
||||
// > Additionally, a combined state is returned. The state is one of:
|
||||
// > failure if any of the contexts report as error or failure
|
||||
// > pending if there are no statuses or a context is pending
|
||||
// > failure if any of the contexts report as error or failure and no contexts are pending
|
||||
// > pending if there are no statuses or a context is pending with no failure
|
||||
// > running_with_failure if there are contexts that are pending and at least one context is failure
|
||||
// > success if the latest status for all contexts is success
|
||||
func (css CommitStatusStates) Combine() CommitStatusState {
|
||||
successCnt := 0
|
||||
hasRunning, hasFailure := false, false
|
||||
for _, state := range css {
|
||||
switch {
|
||||
case state.IsError() || state.IsFailure():
|
||||
return CommitStatusFailure
|
||||
hasFailure = true
|
||||
case state.IsPending():
|
||||
hasRunning = true
|
||||
case state.IsSuccess() || state.IsWarning() || state.IsSkipped():
|
||||
successCnt++
|
||||
}
|
||||
@ -77,5 +87,11 @@ func (css CommitStatusStates) Combine() CommitStatusState {
|
||||
if successCnt > 0 && successCnt == len(css) {
|
||||
return CommitStatusSuccess
|
||||
}
|
||||
if hasFailure {
|
||||
if hasRunning {
|
||||
return CommitStatusRunningWithFailure
|
||||
}
|
||||
return CommitStatusFailure
|
||||
}
|
||||
return CommitStatusPending
|
||||
}
|
||||
|
@ -3789,6 +3789,7 @@ status.failure = "Failure"
|
||||
status.cancelled = "Canceled"
|
||||
status.skipped = "Skipped"
|
||||
status.blocked = "Blocked"
|
||||
status.running_with_failure = "Running with failure"
|
||||
|
||||
runners = Runners
|
||||
runners.runner_manage_panel = Runners Management
|
||||
|
10
public/assets/img/svg/gitea-running-with-failure.svg
generated
Normal file
10
public/assets/img/svg/gitea-running-with-failure.svg
generated
Normal file
@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<!-- Orange dot -->
|
||||
<circle cx="7" cy="8" r="5" fill="#f1c40f"/>
|
||||
|
||||
<!-- Red X (two crossing rectangles) -->
|
||||
<g transform="translate(6, 5)" fill="#e74c3c">
|
||||
<rect x="0" y="2" width="8" height="2" transform="rotate(45 4 3)"/>
|
||||
<rect x="0" y="2" width="8" height="2" transform="rotate(-45 4 3)"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 404 B |
@ -17,6 +17,8 @@
|
||||
{{svg "octicon-blocked" $size (printf "text yellow %s" $className)}}
|
||||
{{else if eq .status "running"}}
|
||||
{{svg "octicon-meter" $size (printf "text yellow circular-spin %s" $className)}}
|
||||
{{else if eq .status "running_with_failure"}}
|
||||
{{svg "gitea-running-with-failure" $size (printf "text yellow circular-spin %s" $className)}}
|
||||
{{else}}{{/*failure, unknown*/}}
|
||||
{{svg "octicon-x-circle-fill" $size (printf "text red %s" $className)}}
|
||||
{{end}}
|
||||
|
@ -18,6 +18,7 @@
|
||||
data-locale-status-cancelled="{{ctx.Locale.Tr "actions.status.cancelled"}}"
|
||||
data-locale-status-skipped="{{ctx.Locale.Tr "actions.status.skipped"}}"
|
||||
data-locale-status-blocked="{{ctx.Locale.Tr "actions.status.blocked"}}"
|
||||
data-locale-status-running-with-failure="{{ctx.Locale.Tr "actions.status.running_with_failure"}}"
|
||||
data-locale-artifacts-title="{{ctx.Locale.Tr "artifacts"}}"
|
||||
data-locale-artifact-expired="{{ctx.Locale.Tr "expired"}}"
|
||||
data-locale-confirm-delete-artifact="{{ctx.Locale.Tr "confirm_delete_artifact"}}"
|
||||
|
@ -17,3 +17,6 @@
|
||||
{{if eq .State "skipped"}}
|
||||
{{svg "octicon-skip" 18 "commit-status icon text grey"}}
|
||||
{{end}}
|
||||
{{if eq .State "running_with_failure"}}
|
||||
{{svg "gitea-running-with-failure" 18 "commit-status icon text red"}}
|
||||
{{end}}
|
||||
|
@ -1,12 +1,12 @@
|
||||
<!-- This vue should be kept the same as templates/repo/actions/status.tmpl
|
||||
Please also update the template file above if this vue is modified.
|
||||
action status accepted: success, skipped, waiting, blocked, running, failure, cancelled, unknown
|
||||
action status accepted: success, skipped, waiting, blocked, running, running_with_failure, failure, cancelled, unknown
|
||||
-->
|
||||
<script lang="ts" setup>
|
||||
import {SvgIcon} from '../svg.ts';
|
||||
|
||||
withDefaults(defineProps<{
|
||||
status: 'success' | 'skipped' | 'waiting' | 'blocked' | 'running' | 'failure' | 'cancelled' | 'unknown',
|
||||
status: 'success' | 'skipped' | 'waiting' | 'blocked' | 'running' | 'running_with_failure' | 'failure' | 'cancelled' | 'unknown',
|
||||
size?: number,
|
||||
className?: string,
|
||||
localeStatus?: string,
|
||||
@ -25,6 +25,7 @@ withDefaults(defineProps<{
|
||||
<SvgIcon name="octicon-clock" class="text yellow" :size="size" :class="className" v-else-if="status === 'waiting'"/>
|
||||
<SvgIcon name="octicon-blocked" class="text yellow" :size="size" :class="className" v-else-if="status === 'blocked'"/>
|
||||
<SvgIcon name="octicon-meter" class="text yellow" :size="size" :class="'circular-spin ' + className" v-else-if="status === 'running'"/>
|
||||
<SvgIcon name="gitea-running-with-failure" class="text yellow" :size="size" :class="'circular-spin ' + className" v-else-if="status === 'running_with_failure'"/>
|
||||
<SvgIcon name="octicon-x-circle-fill" class="text red" :size="size" v-else/><!-- failure, unknown -->
|
||||
</span>
|
||||
</template>
|
||||
|
@ -39,6 +39,7 @@ export function initRepositoryActionView() {
|
||||
cancelled: el.getAttribute('data-locale-status-cancelled'),
|
||||
skipped: el.getAttribute('data-locale-status-skipped'),
|
||||
blocked: el.getAttribute('data-locale-status-blocked'),
|
||||
running_with_failure: el.getAttribute('data-locale-status-running-with-failure'),
|
||||
},
|
||||
logsAlwaysAutoScroll: el.getAttribute('data-locale-logs-always-auto-scroll'),
|
||||
logsAlwaysExpandRunning: el.getAttribute('data-locale-logs-always-expand-running'),
|
||||
|
@ -78,12 +78,14 @@ import octiconTrash from '../../public/assets/img/svg/octicon-trash.svg';
|
||||
import octiconTriangleDown from '../../public/assets/img/svg/octicon-triangle-down.svg';
|
||||
import octiconX from '../../public/assets/img/svg/octicon-x.svg';
|
||||
import octiconXCircleFill from '../../public/assets/img/svg/octicon-x-circle-fill.svg';
|
||||
import giteaRunningWithFailure from '../../public/assets/img/svg/gitea-running-with-failure.svg';
|
||||
|
||||
const svgs = {
|
||||
'gitea-double-chevron-left': giteaDoubleChevronLeft,
|
||||
'gitea-double-chevron-right': giteaDoubleChevronRight,
|
||||
'gitea-empty-checkbox': giteaEmptyCheckbox,
|
||||
'gitea-exclamation': giteaExclamation,
|
||||
'gitea-running-with-failure': giteaRunningWithFailure,
|
||||
'octicon-archive': octiconArchive,
|
||||
'octicon-arrow-switch': octiconArrowSwitch,
|
||||
'octicon-blocked': octiconBlocked,
|
||||
|
Loading…
x
Reference in New Issue
Block a user