Skip to content

Commit ece1ef8

Browse files
akshatsinha007kartik-579prkhrkatvikramdevtroniamayushm
authored
misc: merged main in release-bot (#6500)
* ci pipeline get change * ci pipeline get change * GetCiPipelineByIdWithDefaultTag change * deployment template get response * cd pipeline get response change * oss etn change * oss ent change * prom client in chart-sync * fix in yaml * APP_SYNC_SHUTDOWN_WAIT_DURATION env * APP_SYNC_SHUTDOWN_WAIT_DURATION env * vendor update in develop * fix: incorrect gitops metrics (#6444) * wip: fix gitops metrics * fix pull metrics * github create repo function * wip: metrics changed from defer function * fix metrics publish * self review changes * oss ent change * code cleaning * name suggestion util * added supoort for preserve mode in update repo api * fix in CreateGrafanaDataSource * fix in CreateGrafanaDataSource * feat: Made ng labels env driven (#6438) * feat: Adds karpenter ng to list of ng constants * feat: made nodelabels env driven * feat: Updates env get as per repo standards * prom client in chart-sync * fix in yaml * chore: resolve merge conflict * APP_SYNC_SHUTDOWN_WAIT_DURATION env * code cleaning --------- Co-authored-by: prakhar katiyar <prkhrkat@gmail.com> * updated timeout for git material save/update * fix: compile issue * updated protos version * added sql scripts * sql no update * wip: optimisation (#6473) * vendor update * feat: licensing changes (#6474) * modules handling * example * sql files * common lib update * release: Compatibility Modifications for Enterprise and OSS Chart (#6486) * added devtronEnterprise check conditions * added devtron-operator-cm in inception * added eneterprise flag in devtron-cm * updated dashboard cm * added random alpha for ent-job * added DEVTRON_VERSION_IDENTIFIER_IN_HELM_VALUES in devtro-cm * updated installer for enterprise * bom * fix: for grafana URL * fix: for grafana URL --------- Co-authored-by: kartik-579 <kartik@devtron.ai> Co-authored-by: prakhar katiyar <prkhrkat@gmail.com> Co-authored-by: Vikram Singh <vikram@devtron.ai> Co-authored-by: Vikram <73224103+vikramdevtron@users.noreply.github.com> Co-authored-by: iamayushm <32041961+iamayushm@users.noreply.github.com> Co-authored-by: prakhar katiyar <39842461+prkhrkat@users.noreply.github.com> Co-authored-by: Ash-exp <asutosh2000ad@gmail.com> Co-authored-by: Abhibhaw Asthana <39991296+abhibhaw@users.noreply.github.com> Co-authored-by: kartik-579 <84493919+kartik-579@users.noreply.github.com> Co-authored-by: Shivam Nagar <124123645+Shivam-nagar23@users.noreply.github.com>
1 parent d4848c4 commit ece1ef8

File tree

117 files changed

+9109
-3225
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

117 files changed

+9109
-3225
lines changed

api/restHandler/app/pipeline/configure/BuildPipelineRestHandler.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -565,15 +565,12 @@ func (handler *PipelineConfigRestHandlerImpl) GetCiPipeline(w http.ResponseWrite
565565
common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden)
566566
return
567567
}
568-
ciConf, err := handler.pipelineBuilder.GetCiPipeline(appId)
568+
ciConf, err := handler.pipelineBuilder.GetCiPipelineRespResolved(appId)
569569
if err != nil {
570-
handler.Logger.Errorw("service err, GetCiPipeline", "err", err, "appId", appId)
570+
handler.Logger.Errorw("service err, GetCiPipelineRespResolved", "appId", appId, "err", err)
571571
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
572572
return
573573
}
574-
if ciConf == nil || ciConf.Id == 0 {
575-
err = &util.ApiError{Code: "404", HttpStatusCode: 200, UserMessage: "no data found"}
576-
}
577574
common.WriteJsonResp(w, err, ciConf, http.StatusOK)
578575
}
579576

