@@ -18,6 +18,10 @@ package stage
1818
1919import (
2020 "context"
21+ "errors"
22+ "fmt"
23+ "github.com/devtron-labs/ci-runner/helper/adaptor"
24+ "github.com/devtron-labs/common-lib/utils/workFlow"
2125 "log"
2226 "os"
2327
@@ -42,21 +46,70 @@ func NewCdStage(gitManager helper.GitManager, dockerHelper helper.DockerHelper,
4246 }
4347}
4448
45- func (impl * CdStage ) HandleCDEvent (ciCdRequest * helper.CiCdTriggerEvent , exitCode * int ) {
46- err := impl .runCDStages (ciCdRequest )
47- artifactUploadErr := collectAndUploadCDArtifacts (ciCdRequest .CommonWorkflowRequest )
48- if err != nil || artifactUploadErr != nil {
49- log .Println (err )
50- * exitCode = util .DefaultErrorCode
49+ func deferCDEvent (cdRequest * helper.CommonWorkflowRequest , artifactUploaded bool , err error ) (exitCode int ) {
50+ log .Println (util .DEVTRON , "defer CD stage data." , "err: " , err , "artifactUploaded: " , artifactUploaded )
51+ if err != nil {
52+ exitCode = workFlow .DefaultErrorCode
53+ var stageError * helper.CdStageError
54+ if errors .As (err , & stageError ) {
55+ // update artifact uploaded status
56+ if ! stageError .IsArtifactUploaded () {
57+ stageError = stageError .WithArtifactUploaded (artifactUploaded )
58+ }
59+ } else {
60+ stageError = helper .NewCdStageError (fmt .Errorf (workFlow .CdStageFailed .String (), cdRequest .GetCdStageType (), err )).
61+ WithArtifactUploaded (artifactUploaded )
62+ }
63+ // send ci failure event, for ci failure notification
64+ sendCDFailureEvent (cdRequest , stageError )
65+ // populate stage error
66+ util .PopulateStageError (stageError .ErrorMessage ())
5167 }
68+ return exitCode
69+ }
5270
71+ func (impl * CdStage ) HandleCDEvent (ciCdRequest * helper.CiCdTriggerEvent , exitCode * int ) {
72+ var artifactUploaded bool
73+ var err error
74+ var allPluginArtifacts * helper.PluginArtifacts
75+ defer func () {
76+ * exitCode = deferCDEvent (ciCdRequest .CommonWorkflowRequest , artifactUploaded , err )
77+ }()
78+ allPluginArtifacts , err = impl .runCDStages (ciCdRequest )
79+ if err != nil {
80+ log .Println ("cd stage error: " , err )
81+ // not returning error as we want to upload artifacts
82+ }
83+ var artifactUploadErr error
84+ artifactUploaded , artifactUploadErr = collectAndUploadCDArtifacts (ciCdRequest .CommonWorkflowRequest )
85+ if artifactUploadErr != nil {
86+ log .Println ("error in artifact upload: " , artifactUploadErr )
87+ // if artifact upload fails, treat it as exit status code 1 and set err to artifact upload error
88+ if err == nil {
89+ err = artifactUploadErr
90+ }
91+ }
92+ // IsVirtualExecution run flag indicates that cd stage is running in virtual mode.
93+ // specifically for isolated environment type, for IsVirtualExecution we don't send success event.
94+ // but failure event is sent in case of error.
95+ if err == nil && ! ciCdRequest .CommonWorkflowRequest .IsVirtualExecution {
96+ log .Println (util .DEVTRON , " event" )
97+ event := adaptor .NewCdCompleteEvent (ciCdRequest .CommonWorkflowRequest ).
98+ WithPluginArtifacts (allPluginArtifacts ).
99+ WithIsArtifactUploaded (artifactUploaded )
100+ err = helper .SendCDEvent (ciCdRequest .CommonWorkflowRequest , event )
101+ if err != nil {
102+ log .Println (err )
103+ }
104+ log .Println (util .DEVTRON , " /event" )
105+ }
106+ return
53107}
54108
55- func collectAndUploadCDArtifacts (cdRequest * helper.CommonWorkflowRequest ) error {
109+ func collectAndUploadCDArtifacts (cdRequest * helper.CommonWorkflowRequest ) ( artifactUploaded bool , err error ) {
56110 cloudHelperBaseConfig := cdRequest .GetCloudHelperBaseConfig (util .BlobStorageObjectTypeArtifact )
57111 if cdRequest .PrePostDeploySteps != nil && len (cdRequest .PrePostDeploySteps ) > 0 {
58- err := helper .ZipAndUpload (cloudHelperBaseConfig , cdRequest .CiArtifactFileName )
59- return err
112+ return helper .ZipAndUpload (cloudHelperBaseConfig , cdRequest .CiArtifactFileName )
60113 }
61114
62115 // to support stage YAML outputs
@@ -82,73 +135,75 @@ func collectAndUploadCDArtifacts(cdRequest *helper.CommonWorkflowRequest) error
82135 return helper .UploadArtifact (cloudHelperBaseConfig , artifactFiles , cdRequest .CiArtifactFileName )
83136}
84137
85- func (impl * CdStage ) runCDStages (cicdRequest * helper.CiCdTriggerEvent ) error {
138+ func (impl * CdStage ) runCDStages (ciCdRequest * helper.CiCdTriggerEvent ) ( * helper. PluginArtifacts , error ) {
86139 err := os .Chdir ("/" )
87140 if err != nil {
88- return err
141+ return nil , err
89142 }
90143
91144 if _ , err := os .Stat (util .WORKINGDIR ); os .IsNotExist (err ) {
92145 _ = os .Mkdir (util .WORKINGDIR , os .ModeDir )
93146 }
94147 err = os .Chdir (util .WORKINGDIR )
95148 if err != nil {
96- return err
149+ return nil , err
97150 }
98151 // git handling
99152 // we are skipping clone and checkout in case of ci job type poll cr images plugin does not require it.(ci-job)
100- skipCheckout := cicdRequest .CommonWorkflowRequest .CiPipelineType == helper .CI_JOB
153+ skipCheckout := ciCdRequest .CommonWorkflowRequest .CiPipelineType == helper .CI_JOB
101154 if ! skipCheckout {
102155 log .Println (util .DEVTRON , " git" )
103- err = impl .gitManager .CloneAndCheckout (cicdRequest .CommonWorkflowRequest .CiProjectDetails )
156+ err = impl .gitManager .CloneAndCheckout (ciCdRequest .CommonWorkflowRequest .CiProjectDetails )
104157 if err != nil {
105158 log .Println (util .DEVTRON , "clone err: " , err )
106- return err
159+ return nil , err
107160 }
108161 }
109162 log .Println (util .DEVTRON , " /git" )
110163 // Start docker daemon
111164 log .Println (util .DEVTRON , " docker-start" )
112- impl .dockerHelper .StartDockerDaemon (cicdRequest .CommonWorkflowRequest )
113- ciContext := cictx .BuildCiContext (context .Background (), cicdRequest .CommonWorkflowRequest .EnableSecretMasking )
165+ impl .dockerHelper .StartDockerDaemon (ciCdRequest .CommonWorkflowRequest )
166+ ciContext := cictx .BuildCiContext (context .Background (), ciCdRequest .CommonWorkflowRequest .EnableSecretMasking )
114167 err = impl .dockerHelper .DockerLogin (ciContext , & helper.DockerCredentials {
115- DockerUsername : cicdRequest .CommonWorkflowRequest .DockerUsername ,
116- DockerPassword : cicdRequest .CommonWorkflowRequest .DockerPassword ,
117- AwsRegion : cicdRequest .CommonWorkflowRequest .AwsRegion ,
118- AccessKey : cicdRequest .CommonWorkflowRequest .AccessKey ,
119- SecretKey : cicdRequest .CommonWorkflowRequest .SecretKey ,
120- DockerRegistryURL : cicdRequest .CommonWorkflowRequest .IntermediateDockerRegistryUrl ,
121- DockerRegistryType : cicdRequest .CommonWorkflowRequest .DockerRegistryType ,
168+ DockerUsername : ciCdRequest .CommonWorkflowRequest .DockerUsername ,
169+ DockerPassword : ciCdRequest .CommonWorkflowRequest .DockerPassword ,
170+ AwsRegion : ciCdRequest .CommonWorkflowRequest .AwsRegion ,
171+ AccessKey : ciCdRequest .CommonWorkflowRequest .AccessKey ,
172+ SecretKey : ciCdRequest .CommonWorkflowRequest .SecretKey ,
173+ DockerRegistryURL : ciCdRequest .CommonWorkflowRequest .IntermediateDockerRegistryUrl ,
174+ DockerRegistryType : ciCdRequest .CommonWorkflowRequest .DockerRegistryType ,
122175 })
123176 if err != nil {
124- return err
177+ return nil , err
125178 }
126179
127- scriptEnvs , err := util2 .GetGlobalEnvVariables (cicdRequest )
180+ scriptEnvs , err := util2 .GetGlobalEnvVariables (ciCdRequest )
128181
129182 allPluginArtifacts := helper .NewPluginArtifact ()
130- if len (cicdRequest .CommonWorkflowRequest .PrePostDeploySteps ) > 0 {
183+ if len (ciCdRequest .CommonWorkflowRequest .PrePostDeploySteps ) > 0 {
131184 refStageMap := make (map [int ][]* helper.StepObject )
132- for _ , ref := range cicdRequest .CommonWorkflowRequest .RefPlugins {
185+ for _ , ref := range ciCdRequest .CommonWorkflowRequest .RefPlugins {
133186 refStageMap [ref .Id ] = ref .Steps
134187 }
135- scriptEnvs ["DEST" ] = cicdRequest .CommonWorkflowRequest .CiArtifactDTO .Image
136- scriptEnvs ["DIGEST" ] = cicdRequest .CommonWorkflowRequest .CiArtifactDTO .ImageDigest
137- var stage = helper .StepType (cicdRequest .CommonWorkflowRequest .StageType )
138- pluginArtifacts , _ , _ , err := impl .stageExecutorManager .RunCiCdSteps (stage , cicdRequest .CommonWorkflowRequest , cicdRequest .CommonWorkflowRequest .PrePostDeploySteps , refStageMap , scriptEnvs , nil )
188+ scriptEnvs ["DEST" ] = ciCdRequest .CommonWorkflowRequest .CiArtifactDTO .Image
189+ scriptEnvs ["DIGEST" ] = ciCdRequest .CommonWorkflowRequest .CiArtifactDTO .ImageDigest
190+ var stage = helper .StepType (ciCdRequest .CommonWorkflowRequest .StageType )
191+ pluginArtifacts , _ , step , err := impl .stageExecutorManager .RunCiCdSteps (stage , ciCdRequest .CommonWorkflowRequest , ciCdRequest .CommonWorkflowRequest .PrePostDeploySteps , refStageMap , scriptEnvs , nil )
139192 if err != nil {
140- return err
193+ return allPluginArtifacts , helper .NewCdStageError (err ).
194+ WithFailureMessage (fmt .Sprintf (workFlow .CdStageTaskFailed .String (), ciCdRequest .CommonWorkflowRequest .GetCdStageType (), step .Name )).
195+ WithArtifactUploaded (false )
141196 }
142197 allPluginArtifacts .MergePluginArtifact (pluginArtifacts )
143198 } else {
144199
145200 // Get devtron-cd yaml
146- taskYaml , err := helper .ToTaskYaml ([]byte (cicdRequest .CommonWorkflowRequest .StageYaml ))
201+ taskYaml , err := helper .ToTaskYaml ([]byte (ciCdRequest .CommonWorkflowRequest .StageYaml ))
147202 if err != nil {
148203 log .Println (err )
149- return err
204+ return allPluginArtifacts , err
150205 }
151- cicdRequest .CommonWorkflowRequest .TaskYaml = taskYaml
206+ ciCdRequest .CommonWorkflowRequest .TaskYaml = taskYaml
152207
153208 // run post artifact processing
154209 log .Println (util .DEVTRON , " stage yaml" , taskYaml )
@@ -158,28 +213,16 @@ func (impl *CdStage) runCDStages(cicdRequest *helper.CiCdTriggerEvent) error {
158213 tasks = append (tasks , t .AfterTasks ... )
159214 }
160215
216+ err = impl .stageExecutorManager .RunCdStageTasks (ciContext , tasks , scriptEnvs , ciCdRequest .CommonWorkflowRequest .GetCdStageType ())
161217 if err != nil {
162- return err
163- }
164- err = impl .stageExecutorManager .RunCdStageTasks (ciContext , tasks , scriptEnvs )
165- if err != nil {
166- return err
167- }
168- }
169- // dry run flag indicates that ci runner image is being run from external helm chart
170- if ! cicdRequest .CommonWorkflowRequest .IsDryRun {
171- log .Println (util .DEVTRON , " event" )
172- err = helper .SendCDEvent (cicdRequest .CommonWorkflowRequest , allPluginArtifacts )
173- if err != nil {
174- log .Println (err )
175- return err
218+ return allPluginArtifacts , err
176219 }
177- log .Println (util .DEVTRON , " /event" )
178220 }
221+
179222 err = impl .dockerHelper .StopDocker (ciContext )
180223 if err != nil {
181224 log .Println ("error while stopping docker" , err )
182- return err
225+ return allPluginArtifacts , err
183226 }
184- return nil
227+ return allPluginArtifacts , nil
185228}
0 commit comments