Skip to content

Commit cf78a89

Browse files
Merge branch 'main' into release-bot
2 parents 0ed5869 + 4ae5883 commit cf78a89

22 files changed

+1681
-1446
lines changed

env_gen.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

env_gen.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@
187187
| ECR_REPO_NAME_PREFIX | string |test/ | Prefix for ECR repo to be created in does not exist | | false |
188188
| ENABLE_ASYNC_ARGO_CD_INSTALL_DEVTRON_CHART | bool |false | To enable async installation of gitops application | | false |
189189
| ENABLE_ASYNC_INSTALL_DEVTRON_CHART | bool |false | To enable async installation of no-gitops application | | false |
190+
| ENABLE_LINKED_CI_ARTIFACT_COPY | bool |false | Enable copying artifacts from parent CI pipeline to linked CI pipeline during creation | | false |
190191
| EPHEMERAL_SERVER_VERSION_REGEX | string |v[1-9]\.\b(2[3-9]\|[3-9][0-9])\b.* | ephemeral containers support version regex that is compared with k8sServerVersion | | false |
191192
| EVENT_URL | string |http://localhost:3000/notify | Notifier service url | | false |
192193
| EXECUTE_WIRE_NIL_CHECKER | bool |false | checks for any nil pointer in wire.go | | false |
@@ -225,6 +226,7 @@
225226
| LENS_URL | string |http://lens-milandevtron-service:80 | Lens micro-service URL | | false |
226227
| LIMIT_CI_CPU | string |0.5 | | | false |
227228
| LIMIT_CI_MEM | string |3G | | | false |
229+
| LINKED_CI_ARTIFACT_COPY_LIMIT | int |10 | Maximum number of artifacts to copy from parent CI pipeline to linked CI pipeline | | false |
228230
| LOGGER_DEV_MODE | bool |false | Enables a different logger theme. | | false |
229231
| LOG_LEVEL | int |-1 | | | false |
230232
| MAX_SESSION_PER_USER | int |5 | max no of cluster terminal pods can be created by an user | | false |