@@ -1286,13 +1283,12 @@ func (handler *PipelineConfigRestHandlerImpl) GetCIPipelineById(w http.ResponseW
12861283
}
12871284
}
12881285

1289-
ciPipeline, err := handler.pipelineBuilder.GetCiPipelineById(pipelineId)
1286+
ciPipeline, err := handler.pipelineBuilder.GetCiPipelineByIdWithDefaultTag(pipelineId)
12901287
if err != nil {
1291-
handler.Logger.Infow("service error, GetCIPipelineById", "err", err, "appId", appId, "pipelineId", pipelineId)
1288+
handler.Logger.Infow("service error, GetCiPipelineByIdWithDefaultTag", "err", err, "appId", appId, "pipelineId", pipelineId)
12921289
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
12931290
return
12941291
}
1295-
ciPipeline.DefaultTag = []string{"{git_hash}", "{ci_pipeline_id}", "{global_counter}"}
12961292
common.WriteJsonResp(w, err, ciPipeline, http.StatusOK)
12971293
}
12981294

api/restHandler/app/pipeline/configure/DeploymentPipelineRestHandler.go

Lines changed: 17 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ import (
4141
"github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin"
4242
"github.com/devtron-labs/devtron/pkg/bean"
4343
"github.com/devtron-labs/devtron/pkg/generateManifest"
44-
"github.com/devtron-labs/devtron/pkg/pipeline"
4544
pipelineBean "github.com/devtron-labs/devtron/pkg/pipeline/bean"
4645
resourceGroup2 "github.com/devtron-labs/devtron/pkg/resourceGroup"
4746
"github.com/devtron-labs/devtron/pkg/resourceQualifiers"
@@ -718,48 +717,22 @@ func (handler *PipelineConfigRestHandlerImpl) EnvConfigOverrideCreate(w http.Res
718717
return
719718
}
720719

721-
createResp, err := handler.propertiesConfigService.CreateEnvironmentProperties(appId, &envConfigProperties)
722-
if err != nil {
723-
if err.Error() == bean4.NOCHARTEXIST {
724-
ctx, cancel := context.WithCancel(r.Context())
725-
if cn, ok := w.(http.CloseNotifier); ok {
726-
go func(done <-chan struct{}, closed <-chan bool) {
727-
select {
728-
case <-done:
729-
case <-closed:
730-
cancel()
731-
}
732-
}(ctx.Done(), cn.CloseNotify())
733-
}
734-
appMetrics := false
735-
if envConfigProperties.AppMetrics != nil {
736-
appMetrics = *envConfigProperties.AppMetrics
737-
}
738-
templateRequest := bean3.TemplateRequest{
739-
AppId: appId,
740-
ChartRefId: envConfigProperties.ChartRefId,
741-
ValuesOverride: []byte("{}"),
742-
UserId: userId,
743-
IsAppMetricsEnabled: appMetrics,
720+
ctx, cancel := context.WithCancel(r.Context())
721+
if cn, ok := w.(http.CloseNotifier); ok {
722+
go func(done <-chan struct{}, closed <-chan bool) {
723+
select {
724+
case <-done:
725+
case <-closed:
726+
cancel()
744727
}
728+
}(ctx.Done(), cn.CloseNotify())
729+
}
745730

746-
_, err = handler.chartService.CreateChartFromEnvOverride(templateRequest, ctx)
747-
if err != nil {
748-
handler.Logger.Errorw("service err, EnvConfigOverrideCreate", "err", err, "payload", envConfigProperties)
749-
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
750-
return
751-
}
752-
createResp, err = handler.propertiesConfigService.CreateEnvironmentProperties(appId, &envConfigProperties)
753-
if err != nil {
754-
handler.Logger.Errorw("service err, EnvConfigOverrideCreate", "err", err, "payload", envConfigProperties)
755-
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
756-
return
757-
}
758-
} else {
759-
handler.Logger.Errorw("service err, EnvConfigOverrideCreate", "err", err, "payload", envConfigProperties)
760-
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
761-
return
762-
}
731+
createResp, err := handler.propertiesConfigService.CreateEnvironmentPropertiesAndBaseIfNeeded(ctx, appId, &envConfigProperties)
732+
if err != nil {
733+
handler.Logger.Errorw("service err, CreateEnvironmentPropertiesAndBaseIfNeeded", "payload", envConfigProperties, "err", err)
734+
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
735+
return
763736
}
764737
common.WriteJsonResp(w, err, createResp, http.StatusOK)
765738
}
@@ -1037,77 +1010,12 @@ func (handler *PipelineConfigRestHandlerImpl) GetDeploymentTemplate(w http.Respo
10371010
common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden)
10381011
return
10391012
}
1040-
1041-
appConfigResponse := make(map[string]interface{})
1042-
appConfigResponse["globalConfig"] = nil
1043-
1044-
err = handler.chartRefService.CheckChartExists(chartRefId)
1013+
appConfigResponse, err := handler.chartService.GetDeploymentTemplateDataByAppIdAndCharRefId(appId, chartRefId)
10451014
if err != nil {
10461015
handler.Logger.Errorw("refChartDir Not Found err, JsonSchemaExtractFromFile", err)
10471016
common.WriteJsonResp(w, err, nil, http.StatusForbidden)
10481017
return
10491018
}
1050-
1051-
schema, readme, err := handler.chartRefService.GetSchemaAndReadmeForTemplateByChartRefId(chartRefId)
1052-
if err != nil {
1053-
handler.Logger.Errorw("err in getting schema and readme, GetDeploymentTemplate", "err", err, "appId", appId, "chartRefId", chartRefId)
1054-
}
1055-
1056-
template, err := handler.chartReadService.FindLatestChartForAppByAppId(appId)
1057-
if err != nil && pg.ErrNoRows != err {
1058-
handler.Logger.Errorw("service err, GetDeploymentTemplate", "err", err, "appId", appId, "chartRefId", chartRefId)
1059-
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
1060-
return
1061-
}
1062-
1063-
if pg.ErrNoRows == err {
1064-
appOverride, _, err := handler.chartRefService.GetAppOverrideForDefaultTemplate(chartRefId)
1065-
if err != nil {
1066-
handler.Logger.Errorw("service err, GetDeploymentTemplate", "err", err, "appId", appId, "chartRefId", chartRefId)
1067-
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
1068-
return
1069-
}
1070-
appOverride["schema"] = json.RawMessage(schema)
1071-
appOverride["readme"] = string(readme)
1072-
mapB, err := json.Marshal(appOverride)
1073-
if err != nil {
1074-
handler.Logger.Errorw("marshal err, GetDeploymentTemplate", "err", err, "appId", appId, "chartRefId", chartRefId)
1075-
return
1076-
}
1077-
appConfigResponse["globalConfig"] = json.RawMessage(mapB)
1078-
} else {
1079-
if template.ChartRefId != chartRefId {
1080-
templateRequested, err := handler.chartService.GetByAppIdAndChartRefId(appId, chartRefId)
1081-
if err != nil && err != pg.ErrNoRows {
1082-
handler.Logger.Errorw("service err, GetDeploymentTemplate", "err", err, "appId", appId, "chartRefId", chartRefId)
1083-
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
1084-
return
1085-
}
1086-
1087-
if pg.ErrNoRows == err {
1088-
template.ChartRefId = chartRefId
1089-
template.Id = 0
1090-
template.Latest = false
1091-
} else {
1092-
template.ChartRefId = templateRequested.ChartRefId
1093-
template.Id = templateRequested.Id
1094-
template.ChartRepositoryId = templateRequested.ChartRepositoryId
1095-
template.RefChartTemplate = templateRequested.RefChartTemplate
1096-
template.RefChartTemplateVersion = templateRequested.RefChartTemplateVersion
1097-
template.Latest = templateRequested.Latest
1098-
}
1099-
}
1100-
template.Schema = schema
1101-
template.Readme = string(readme)
1102-
bytes, err := json.Marshal(template)
1103-
if err != nil {
1104-
handler.Logger.Errorw("marshal err, GetDeploymentTemplate", "err", err, "appId", appId, "chartRefId", chartRefId)
1105-
return
1106-
}
1107-
appOverride := json.RawMessage(bytes)
1108-
appConfigResponse["globalConfig"] = appOverride
1109-
}
1110-
11111019
common.WriteJsonResp(w, nil, appConfigResponse, http.StatusOK)
11121020
}
11131021

