Skip to content

Commit

Permalink
fix(pipeline): Handle render/validation when stageTimeoutMs is a Spel…
Browse files Browse the repository at this point in the history
… expression (#10103)
  • Loading branch information
christosarvanitis committed May 10, 2024
1 parent 9374f06 commit 9237f78
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 5 deletions.
@@ -1,4 +1,4 @@
import { get } from 'lodash';
import { get, isNumber } from 'lodash';
import { Duration } from 'luxon';
import React from 'react';

Expand All @@ -10,7 +10,7 @@ const { useEffect, useState } = React;

export interface IOverrideTimeoutConfigProps {
stageConfig: IStageConfig;
stageTimeoutMs: number;
stageTimeoutMs: number | any;
updateStageField: (changes: Partial<IStage>) => void;
}

Expand Down Expand Up @@ -41,8 +41,13 @@ export const OverrideTimeout = (props: IOverrideTimeoutConfigProps) => {
}, [props.stageTimeoutMs]);

const stageChanged = () => {
if (props.stageTimeoutMs !== undefined) {
if (props.stageTimeoutMs !== undefined && !isExpression) {
enableTimeout();
} else if (props.stageTimeoutMs !== undefined && isExpression) {
setOverrideTimeout(true);
props.updateStageField({
stageTimeoutMs: props.stageTimeoutMs || null,
});
} else {
clearTimeout();
}
Expand Down Expand Up @@ -74,6 +79,10 @@ export const OverrideTimeout = (props: IOverrideTimeoutConfigProps) => {
};

const isConfigurable = !!get(props.stageConfig, 'supportsCustomTimeout');
const isExpression =
props.stageTimeoutMs !== undefined && props.stageTimeoutMs !== null && !isNumber(props.stageTimeoutMs)
? props.stageTimeoutMs.includes('${')
: false;

if (isConfigurable) {
return (
Expand All @@ -94,7 +103,7 @@ export const OverrideTimeout = (props: IOverrideTimeoutConfigProps) => {
</div>
</div>
</div>
{overrideTimeout && (
{overrideTimeout && !isExpression && (
<div>
<div className="form-group form-inline">
<div className="col-md-9 col-md-offset-1 checkbox-padding">
Expand Down Expand Up @@ -123,6 +132,17 @@ export const OverrideTimeout = (props: IOverrideTimeoutConfigProps) => {
</div>
</div>
)}
{overrideTimeout && isExpression && (
<div className="form-group">
<div className="col-md-9 col-md-offset-1">
<div className="sm-control-field">
<span>
Resolved at runtime from expression: <code>{props.stageTimeoutMs}</code>
</span>
</div>
</div>
</div>
)}
</>
);
} else {
Expand Down
Expand Up @@ -54,6 +54,10 @@ export interface ICustomValidator extends IStageOrTriggerValidator, IValidatorCo
[k: string]: any;
}

function isNumberOrSpel(valInput: any) {
return (isNumber(valInput) && valInput > 0) || (typeof valInput === 'string' && valInput.includes('${'));
}

export class PipelineConfigValidator {
private static validators: Map<string, IStageOrTriggerValidator> = new Map();
private static validationStream: Subject<IPipelineValidationResults> = new Subject();
Expand Down Expand Up @@ -151,7 +155,7 @@ export class PipelineConfigValidator {
);
}

if (stage.stageTimeoutMs !== undefined && !(isNumber(stage.stageTimeoutMs) && stage.stageTimeoutMs > 0)) {
if (stage.stageTimeoutMs !== undefined && !isNumberOrSpel(stage.stageTimeoutMs)) {
stageValidations.set(stage, [
...(stageValidations.get(stage) || []),
'Stage is configured to fail after a specific amount of time, but no time is set.',
Expand Down

0 comments on commit 9237f78

Please sign in to comment.