Introduce V1 schema

This commit is contained in:
Vardan Bansal 2023-09-13 14:49:41 -07:00
parent 7f2b179711
commit 2c71ca207b
4 changed files with 697 additions and 75 deletions

View File

@ -207,7 +207,7 @@ export const PluginsPanel = ({ version = YamlVersion.V0, onPluginAddUpdate }: Pl
case PluginCategory.Harness:
constructedPayload =
version === YamlVersion.V1
? { type: 'script', spec: constructedPayload }
? { type: 'script', spec: { run: get(constructedPayload, 'script', '') } }
: { name: 'run step', commands: [get(constructedPayload, 'script', '')] }
}
onPluginAddUpdate?.(isUpdate, constructedPayload)

View File

@ -31,27 +31,33 @@ import { getErrorMessage } from 'utils/Utils'
import { decodeGitContent } from 'utils/GitUtils'
import pipelineSchemaV1 from './schema/pipeline-schema-v1.json'
import pipelineSchemaV0 from './schema/pipeline-schema-v0.json'
import { YamlVersion } from './Constants'
import { DRONE_CONFIG_YAML_FILE_SUFFIXES, YamlVersion } from './Constants'
import css from './AddUpdatePipeline.module.scss'
const StarterPipelineV1: Record<string, any> = {
version: 1,
stages: [
{
type: 'ci',
spec: {
steps: [
{
type: 'script',
spec: {
run: 'echo hello world'
kind: 'pipeline',
spec: {
stages: [
{
name: 'build',
type: 'ci',
spec: {
steps: [
{
name: 'build',
type: 'script',
spec: {
image: 'golang',
run: 'echo "hello world"'
}
}
}
]
]
}
}
}
]
]
}
}
const StarterPipelineV0: Record<string, any> = {
@ -79,15 +85,13 @@ interface PipelineSaveAndRunOption {
}
const AddUpdatePipeline = (): JSX.Element => {
const version = YamlVersion.V0
const { routes } = useAppContext()
const { getString } = useStrings()
const { pipeline } = useParams<CODEProps>()
const { repoMetadata } = useGetRepositoryMetadata()
const { showError, showSuccess, clear: clearToaster } = useToaster()
const [pipelineAsObj, setPipelineAsObj] = useState<Record<string, any>>(
version === YamlVersion.V0 ? StarterPipelineV0 : StarterPipelineV1
)
const [yamlVersion, setYAMLVersion] = useState<YamlVersion>()
const [pipelineAsObj, setPipelineAsObj] = useState<Record<string, any>>({})
const [pipelineAsYAML, setPipelineAsYaml] = useState<string>('')
const { openModal: openRunPipelineModal } = useRunPipelineModal()
const repoPath = useMemo(() => repoMetadata?.path || '', [repoMetadata])
@ -139,6 +143,15 @@ const AddUpdatePipeline = (): JSX.Element => {
[pipelineYAMLFileContent?.content]
)
// set YAML version for Pipeline setup
useEffect(() => {
setYAMLVersion(
DRONE_CONFIG_YAML_FILE_SUFFIXES.map((suffix: string) => pipelineData?.config_path?.endsWith(suffix))
? YamlVersion.V0
: YamlVersion.V1
)
}, [pipelineData])
// check if file already exists and has some content
useEffect(() => {
setIsExistingPipeline(!isEmpty(originalPipelineYAMLFileContent) && !isUndefined(originalPipelineYAMLFileContent))
@ -151,12 +164,12 @@ const AddUpdatePipeline = (): JSX.Element => {
} else {
// load with starter pipeline
try {
setPipelineAsYaml(stringify(pipelineAsObj))
setPipelineAsYaml(stringify(yamlVersion === YamlVersion.V1 ? StarterPipelineV1 : StarterPipelineV0))
} catch (ex) {
// ignore exception
}
}
}, [isExistingPipeline, originalPipelineYAMLFileContent, pipelineAsObj])
}, [yamlVersion, isExistingPipeline, originalPipelineYAMLFileContent, pipelineAsObj])
// find if editor content was modified
useEffect(() => {
@ -206,7 +219,7 @@ const AddUpdatePipeline = (): JSX.Element => {
const updatePipeline = (payload: Record<string, any>): Record<string, any> => {
const pipelineAsObjClone = { ...pipelineAsObj }
const stepInsertPath = version === YamlVersion.V0 ? 'steps' : 'stages.0.spec.steps'
const stepInsertPath = yamlVersion === YamlVersion.V1 ? 'spec.stages.0.spec.steps' : 'steps'
let existingSteps: [unknown] = get(pipelineAsObjClone, stepInsertPath, [])
if (existingSteps.length > 0) {
existingSteps.push(payload)
@ -309,13 +322,13 @@ const AddUpdatePipeline = (): JSX.Element => {
<Container className={css.editorContainer}>
<MonacoSourceCodeEditor
language={'yaml'}
schema={version === YamlVersion.V0 ? pipelineSchemaV0 : pipelineSchemaV1}
schema={yamlVersion === YamlVersion.V1 ? pipelineSchemaV1 : pipelineSchemaV0}
source={pipelineAsYAML}
onChange={(value: string) => setPipelineAsYaml(value)}
/>
</Container>
<Container className={css.pluginsContainer}>
<PluginsPanel onPluginAddUpdate={addUpdatePluginToPipelineYAML} />
<PluginsPanel onPluginAddUpdate={addUpdatePluginToPipelineYAML} version={yamlVersion} />
</Container>
</Layout.Horizontal>
</PageBody>

View File

@ -5,3 +5,5 @@ export enum YamlVersion {
export const DEFAULT_YAML_PATH_PREFIX = '.harness/'
export const DEFAULT_YAML_PATH_SUFFIX = '.yaml'
export const DRONE_CONFIG_YAML_FILE_SUFFIXES = ['.drone.yml', '.drone.yaml']

View File

@ -1,18 +1,142 @@
{
"definitions": {
"Pipeline": {
"title": "Pipeline",
"description": "Pipeline defines the pipeline execution.",
"Config": {
"title": "Config",
"description": "Config defines the a resource configuration.",
"type": "object",
"properties": {
"version": {
"description": "Version defines the schema version.",
"type": ["string", "number"]
},
"name": {
"description": "Pipeline provides the pipeline name.",
"type": "string"
"kind": {
"type": "string",
"description": "Type defines the schema type.",
"enum": ["pipeline", "plugin", "template"]
},
"type": {
"type": "string",
"description": "Type defines the schema type.",
"enum": ["pipeline", "stage", "step"]
},
"name": {
"type": "string",
"description": "Name defines an optional resource name."
}
},
"required": ["kind"],
"oneOf": [
{
"allOf": [
{
"properties": {
"kind": {
"const": "pipeline"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/Pipeline"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"kind": {
"const": "template"
},
"type": {
"const": "stage"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/TemplateStage"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"kind": {
"const": "template"
},
"type": {
"const": "step"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/TemplateStep"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"kind": {
"const": "plugin"
},
"type": {
"const": "step"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/PluginStep"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"kind": {
"const": "plugin"
},
"type": {
"const": "stage"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/PluginStage"
}
}
}
]
}
],
"x-go-skip": true,
"x-file": "config.yaml"
},
"Pipeline": {
"title": "Pipeline",
"description": "Pipeline defines the pipeline execution.",
"type": "object",
"properties": {
"stages": {
"type": "array",
"description": "Stages defines a list of pipeline stages.",
@ -32,7 +156,7 @@
"description": "Options defines global configuration options."
}
},
"required": ["version", "stages"],
"required": ["stages"],
"examples": [
{
"version": 1,
@ -105,8 +229,8 @@
"description": "The stage conditional logic.",
"$ref": "#/definitions/When"
},
"on": {
"$ref": "#/definitions/On"
"failure": {
"$ref": "#/definitions/FailureList"
}
},
"oneOf": [
@ -435,47 +559,26 @@
"x-go-skip": true,
"x-file": "when_expr.yaml"
},
"On": {
"title": "On",
"type": "object",
"properties": {
"failure": {
"oneOf": [
{
"$ref": "#/definitions/Failure"
},
{
"type": "array",
"items": {
"$ref": "#/definitions/Failure"
}
}
]
"FailureList": {
"title": "FailureList",
"oneOf": [
{
"$ref": "#/definitions/Failure"
},
{
"type": "array",
"items": {
"$ref": "#/definitions/Failure"
}
}
},
],
"x-go-skip": true,
"x-file": "on.yaml"
"x-file": "failure_list.yaml"
},
"Failure": {
"title": "Failure",
"type": "object",
"description": "Failure defines a failure strategy.",
"properties": {
"type": {
"description": "Type defines the failure strategy type.",
"type": "string",
"enum": [
"abort",
"ignore",
"manual-intervention",
"retry",
"success",
"stage-rollback",
"pipeline-rollback",
"retry-step-group",
"fail"
]
},
"errors": {
"description": "Errors specifies the types of errors.",
"type": "array",
@ -497,9 +600,125 @@
"user-mark-fail"
]
}
},
"action": {
"$ref": "#/definitions/FailureAction"
}
},
"x-file": "failure.yaml"
},
"FailureAction": {
"title": "FailureAction",
"type": "object",
"description": "Failure defines a failure strategy.",
"properties": {
"type": {
"description": "Type defines the failure strategy type.",
"type": "string",
"enum": [
"abort",
"fail",
"ignore",
"manual-intervention",
"pipeline-rollback",
"retry",
"retry-step-group",
"stage-rollback",
"success"
]
}
},
"oneOf": [
{
"allOf": [
{
"properties": {
"type": {
"const": "success"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/EmptySpec"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"type": {
"const": "fail"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/EmptySpec"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"type": {
"const": "retry-step-group"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/EmptySpec"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"type": {
"const": "stage-rollback"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/EmptySpec"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"type": {
"const": "pipeline-rollback"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/EmptySpec"
}
}
}
]
},
{
"allOf": [
{
@ -573,7 +792,13 @@
]
}
],
"x-file": "failure.yaml"
"x-file": "failure_action.yaml"
},
"EmptySpec": {
"title": "EmptySpec",
"type": "object",
"properties": {},
"x-file": "empty_spec.yaml"
},
"Abort": {
"title": "Abort",
@ -611,18 +836,169 @@
}
]
},
"on": {
"$ref": "#/definitions/On"
"failure": {
"$ref": "#/definitions/RetryFailure"
}
},
"type": "object",
"x-file": "failure_retry.yaml"
},
"RetryFailure": {
"title": "RetryFailure",
"type": "object",
"properties": {
"action": {
"$ref": "#/definitions/RetryFailureAction"
}
},
"x-file": "retry_failure.yaml"
},
"RetryFailureAction": {
"title": "RetryFailureAction",
"type": "object",
"description": "Failure action on failure for all retries",
"properties": {
"type": {
"description": "Type defines the failure strategy type.",
"type": "string",
"enum": ["abort", "fail", "ignore", "manual-intervention", "pipeline-rollback", "stage-rollback", "success"]
}
},
"oneOf": [
{
"allOf": [
{
"properties": {
"type": {
"const": "success"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/EmptySpec"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"type": {
"const": "fail"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/EmptySpec"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"type": {
"const": "stage-rollback"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/EmptySpec"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"type": {
"const": "pipeline-rollback"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/EmptySpec"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"type": {
"const": "abort"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/Abort"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"type": {
"const": "ignore"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/Ignore"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"type": {
"const": "manual-intervention"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/ManualIntervention"
}
}
}
]
}
],
"x-file": "retry_failure_action.yaml"
},
"ManualIntervention": {
"title": "ManualIntervention",
"properties": {
"on": {
"$ref": "#/definitions/On"
"timeout_action": {
"$ref": "#/definitions/TimeoutAction"
},
"timeout": {
"format": "duration",
@ -633,6 +1009,129 @@
"type": "object",
"x-file": "failure_manual.yaml"
},
"TimeoutAction": {
"title": "TimeoutAction",
"type": "object",
"description": "Manual intervention for timeout failure action",
"properties": {
"type": {
"description": "Type defines the failure strategy type.",
"type": "string",
"enum": ["abort", "ignore", "success", "stage-rollback", "pipeline-rollback", "fail"]
}
},
"oneOf": [
{
"allOf": [
{
"properties": {
"type": {
"const": "success"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/EmptySpec"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"type": {
"const": "fail"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/EmptySpec"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"type": {
"const": "stage-rollback"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/EmptySpec"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"type": {
"const": "pipeline-rollback"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/EmptySpec"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"type": {
"const": "abort"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/Abort"
}
}
}
]
},
{
"allOf": [
{
"properties": {
"type": {
"const": "ignore"
}
}
},
{
"properties": {
"spec": {
"$ref": "#/definitions/Ignore"
}
}
}
]
}
],
"x-file": "timeout_action.yaml"
},
"StageCI": {
"properties": {
"cache": {
@ -1080,8 +1579,8 @@
"description": "The stage conditional logic.",
"$ref": "#/definitions/When"
},
"on": {
"$ref": "#/definitions/On"
"failure": {
"$ref": "#/definitions/FailureList"
}
},
"oneOf": [
@ -2138,6 +2637,10 @@
},
"description": "Enum defines a list of accepted input values.",
"x-go-type": "[]string"
},
"mask": {
"type": "boolean",
"description": "Mask indicates the input should be masked."
}
},
"x-file": "input.yaml"
@ -2362,11 +2865,115 @@
}
},
"x-file": "status.yaml"
},
"TemplateStage": {
"title": "TemplateStage",
"description": "TemplateStage defines a stage-level template",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The template name."
},
"description": {
"type": "string",
"description": "The template description."
},
"stage": {
"$ref": "#/definitions/Stage"
},
"inputs": {
"type": "object",
"description": "Inputs defines the template input parameters.",
"additionalProperties": {
"$ref": "#/definitions/Input"
}
}
},
"x-file": "template_stage.yaml"
},
"TemplateStep": {
"title": "TemplateStep",
"description": "TemplateStep defines a step-level template",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The template name."
},
"description": {
"type": "string",
"description": "The template description."
},
"step": {
"$ref": "#/definitions/Step"
},
"inputs": {
"type": "object",
"description": "Inputs defines the template input parameters.",
"additionalProperties": {
"$ref": "#/definitions/Input"
}
}
},
"x-file": "template_step.yaml"
},
"PluginStep": {
"title": "PluginStep",
"description": "PluginStep defines a step-level plugin",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The plugin name."
},
"description": {
"type": "string",
"description": "The plugin description."
},
"step": {
"$ref": "#/definitions/Step"
},
"inputs": {
"type": "object",
"description": "Inputs defines the plugin input parameters.",
"additionalProperties": {
"$ref": "#/definitions/Input"
}
}
},
"x-file": "plugin_step.yaml"
},
"PluginStage": {
"title": "PluginStage",
"description": "PluginStage defines a stage-level plugin",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The plugin name."
},
"description": {
"type": "string",
"description": "The plugin description."
},
"stage": {
"$ref": "#/definitions/Stage"
},
"inputs": {
"type": "object",
"description": "Inputs defines the plugin input parameters.",
"additionalProperties": {
"$ref": "#/definitions/Input"
}
}
},
"x-file": "plugin_stage.yaml"
}
},
"oneOf": [
{
"$ref": "#/definitions/Pipeline"
"$ref": "#/definitions/Config"
}
]
}