@@ -1992,15 +1900,9 @@ func (handler *PipelineConfigRestHandlerImpl) GetCdPipelineById(w http.ResponseW
19921900
return
19931901
}
19941902

1995-
cdPipeline, err := handler.pipelineBuilder.GetCdPipelineById(pipelineId)
1996-
if err != nil {
1997-
handler.Logger.Errorw("service err, GetCdPipelineById", "err", err, "appId", appId, "pipelineId", pipelineId)
1998-
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
1999-
return
2000-
}
2001-
cdResp, err := pipeline.CreatePreAndPostStageResponse(cdPipeline, version)
1903+
cdResp, err := handler.pipelineBuilder.GetCdPipelineByIdResolved(pipelineId, version)
20021904
if err != nil {
2003-
handler.Logger.Errorw("service err, CheckForVersionAndCreatePreAndPostStagePayload", "err", err, "appId", appId, "pipelineId", pipelineId)
1905+
handler.Logger.Errorw("service err, GetCdPipelineByIdResolved", "appId", appId, "pipelineId", pipelineId, "err", err)
20041906
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
20051907
return
20061908
}

api/restHandler/app/pipeline/configure/PipelineConfigRestHandler.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
security2 "github.com/devtron-labs/devtron/pkg/policyGovernance/security/imageScanning"
3636
"github.com/devtron-labs/devtron/pkg/policyGovernance/security/imageScanning/read"
3737
read3 "github.com/devtron-labs/devtron/pkg/team/read"
38+
"github.com/devtron-labs/devtron/util/beHelper"
3839
"io"
3940
"net/http"
4041
"strconv"
@@ -60,7 +61,6 @@ import (
6061
"github.com/devtron-labs/devtron/pkg/bean"
6162
"github.com/devtron-labs/devtron/pkg/pipeline"
6263
"github.com/devtron-labs/devtron/pkg/team"
63-
util2 "github.com/devtron-labs/devtron/util"
6464
"github.com/devtron-labs/devtron/util/rbac"
6565
"github.com/gorilla/mux"
6666
"go.uber.org/zap"
@@ -663,7 +663,7 @@ func (handler *PipelineConfigRestHandlerImpl) PipelineNameSuggestion(w http.Resp
663663
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
664664
return
665665
}
666-
suggestedName := fmt.Sprintf("%s-%d-%s", pType, appId, util2.Generate(4))
666+
suggestedName := beHelper.GetPipelineNameByPipelineType(pType, appId)
667667
resourceName := handler.enforcerUtil.GetAppRBACName(app.AppName)
668668
ok := handler.enforcerUtil.CheckAppRbacForAppOrJob(token, resourceName, casbin.ActionGet)
669669
if !ok {

api/restHandler/app/workflow/AppWorkflowRestHandler.go

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -188,13 +188,6 @@ func (impl AppWorkflowRestHandlerImpl) FindAppWorkflow(w http.ResponseWriter, r
188188
return
189189
}
190190
token := r.Header.Get("token")
191-
app, err := impl.pipelineBuilder.GetApp(appId)
192-
if err != nil {
193-
impl.Logger.Errorw("bad request", "err", err)
194-
common.WriteJsonResp(w, err, nil, http.StatusBadRequest)
195-
return
196-
}
197-
198191
v := r.URL.Query()
199192
envIdsString := v.Get("envIds")
200193
envIds := make([]int, 0)
@@ -207,16 +200,15 @@ func (impl AppWorkflowRestHandlerImpl) FindAppWorkflow(w http.ResponseWriter, r
207200
}
208201

209202
// RBAC enforcer applying
210-
object := impl.enforcerUtil.GetAppRBACName(app.AppName)
203+
object := impl.enforcerUtil.GetAppRBACNameByAppId(appId)
211204
impl.Logger.Debugw("rbac object for other environment list", "object", object)
212205
ok := impl.enforcerUtil.CheckAppRbacForAppOrJob(token, object, casbin.ActionGet)
213206
if !ok {
214207
common.WriteJsonResp(w, err, "unauthorized user", http.StatusForbidden)
215208
return
216209
}
217-
// RBAC enforcer Ends
218-
workflows := make(map[string]interface{})
219-
workflowsList, err := impl.appWorkflowService.FindAppWorkflows(appId)
210+
//RBAC enforcer Ends
211+
workflowsListResp, appType, err := impl.appWorkflowService.FindAppWorkflowsListResolvedResp(appId)
220212
if err != nil {
221213
impl.Logger.Errorw("error in fetching workflows for app", "err", err)
222214
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
@@ -231,7 +223,7 @@ func (impl AppWorkflowRestHandlerImpl) FindAppWorkflow(w http.ResponseWriter, r
231223
return
232224
}
233225
triggerViewPayload := &bean2.TriggerViewWorkflowConfig{
234-
Workflows: workflowsList,
226+
Workflows: workflowsListResp.Workflows,
235227
CdPipelines: cdPipelineWfData,
236228
}
237229
queryParam := bean2.NewWorkflowsFilterQuery().WithEnvIds(envIds)
@@ -242,12 +234,10 @@ func (impl AppWorkflowRestHandlerImpl) FindAppWorkflow(w http.ResponseWriter, r
242234
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
243235
return
244236
}
245-
workflowsList = response.Workflows
237+
workflowsListResp.Workflows = response.Workflows
246238
}
247239

248-
workflows["appId"] = app.Id
249-
workflows["appName"] = app.AppName
250-
if len(workflowsList) > 0 && app.AppType == helper.Job {
240+
if len(workflowsListResp.Workflows) > 0 && appType == helper.Job {
251241
// RBAC
252242

253243
var workflowNames []string
@@ -256,15 +246,15 @@ func (impl AppWorkflowRestHandlerImpl) FindAppWorkflow(w http.ResponseWriter, r
256246
var rbacObjects []string
257247
workNameObjectMap := make(map[string]bean2.AppWorkflowDto)
258248

259-
for _, workflow := range workflowsList {
249+
for _, workflow := range workflowsListResp.Workflows {
260250
workflowNames = append(workflowNames, workflow.Name)
261251
workflowIds = append(workflowIds, workflow.Id)
262252
}
263253
workflowIdToObjectMap := impl.enforcerUtil.GetAllWorkflowRBACObjectsByAppId(appId, workflowNames, workflowIds)
264254
itr := 0
265255
for _, val := range workflowIdToObjectMap {
266256
rbacObjects = append(rbacObjects, val)
267-
workNameObjectMap[val] = workflowsList[itr]
257+
workNameObjectMap[val] = workflowsListResp.Workflows[itr]
268258
itr++
269259
}
270260

@@ -277,20 +267,8 @@ func (impl AppWorkflowRestHandlerImpl) FindAppWorkflow(w http.ResponseWriter, r
277267
if len(updatedWorkflowList) == 0 {
278268
updatedWorkflowList = []bean2.AppWorkflowDto{}
279269
}
280-
workflows[bean3.Workflows] = updatedWorkflowList
281-
} else if len(workflowsList) > 0 {
282-
workflows[bean3.Workflows] = workflowsList
283-
} else {
284-
workflows[bean3.Workflows] = []bean2.AppWorkflowDto{}
285-
}
286-
isAppLevelGitOpsConfigured, err := impl.chartService.IsGitOpsRepoConfiguredForDevtronApp(appId)
287-
if err != nil && !util.IsErrNoRows(err) {
288-
impl.Logger.Errorw("service err, IsGitOpsRepoConfiguredForDevtronApp", "appId", appId, "envIds", envIds, "err", err)
289-
common.WriteJsonResp(w, err, nil, http.StatusInternalServerError)
290-
return
291270
}
292-
workflows["isGitOpsRepoNotConfigured"] = !isAppLevelGitOpsConfigured
293-
common.WriteJsonResp(w, nil, workflows, http.StatusOK)
271+
common.WriteJsonResp(w, nil, workflowsListResp, http.StatusOK)
294272
}
295273

296274
func (impl AppWorkflowRestHandlerImpl) FindAllWorkflows(w http.ResponseWriter, r *http.Request) {

charts/devtron/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ keywords:
1111
- argocd
1212
- Hyperion
1313
engine: gotpl
14-
version: 0.22.87
14+
version: 0.22.88
1515
sources:
1616
- https://github.com/devtron-labs/charts
1717
dependencies:

charts/devtron/templates/configmap-secret.yaml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,13 @@ metadata:
2929
data:
3030
{{- if $.Values.configs }}
3131
{{ toYaml $.Values.configs | indent 2 }}
32+
{{- end }}
33+
{{- if $.Values.devtronEnterprise.enabled }}
34+
DEVTRON_INSTALLATION_TYPE: "enterprise"
3235
{{- end }}
3336
INSTALLATION_THROUGH_HELM: "True"
3437
DEVTRON_HELM_RELEASE_NAME: {{ $.Release.Name }}
38+
DEVTRON_HELM_RELEASE_NAMESPACE: {{ $.Release.Namespace }}
3539
{{- if and ($.Values.minio.enabled) (not $.Values.configs.BLOB_STORAGE_PROVIDER) }}
3640
BLOB_STORAGE_PROVIDER: "S3"
3741
BLOB_STORAGE_S3_ENDPOINT: "http://devtron-minio.devtroncd:9000"
@@ -302,7 +306,8 @@ metadata:
302306
data:
303307
{{- if $.Values.global.configs }}
304308
{{- toYaml $.Values.global.configs | nindent 2 }}
305-
{{- end }}
309+
{{- end }}
310+
{{- if not $.Values.devtronEnterprise.enabled }}
306311
---
307312
apiVersion: v1
308313
kind: ConfigMap
@@ -317,7 +322,7 @@ data:
317322
{{- if $.Values.global.configs }}
318323
{{- toYaml $.Values.global.configs | nindent 2 }}
319324
{{- end }}
320-
325+
{{- end }}
321326
{{- if $.Values.imagePullSecret }}
322327
{{- if $.Values.imagePullSecret.create }}
323328
---
@@ -356,7 +361,7 @@ metadata:
356361
type: kubernetes.io/dockerconfigjson
357362
data:
358363
.dockerconfigjson: {{ include "imagePullSecret" . }}
359-
364+
{{- if not $.Values.devtronEnterprise.enabled }}
360365
---
361366
apiVersion: v1
362367
kind: Secret
@@ -371,3 +376,4 @@ data:
371376
{{- end }}
372377
{{- end }}
373378
{{- end }}
379+
{{- end }}

charts/devtron/templates/dashboard.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ metadata:
1818
annotations:
1919
"helm.sh/resource-policy": keep
2020
data:
21+
{{- if $.Values.devtronEnterprise.enabled }}
22+
GATEKEEPER_URL: "https://license.devtron.ai/dashboard"
23+
{{- end }}
2124
{{- if .config }}
2225
GA_ENABLED: {{ .config.analytics | default "false" | quote }}
2326
HOTJAR_ENABLED: {{ .config.hotjar | default "false" | quote }}

0 commit comments

Comments
 (0)