internal/sql/repository/CiArtifactRepository.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ type CiArtifactRepository interface {
124124
GetArtifactsByCDPipelineAndRunnerType(cdPipelineId int, runnerType bean.WorkflowType) ([]CiArtifact, error)
125125
SaveAll(artifacts []*CiArtifact) ([]*CiArtifact, error)
126126
GetArtifactsByCiPipelineId(ciPipelineId int) ([]CiArtifact, error)
127+
GetLatestArtifactsByCiPipelineId(ciPipelineId, limit int) ([]CiArtifact, error)
127128
GetArtifactsByCiPipelineIds(ciPipelineIds []int) ([]CiArtifact, error)
128129
FinDByParentCiArtifactAndCiId(parentCiArtifact int, ciPipelineIds []int) ([]*CiArtifact, error)
129130
GetLatest(cdPipelineId int) (int, error)
@@ -680,6 +681,19 @@ func (impl CiArtifactRepositoryImpl) GetArtifactsByCiPipelineId(ciPipelineId int
680681
return artifacts, err
681682
}
682683

684+
func (impl CiArtifactRepositoryImpl) GetLatestArtifactsByCiPipelineId(ciPipelineId, limit int) ([]CiArtifact, error) {
685+
var artifacts []CiArtifact
686+
err := impl.dbConnection.
687+
Model(&artifacts).
688+
Column("ci_artifact.*").
689+
Join("INNER JOIN ci_pipeline cp on cp.id=ci_artifact.pipeline_id").
690+
Where("ci_artifact.pipeline_id = ?", ciPipelineId).
691+
Where("cp.deleted = ?", false).
692+
Order("ci_artifact.id DESC").Limit(limit).
693+
Select()
694+
return artifacts, err
695+
}
696+
683697
func (impl CiArtifactRepositoryImpl) GetArtifactsByCiPipelineIds(ciPipelineIds []int) ([]CiArtifact, error) {
684698
var artifacts []CiArtifact
685699
if len(ciPipelineIds) == 0 {

internal/util/ChartTemplateService.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,6 @@ func (impl ChartTemplateServiceImpl) overrideChartMetaDataInDir(chartDir string,
292292
impl.logger.Errorw("error in loading template chart", "chartPath", chartDir, "err", err)
293293
return nil, err
294294
}
295-
if len(chartMetaData.APIVersion) > 0 {
296-
chart.Metadata.APIVersion = chartMetaData.APIVersion
297-
}
298295
if len(chartMetaData.Name) > 0 {
299296
chart.Metadata.Name = chartMetaData.Name
300297
}

pkg/pipeline/CiCdPipelineOrchestrator.go

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ type CiCdPipelineOrchestratorImpl struct {
154154
deploymentConfigReadService read.DeploymentConfigReadService
155155
workflowCacheConfig types.WorkflowCacheConfig
156156
chartReadService read2.ChartReadService
157+
globalEnvVariables *util2.GlobalEnvVariables
157158
}
158159

159160
func NewCiCdPipelineOrchestrator(
@@ -185,7 +186,8 @@ func NewCiCdPipelineOrchestrator(
185186
gitOpsConfigReadService config.GitOpsConfigReadService,
186187
deploymentConfigService common.DeploymentConfigService,
187188
deploymentConfigReadService read.DeploymentConfigReadService,
188-
chartReadService read2.ChartReadService) *CiCdPipelineOrchestratorImpl {
189+
chartReadService read2.ChartReadService,
190+
envVariables *util2.EnvironmentVariables) *CiCdPipelineOrchestratorImpl {
189191
_, workflowCacheConfig, err := types.GetCiConfigWithWorkflowCacheConfig()
190192
if err != nil {
191193
logger.Errorw("Error in getting workflow cache config, continuing with default values", "err", err)
@@ -223,6 +225,7 @@ func NewCiCdPipelineOrchestrator(
223225
deploymentConfigReadService: deploymentConfigReadService,
224226
workflowCacheConfig: workflowCacheConfig,
225227
chartReadService: chartReadService,
228+
globalEnvVariables: envVariables.GlobalEnvVariables,
226229
}
227230
}
228231

@@ -1160,6 +1163,19 @@ func (impl CiCdPipelineOrchestratorImpl) CreateCiConf(createRequest *bean.CiConf
11601163
r.GitMaterialName = ciMaterial.GitMaterial.Name[strings.Index(ciMaterial.GitMaterial.Name, "-")+1:]
11611164
}
11621165
}
1166+
1167+
// Copy artifacts from parent CI pipeline if this is a linked CI pipeline
1168+
if ciPipeline.ParentCiPipeline > 0 && ciPipeline.PipelineType == buildCommonBean.LINKED {
1169+
go func() {
1170+
err = impl.copyArtifactsFromParentCiPipeline(ciPipeline.ParentCiPipeline, ciPipeline.Id, createRequest.UserId)
1171+
if err != nil {
1172+
impl.logger.Errorw("error in copying artifacts from parent CI pipeline",
1173+
"parentCiPipelineId", ciPipeline.ParentCiPipeline,
1174+
"childCiPipelineId", ciPipeline.Id,
1175+
"err", err)
1176+
}
1177+
}()
1178+
}
11631179
}
11641180
return createRequest, nil
11651181
}
@@ -2511,3 +2527,63 @@ func (impl *CiCdPipelineOrchestratorImpl) GetWorkflowCacheConfig(appType helper.
25112527
}
25122528
}
25132529
}
2530+
2531+
// copyArtifactsFromParentCiPipeline copies existing artifacts from parent CI pipeline to linked CI pipeline during pipeline creation
2532+
func (impl *CiCdPipelineOrchestratorImpl) copyArtifactsFromParentCiPipeline(parentCiPipelineId, childCiPipelineId int, userId int32) error {
2533+
if !impl.globalEnvVariables.EnableLinkedCiArtifactCopy {
2534+
impl.logger.Debugw("Linked CI artifact copying is disabled", "parentCiPipelineId", parentCiPipelineId, "childCiPipelineId", childCiPipelineId)
2535+
return nil
2536+
}
2537+
limit := impl.globalEnvVariables.LinkedCiArtifactCopyLimit
2538+
if limit <= 0 {
2539+
return nil
2540+
}
2541+
2542+
impl.logger.Infow("Starting, copyArtifactsFromParentCiPipeline", "parentCiPipelineId", parentCiPipelineId,
2543+
"childCiPipelineId", childCiPipelineId, "limit", limit)
2544+
2545+
parentArtifacts, err := impl.CiArtifactRepository.GetLatestArtifactsByCiPipelineId(parentCiPipelineId, limit)
2546+
if err != nil && !util.IsErrNoRows(err) {
2547+
impl.logger.Errorw("error in fetching artifacts from parent CI pipeline", "parentCiPipelineId", parentCiPipelineId, "err", err)
2548+
return err
2549+
}
2550+
2551+
if len(parentArtifacts) == 0 {
2552+
impl.logger.Infow("No artifacts found in parent CI pipeline", "parentCiPipelineId", parentCiPipelineId)
2553+
return nil
2554+
}
2555+
2556+
var childArtifacts []*repository.CiArtifact
2557+
for i := len(parentArtifacts); i > 0; i-- {
2558+
parentArtifact := parentArtifacts[i-1] //reversing order into new array because postgres will save the array as it is thus causing our actual order to reverse
2559+
childArtifact := &repository.CiArtifact{
2560+
Image: parentArtifact.Image,
2561+
ImageDigest: parentArtifact.ImageDigest,
2562+
MaterialInfo: parentArtifact.MaterialInfo,
2563+
DataSource: parentArtifact.DataSource,
2564+
PipelineId: childCiPipelineId,
2565+
ParentCiArtifact: parentArtifact.Id,
2566+
IsArtifactUploaded: parentArtifact.IsArtifactUploaded, // for backward compatibility
2567+
ScanEnabled: parentArtifact.ScanEnabled,
2568+
TargetPlatforms: parentArtifact.TargetPlatforms,
2569+
AuditLog: sql.AuditLog{
2570+
CreatedOn: time.Now(),
2571+
CreatedBy: userId,
2572+
UpdatedOn: time.Now(),
2573+
UpdatedBy: userId,
2574+
},
2575+
}
2576+
if parentArtifact.ScanEnabled {
2577+
childArtifact.Scanned = parentArtifact.Scanned
2578+
}
2579+
childArtifacts = append(childArtifacts, childArtifact)
2580+
}
2581+
if len(childArtifacts) > 0 {
2582+
_, err = impl.CiArtifactRepository.SaveAll(childArtifacts)
2583+
if err != nil {
2584+
impl.logger.Errorw("error in saving copied artifacts for child ci pipeline", "childCiPipelineId", childCiPipelineId, "err", err)
2585+
return err
2586+
}
2587+
}
2588+
return nil
2589+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1+
apiVersion: v2
2+
description: Proxy chart for devtron reference app
13
name: sample
24
version: 1.0.0
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
BEGIN;
2+
3+
-- Delete plugin step variable (for step index=1)
4+
DELETE FROM plugin_step_variable
5+
WHERE plugin_step_id = (
6+
SELECT ps.id
7+
FROM plugin_metadata p
8+
INNER JOIN plugin_step ps ON ps.plugin_id = p.id
9+
WHERE p.plugin_version = '1.0.1'
10+
AND p.name = 'Terraform CLI v1.0.0'
11+
AND p.deleted = false
12+
AND ps."index" = 1
13+
AND ps.deleted = false
14+
);
15+
16+
-- Delete plugin steps
17+
DELETE FROM plugin_step
18+
WHERE plugin_id = (
19+
SELECT id
20+
FROM plugin_metadata
21+
WHERE plugin_version = '1.0.1'
22+
AND name = 'Terraform CLI v1.0.0'
23+
AND deleted = false
24+
);
25+
26+
-- Delete pipeline script
27+
DELETE FROM plugin_pipeline_script
28+
WHERE id = (
29+
SELECT script_id
30+
FROM plugin_step
31+
WHERE plugin_id = (
32+
SELECT id
33+
FROM plugin_metadata
34+
WHERE plugin_version = '1.0.1'
35+
AND name = 'Terraform CLI v1.0.0'
36+
AND deleted = false
37+
)
38+
);
39+
40+
-- Delete stage mappings
41+
DELETE FROM plugin_stage_mapping
42+
WHERE plugin_id = (
43+
SELECT id
44+
FROM plugin_metadata
45+
WHERE plugin_version = '1.0.1'
46+
AND name = 'Terraform CLI v1.0.0'
47+
AND deleted = false
48+
);
49+
50+
-- Delete plugin metadata entry
51+
DELETE FROM plugin_metadata
52+
WHERE plugin_version = '1.0.1'
53+
AND name = 'Terraform CLI v1.0.0'
54+
AND deleted = false;
55+
56+
-- Mark previous version as latest
57+
UPDATE plugin_metadata
58+
SET is_latest = true
59+
WHERE id = (
60+
SELECT id
61+
FROM plugin_metadata
62+
WHERE name = 'Terraform CLI v1.0.0'
63+
AND is_latest = false
64+
AND plugin_version = '1.0.0'
65+
);
66+
67+
COMMIT;
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright (c) 2025. Devtron Inc.
3+
*/
4+
BEGIN;
5+
6+
-- Update the existing entry is_latest false for terrfaorm plugin
7+
UPDATE plugin_metadata SET is_latest = false WHERE id = (SELECT id FROM plugin_metadata WHERE name= 'Terraform CLI v1.0.0' and is_latest= true);
8+
9+
-- Insert an entry in plugin_metadata for new version v1.0.1
10+
INSERT INTO "plugin_metadata" ("id", "name", "description","deleted", "created_on", "created_by", "updated_on", "updated_by","plugin_parent_metadata_id","plugin_version","is_deprecated","is_latest")
11+
VALUES (nextval('id_seq_plugin_metadata'), 'Terraform CLI v1.0.0','Terraform: Simplify infrastructure as code, manage resources effortlessly, and deploy with ease using this plugins','f', 'now()', 1, 'now()', 1, (SELECT id FROM plugin_parent_metadata WHERE identifier='terraform-cli-v1-0-0'),'1.0.1', false, true);
12+
13+
-- Insert the plugin stage mapping
14+
INSERT INTO "plugin_stage_mapping" ("plugin_id","stage_type","created_on", "created_by", "updated_on", "updated_by")
15+
VALUES ((SELECT id FROM plugin_metadata WHERE plugin_version='1.0.1' and name='Terraform CLI v1.0.0' and deleted= false),0,'now()', 1, 'now()', 1);
16+
17+
-- Insert updated script
18+
INSERT INTO "plugin_pipeline_script" ("id", "script","type","deleted","created_on", "created_by", "updated_on", "updated_by")
19+
VALUES (nextval('id_seq_plugin_pipeline_script'),E'
20+
export DEFAULT_TF_IMAGE=docker.io/hashicorp/terraform:latest
21+
if [ -n "$TERRAFORM_IMAGE" ]; then
22+
echo "Using $TERRAFORM_IMAGE as the custom image."
23+
DEFAULT_TF_IMAGE="$TERRAFORM_IMAGE"
24+
else
25+
echo "Using the default image --> $DEFAULT_TF_IMAGE"
26+
fi
27+
28+
# RUNNING Terraform init
29+
if [ $RUN_TERRAFORM_INIT == "TRUE" ]; then
30+
#RUNNING Terraform init
31+
docker run -v $PWD:$PWD -w $PWD/$WORKINGDIR -e HTTP_PROXY=$HTTP_PROXY -e HTTPS_PROXY=$HTTPS_PROXY -e NO_PROXY=$NO_PROXY $DEFAULT_TF_IMAGE init
32+
fi
33+
34+
35+
# exporting all the env variables
36+
echo "$ADDITIONALPARAMS" > devtron-custom-values.env
37+
38+
# RUNNING Terraform command
39+
echo "docker run -v $PWD:$PWD -w $PWD/$WORKINGDIR --env-file devtron-custom-values.env -e HTTP_PROXY=$HTTP_PROXY -e HTTPS_PROXY=$HTTPS_PROXY -e NO_PROXY=$NO_PROXY $DEFAULT_TF_IMAGE $ARGS"
40+
docker run -v $PWD:$PWD -w $PWD/$WORKINGDIR --env-file devtron-custom-values.env -e HTTP_PROXY=$HTTP_PROXY -e HTTPS_PROXY=$HTTPS_PROXY -e NO_PROXY=$NO_PROXY $DEFAULT_TF_IMAGE $ARGS','SHELL','f','now()',1,'now()',1);
41+
42+
INSERT INTO "plugin_step" ("id", "plugin_id","name","description","index","step_type","script_id","deleted", "created_on", "created_by", "updated_on", "updated_by")
43+
VALUES (nextval('id_seq_plugin_step'), (SELECT id FROM plugin_metadata WHERE name='Terraform CLI v1.0.0' and plugin_version='1.0.1'),'Step 1','Step 1 - Terraform CLI v1.0.0','1','INLINE',(SELECT last_value FROM id_seq_plugin_pipeline_script),'f','now()', 1, 'now()', 1);
44+
45+
INSERT INTO plugin_step_variable (id,plugin_step_id,name,format,description,is_exposed,allow_empty_value,default_value,value,variable_type,value_type,previous_step_index,variable_step_index,variable_step_index_in_plugin,reference_variable_name,deleted,created_on,created_by,updated_on,updated_by)
46+
VALUES
47+
(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Terraform CLI v1.0.0' and ps."index"=1 and p.plugin_version='1.0.1' and ps.deleted=false),'HTTP_PROXY','STRING','Specify the HTTP proxy server for non-SSL requests.','t','t',null,null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1),
48+
(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Terraform CLI v1.0.0' and ps."index"=1 and p.plugin_version='1.0.1' and ps.deleted=false),'HTTPS_PROXY','STRING','Specify the HTTPS proxy server for SSL requests.','t','t',null,null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1),
49+
(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Terraform CLI v1.0.0' and ps."index"=1 and p.plugin_version='1.0.1' and ps.deleted=false),'NO_PROXY','STRING','Opt out of proxying HTTP/HTTPS requests. Use this to specify hosts that should bypass the proxy.','t','t',null,null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1),
50+
(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Terraform CLI v1.0.0' and ps."index"=1 and p.plugin_version='1.0.1' and ps.deleted=false),'TERRAFORM_IMAGE','STRING','Specify a custom Terraform container image to use for the execution of Terraform commands.','t','t',null,null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1),
51+
(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Terraform CLI v1.0.0' and ps."index"=1 and p.plugin_version='1.0.1' and ps.deleted=false),'WORKINGDIR','STRING','Set the source directory for Terraform execution.Example: /path/to/terraform/project','t','t',null,null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1),
52+
(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Terraform CLI v1.0.0' and ps."index"=1 and p.plugin_version='1.0.1' and ps.deleted=false),'ARGS','STRING','Specifies Terraform CLI commands to run. Example: plan -var-file=myvars.tfvars','t','t','--help',null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1),
53+
(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Terraform CLI v1.0.0' and ps."index"=1 and p.plugin_version='1.0.1' and ps.deleted=false),'RUN_TERRAFORM_INIT','BOOL','Determines whether to run the Terraform initialization command.','t','t','TRUE',null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1),
54+
(nextval('id_seq_plugin_step_variable'),(SELECT ps.id FROM plugin_metadata p inner JOIN plugin_step ps on ps.plugin_id=p.id WHERE p.name='Terraform CLI v1.0.0' and ps."index"=1 and p.plugin_version='1.0.1' and ps.deleted=false),'ADDITIONALPARAMS','STRING','Provides key-value pairs to inject into the Terraform container.Example: VAR1=value1 VAR2=value2c','t','t',null,null,'INPUT','NEW',null,1,null,null,'f','now()',1,'now()',1);
55+
COMMIT;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--- No down migration required
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--- There was an issue with Deployment chart versions 4.18.0, 4.19.0, 1.0.0, 1.1.0
2+
--- Which was fixed in PR https://github.com/devtron-labs/devtron/pull/5215/files
3+
--- But as we cache the reference chart in DB, we need to clear that cache for those charts
4+
UPDATE charts
5+
SET reference_chart = NULL
6+
WHERE id IN (
7+
SELECT charts.id FROM charts
8+
INNER JOIN chart_ref ON (charts.chart_ref_id = chart_ref.id)
9+
INNER JOIN app ON (charts.app_id = app.id AND app.active = true)
10+
WHERE charts.active = true
11+
AND chart_ref.version IN ('4.18.0', '4.19.0', '1.0.0', '1.1.0')
12+
AND chart_ref.name = 'Deployment'
13+
);

0 commit comments

Comments
 (0)