sfdx-hardis 7.11.0 → 7.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/defaults/ci/.gitattributes +20 -0
  2. package/defaults/ci/.github/workflows/check-deploy.yml +2 -2
  3. package/defaults/ci/.github/workflows/megalinter.yml +1 -1
  4. package/defaults/ci/.github/workflows/process-deploy.yml +2 -2
  5. package/defaults/ci/Jenkinsfile +241 -131
  6. package/defaults/ci/manifest/package-no-overwrite.xml +11 -1
  7. package/defaults/monitoring/.gitattributes +20 -0
  8. package/defaults/monitoring/Jenkinsfile +283 -0
  9. package/lib/commands/hardis/doc/dora-report.d.ts +27 -0
  10. package/lib/commands/hardis/doc/dora-report.js +1269 -0
  11. package/lib/commands/hardis/doc/dora-report.js.map +1 -0
  12. package/lib/commands/hardis/doc/release-notes.d.ts +11 -0
  13. package/lib/commands/hardis/doc/release-notes.js +305 -0
  14. package/lib/commands/hardis/doc/release-notes.js.map +1 -0
  15. package/lib/commands/hardis/git/pull-requests/extract.js +1 -1
  16. package/lib/commands/hardis/git/pull-requests/extract.js.map +1 -1
  17. package/lib/commands/hardis/org/diagnose/deployments.d.ts +1 -12
  18. package/lib/commands/hardis/org/diagnose/deployments.js +1 -11
  19. package/lib/commands/hardis/org/diagnose/deployments.js.map +1 -1
  20. package/lib/commands/hardis/org/monitor/backup.d.ts +0 -1
  21. package/lib/commands/hardis/org/monitor/backup.js +10 -17
  22. package/lib/commands/hardis/org/monitor/backup.js.map +1 -1
  23. package/lib/commands/hardis/org/select.js +79 -26
  24. package/lib/commands/hardis/org/select.js.map +1 -1
  25. package/lib/commands/hardis/packagexml/remove-managed.d.ts +9 -0
  26. package/lib/commands/hardis/packagexml/remove-managed.js +203 -0
  27. package/lib/commands/hardis/packagexml/remove-managed.js.map +1 -0
  28. package/lib/commands/hardis/packagexml/remove.d.ts +1 -1
  29. package/lib/commands/hardis/packagexml/remove.js +43 -12
  30. package/lib/commands/hardis/packagexml/remove.js.map +1 -1
  31. package/lib/commands/hardis/project/action/update.js +1 -1
  32. package/lib/commands/hardis/project/clean/standarditems.js +11 -4
  33. package/lib/commands/hardis/project/clean/standarditems.js.map +1 -1
  34. package/lib/commands/hardis/project/create.js +62 -20
  35. package/lib/commands/hardis/project/create.js.map +1 -1
  36. package/lib/commands/hardis/project/deploy/quick.js +2 -2
  37. package/lib/commands/hardis/project/deploy/smart.js +8 -7
  38. package/lib/commands/hardis/project/deploy/smart.js.map +1 -1
  39. package/lib/commands/hardis/project/deploy/start.js +2 -2
  40. package/lib/commands/hardis/project/deploy/validate.js +2 -2
  41. package/lib/commands/hardis/source/deploy.js +2 -2
  42. package/lib/commands/hardis/work/backpromote.d.ts +11 -0
  43. package/lib/commands/hardis/work/backpromote.js +209 -0
  44. package/lib/commands/hardis/work/backpromote.js.map +1 -0
  45. package/lib/commands/hardis/work/new.js +60 -17
  46. package/lib/commands/hardis/work/new.js.map +1 -1
  47. package/lib/commands/hardis/work/refresh.d.ts +0 -5
  48. package/lib/commands/hardis/work/refresh.js +9 -152
  49. package/lib/commands/hardis/work/refresh.js.map +1 -1
  50. package/lib/common/aiProvider/promptTemplates/PROMPT_RELEASE_SUMMARY.d.ts +3 -0
  51. package/lib/common/aiProvider/promptTemplates/PROMPT_RELEASE_SUMMARY.js +37 -0
  52. package/lib/common/aiProvider/promptTemplates/PROMPT_RELEASE_SUMMARY.js.map +1 -0
  53. package/lib/common/aiProvider/promptTemplates/index.js +2 -0
  54. package/lib/common/aiProvider/promptTemplates/index.js.map +1 -1
  55. package/lib/common/aiProvider/promptTemplates.d.ts +1 -1
  56. package/lib/common/aiProvider/promptTemplates.js.map +1 -1
  57. package/lib/common/gitProvider/azureDevops.d.ts +3 -4
  58. package/lib/common/gitProvider/azureDevops.js +106 -48
  59. package/lib/common/gitProvider/azureDevops.js.map +1 -1
  60. package/lib/common/gitProvider/bitbucket.d.ts +11 -0
  61. package/lib/common/gitProvider/bitbucket.js +119 -0
  62. package/lib/common/gitProvider/bitbucket.js.map +1 -1
  63. package/lib/common/gitProvider/gitProviderRoot.d.ts +1 -3
  64. package/lib/common/gitProvider/gitProviderRoot.js +1 -1
  65. package/lib/common/gitProvider/gitProviderRoot.js.map +1 -1
  66. package/lib/common/gitProvider/github.d.ts +11 -0
  67. package/lib/common/gitProvider/github.js +149 -1
  68. package/lib/common/gitProvider/github.js.map +1 -1
  69. package/lib/common/gitProvider/gitlab.d.ts +10 -0
  70. package/lib/common/gitProvider/gitlab.js +150 -0
  71. package/lib/common/gitProvider/gitlab.js.map +1 -1
  72. package/lib/common/gitProvider/index.d.ts +3 -0
  73. package/lib/common/gitProvider/index.js +22 -6
  74. package/lib/common/gitProvider/index.js.map +1 -1
  75. package/lib/common/gitProvider/jenkinsUtils.d.ts +41 -0
  76. package/lib/common/gitProvider/jenkinsUtils.js +66 -0
  77. package/lib/common/gitProvider/jenkinsUtils.js.map +1 -0
  78. package/lib/common/metadata-utils/metadataList.js +7 -0
  79. package/lib/common/metadata-utils/metadataList.js.map +1 -1
  80. package/lib/common/notifProvider/types.d.ts +1 -1
  81. package/lib/common/ticketProvider/azureBoardsProvider.js +2 -2
  82. package/lib/common/ticketProvider/azureBoardsProvider.js.map +1 -1
  83. package/lib/common/ticketProvider/jiraProvider.d.ts +16 -0
  84. package/lib/common/ticketProvider/jiraProvider.js +53 -12
  85. package/lib/common/ticketProvider/jiraProvider.js.map +1 -1
  86. package/lib/common/utils/actionUtils.js +1 -1
  87. package/lib/common/utils/authUtils.js +7 -3
  88. package/lib/common/utils/authUtils.js.map +1 -1
  89. package/lib/common/utils/backpromoteUtils.d.ts +76 -0
  90. package/lib/common/utils/backpromoteUtils.js +1115 -0
  91. package/lib/common/utils/backpromoteUtils.js.map +1 -0
  92. package/lib/common/utils/dateUtils.d.ts +1 -0
  93. package/lib/common/utils/dateUtils.js +6 -0
  94. package/lib/common/utils/dateUtils.js.map +1 -0
  95. package/lib/common/utils/deployUtils.d.ts +17 -1
  96. package/lib/common/utils/deployUtils.js +17 -5
  97. package/lib/common/utils/deployUtils.js.map +1 -1
  98. package/lib/common/utils/deploymentActionsStateUtils.d.ts +2 -0
  99. package/lib/common/utils/deploymentActionsStateUtils.js +6 -6
  100. package/lib/common/utils/deploymentActionsStateUtils.js.map +1 -1
  101. package/lib/common/utils/doraUtils.d.ts +45 -0
  102. package/lib/common/utils/doraUtils.js +90 -0
  103. package/lib/common/utils/doraUtils.js.map +1 -0
  104. package/lib/common/utils/filesUtils.d.ts +2 -0
  105. package/lib/common/utils/filesUtils.js +2 -2
  106. package/lib/common/utils/filesUtils.js.map +1 -1
  107. package/lib/common/utils/gitUtils.js +2 -2
  108. package/lib/common/utils/gitUtils.js.map +1 -1
  109. package/lib/common/utils/index.d.ts +0 -1
  110. package/lib/common/utils/index.js +5 -129
  111. package/lib/common/utils/index.js.map +1 -1
  112. package/lib/common/utils/markdownUtils.d.ts +3 -1
  113. package/lib/common/utils/markdownUtils.js +56 -20
  114. package/lib/common/utils/markdownUtils.js.map +1 -1
  115. package/lib/common/utils/orgUtils.d.ts +1 -0
  116. package/lib/common/utils/orgUtils.js +15 -13
  117. package/lib/common/utils/orgUtils.js.map +1 -1
  118. package/lib/common/utils/prePostCommandUtils.js +2 -2
  119. package/lib/common/utils/projectUtils.js +1 -1
  120. package/lib/common/utils/projectUtils.js.map +1 -1
  121. package/lib/common/utils/releaseNotesUtils.d.ts +63 -0
  122. package/lib/common/utils/releaseNotesUtils.js +1013 -0
  123. package/lib/common/utils/releaseNotesUtils.js.map +1 -0
  124. package/lib/common/utils/statsUtils.d.ts +3 -0
  125. package/lib/common/utils/statsUtils.js +20 -0
  126. package/lib/common/utils/statsUtils.js.map +1 -0
  127. package/lib/common/utils/xmlUtils.d.ts +15 -1
  128. package/lib/common/utils/xmlUtils.js +79 -13
  129. package/lib/common/utils/xmlUtils.js.map +1 -1
  130. package/lib/config/index.js +2 -2
  131. package/lib/config/index.js.map +1 -1
  132. package/lib/i18n/de.json +286 -3
  133. package/lib/i18n/en.json +286 -3
  134. package/lib/i18n/es.json +286 -3
  135. package/lib/i18n/fr.json +286 -3
  136. package/lib/i18n/it.json +286 -3
  137. package/lib/i18n/ja.json +286 -3
  138. package/lib/i18n/nl.json +286 -3
  139. package/lib/i18n/pl.json +286 -3
  140. package/lib/i18n/pt-BR.json +286 -3
  141. package/messages/org.md +48 -0
  142. package/oclif.lock +13 -43
  143. package/oclif.manifest.json +2595 -1981
  144. package/package.json +5 -5
@@ -0,0 +1,20 @@
1
+ # =============================================================
2
+ # Salesforce CI/CD - Git attributes
3
+ # Normalize line endings to LF on all platforms.
4
+ # =============================================================
5
+
6
+ # All text files: store as LF
7
+ * text=auto eol=lf
8
+
9
+ # Binary files - no diff, no merge
10
+ *.png binary
11
+ *.jpg binary
12
+ *.jpeg binary
13
+ *.gif binary
14
+ *.ico binary
15
+ *.svg binary
16
+ *.zip binary
17
+ *.jar binary
18
+ *.pdf binary
19
+ *.xlsx binary
20
+ *.docx binary
@@ -33,7 +33,7 @@ jobs:
33
33
  uses: actions/checkout@v4
34
34
  with:
35
35
  persist-credentials: true
36
- token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }}
36
+ token: ${{ secrets.GITHUB_TOKEN }}
37
37
  fetch-depth: 0 # Fetch all branches
38
38
  # Setup node
39
39
  - name: Setup Node
@@ -73,7 +73,7 @@ jobs:
73
73
  ORG_ALIAS: ${{ github.event.pull_request.base.ref }} # Defines the target branch of the PR
74
74
  CONFIG_BRANCH: ${{ github.event.pull_request.base.ref }} # Defines the target branch of the PR
75
75
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
76
- CI_SFDX_HARDIS_GITHUB_PUSH_TOKEN: ${{ secrets.PAT || secrets.GITHUB_TOKEN }}
76
+ CI_SFDX_HARDIS_GITHUB_PUSH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
77
77
  SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }}
78
78
  SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }}
79
79
  SLACK_CHANNEL_ID_INTEGRATION: ${{ secrets.SLACK_CHANNEL_ID_INTEGRATION }}
@@ -66,7 +66,7 @@ jobs:
66
66
  if: steps.ml.outputs.has_updated_sources == 1 && (env.APPLY_FIXES_EVENT == 'all' || env.APPLY_FIXES_EVENT == github.event_name) && env.APPLY_FIXES_MODE == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && !contains(github.event.head_commit.message, 'skip fix')
67
67
  uses: peter-evans/create-pull-request@v6
68
68
  with:
69
- token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }}
69
+ token: ${{ secrets.GITHUB_TOKEN }}
70
70
  commit-message: "[Mega-Linter] Apply linters automatic fixes"
71
71
  title: "[Mega-Linter] Apply linters automatic fixes"
72
72
  labels: bot
@@ -32,7 +32,7 @@ jobs:
32
32
  uses: actions/checkout@v4
33
33
  with:
34
34
  persist-credentials: true
35
- token: ${{ secrets.PAT || secrets.GITHUB_TOKEN }}
35
+ token: ${{ secrets.GITHUB_TOKEN }}
36
36
  fetch-depth: 0
37
37
  # Setup node
38
38
  - name: Setup Node
@@ -75,7 +75,7 @@ jobs:
75
75
  ORG_ALIAS: ${{ env.BRANCH }} # Defines the target branch of the PR
76
76
  CONFIG_BRANCH: ${{ env.BRANCH }} # Defines the target branch of the PR
77
77
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
78
- CI_SFDX_HARDIS_GITHUB_PUSH_TOKEN: ${{ secrets.PAT || secrets.GITHUB_TOKEN }}
78
+ CI_SFDX_HARDIS_GITHUB_PUSH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
79
79
  SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }}
80
80
  SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }}
81
81
  NOTIF_EMAIL_ADDRESS: ${{ secrets.NOTIF_EMAIL_ADDRESS }}
@@ -1,153 +1,263 @@
1
- /* sfdx-hardis CI/CD Pipeline for Jenkins
1
+ // Pipeline for Salesforce CI/CD using sfdx-hardis
2
+ //
3
+ // SETUP (do a CTRL+F on "MANUAL"):
4
+ // 1. In Jenkins, create a Multibranch Pipeline pointing to this repository.
5
+ // Jenkins will automatically discover branches and create one sub-job per branch.
6
+ //
7
+ // 2. Add the following credentials in Jenkins (Manage Jenkins -> Credentials -> global):
8
+ // Required:
9
+ // - SFDX_CLIENT_ID_<BRANCH> : Secret text - Connected App consumer key for each target org
10
+ // - SFDX_CLIENT_KEY_<BRANCH> : Secret text - Private key for each target org
11
+ // Optional - add only the ones you use (missing optional credentials are silently ignored):
12
+ // - SLACK_TOKEN, SLACK_CHANNEL_ID : Slack notifications
13
+ // - NOTIF_EMAIL_ADDRESS : Email notifications
14
+ // - JIRA_HOST, JIRA_EMAIL, JIRA_TOKEN, JIRA_PAT : JIRA integration
15
+ // - ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY : AI auto-fix of deployment errors
16
+ // - GITHUB_TOKEN, CI_SFDX_HARDIS_GITLAB_TOKEN, CI_SFDX_HARDIS_BITBUCKET_TOKEN,
17
+ // CI_SFDX_HARDIS_AZURE_TOKEN : Allow coding agents to push branches and create PRs
18
+ // - SFDX_AUTH_URL_TECHNICAL_ORG : Auth URL for a technical org (e.g. DevHub)
19
+ // Optional credentials use `optional: true` (requires Credentials Binding Plugin >= 1.24).
20
+ // Missing optional credentials are silently ignored - the pipeline will NOT crash.
21
+ //
22
+ // 3. The Docker agent requires Docker to be available on the Jenkins node.
23
+ // The main agent uses hardisgroupcom/sfdx-hardis:latest.
24
+ // MegaLinter runs via `docker run` inside that agent (Docker socket must be mounted).
25
+ //
26
+ // Doc & support: https://sfdx-hardis.cloudity.com/salesforce-ci-cd-setup-integration-jenkins/
2
27
 
3
- You need to do a CTRL+F on "MANUAL" and add your variable instead of example variable
28
+ // MANUAL: List every branch that triggers a real deployment to a Salesforce org
29
+ def DEPLOYMENT_BRANCHES = [
30
+ 'integration', // Example
31
+ 'uat', // Example
32
+ 'preprod', // Example
33
+ 'main', // Example
34
+ ]
4
35
 
5
- */
6
36
  pipeline {
7
- agent any
8
- // MANUAL : Add Environment variable if necessary
37
+
38
+ agent {
39
+ docker {
40
+ // Use sfdx-hardis image - no install step needed
41
+ // If rate limits are reached, use: ghcr.io/hardisgroupcom/sfdx-hardis:latest
42
+ image 'hardisgroupcom/sfdx-hardis:latest'
43
+ // Mount Docker socket so MegaLinter can run as a sibling container
44
+ args '-v /var/run/docker.sock:/var/run/docker.sock --user root'
45
+ }
46
+ }
47
+
48
+ options {
49
+ timeout(time: 120, unit: 'MINUTES')
50
+ disableConcurrentBuilds()
51
+ // Keep build logs for 30 days
52
+ buildDiscarder(logRotator(daysToKeepStr: '30'))
53
+ }
54
+
9
55
  environment {
10
- SFDX_CLIENT_ID_INTEGRATION = credentials('SFDX_CLIENT_ID_INTEGRATION') //Example
11
- SFDX_CLIENT_KEY_INTEGRATION = credentials('SFDX_CLIENT_KEY_INTEGRATION') //Example
12
- SFDX_CLIENT_ID_UAT = credentials('SFDX_CLIENT_ID_UAT') //Example
13
- SFDX_CLIENT_KEY_UAT = credentials('SFDX_CLIENT_KEY_UAT') //Example
14
- SFDX_CLIENT_ID_PREPROD = credentials('SFDX_CLIENT_ID_PREPROD') //Example
15
- SFDX_CLIENT_KEY_PREPROD = credentials('SFDX_CLIENT_KEY_PREPROD') //Example
16
- SFDX_CLIENT_ID_MAIN = credentials('SFDX_CLIENT_ID_MAIN') //Example
17
- SFDX_CLIENT_KEY_MAIN = credentials('SFDX_CLIENT_KEY_MAIN') //Example
18
- SFDX_AUTH_URL_TECHNICAL_ORG = credentials('SFDX_AUTH_URL_TECHNICAL_ORG')
19
- SLACK_TOKEN = credentials('SLACK_TOKEN') // Remove if not used
20
- SLACK_CHANNEL_ID = credentials('SLACK_CHANNEL_ID') // Remove if not used
21
- NOTIF_EMAIL_ADDRESS = credentials('NOTIF_EMAIL_ADDRESS') // Remove if not used
22
- JIRA_HOST = credentials('JIRA_HOST') // Remove if not used
23
- JIRA_EMAIL = credentials('JIRA_EMAIL') // Remove if not used
24
- JIRA_TOKEN = credentials('JIRA_TOKEN') // Remove if not used
25
- JIRA_PAT = credentials('JIRA_PAT') // Remove if not used
26
- // Uncomment to provide API keys for coding agent auto-fix of deployment errors
27
- // ANTHROPIC_API_KEY = credentials('ANTHROPIC_API_KEY')
28
- // OPENAI_API_KEY = credentials('OPENAI_API_KEY')
29
- // GEMINI_API_KEY = credentials('GEMINI_API_KEY')
30
- // Uncomment to customize coding agent behavior
31
- // SFDX_HARDIS_CODING_AGENT_MODEL = "sonnet" // Override the model used by the agent
32
- // SFDX_HARDIS_CODING_AGENT_MAX_TURNS = "30" // Limit the number of agentic turns
33
- // Optional tokens to allow coding agents to git push and create PR/MR
34
- // GITHUB_TOKEN = credentials('GITHUB_TOKEN')
35
- // CI_SFDX_HARDIS_GITLAB_TOKEN = credentials('CI_SFDX_HARDIS_GITLAB_TOKEN')
36
- // CI_SFDX_HARDIS_BITBUCKET_TOKEN = credentials('CI_SFDX_HARDIS_BITBUCKET_TOKEN')
37
- // CI_SFDX_HARDIS_AZURE_TOKEN = credentials('CI_SFDX_HARDIS_AZURE_TOKEN')
38
- CONFIG_BRANCH = "${GIT_BRANCH}"
39
- CI_COMMIT_REF_NAME = "${GIT_BRANCH}"
40
- ORG_ALIAS = "${GIT_BRANCH}"
41
- SFDX_DISABLE_FLOW_DIFF = 'false' // Set to true to disable Flow doc during CI/CD setup
56
+ FORCE_COLOR = '1'
57
+ // Normalize branch name: strip the "origin/" prefix added by Jenkins
58
+ BRANCH_NAME_CLEAN = "${env.BRANCH_NAME ?: env.GIT_BRANCH?.replaceAll('^origin/', '')}"
59
+ CI_COMMIT_REF_NAME = "${BRANCH_NAME_CLEAN}"
60
+ CONFIG_BRANCH = "${BRANCH_NAME_CLEAN}"
61
+ ORG_ALIAS = "${BRANCH_NAME_CLEAN}"
62
+ // Set to true to disable Flow documentation generation during initial CI/CD setup
63
+ SFDX_DISABLE_FLOW_DIFF = 'false'
42
64
  }
43
65
 
44
- //Stage of the job
45
66
  stages {
46
- parallel {
47
- //run megalinter
48
- stage('MegaLinter') {
49
- agent {
50
- docker {
51
- image 'oxsecurity/megalinter:latest'
52
- args "-u root -e VALIDATE_ALL_CODEBASE=true -v ${WORKSPACE}:/tmp/lint --entrypoint=''"
53
- reuseNode true
67
+
68
+ ///////////////////////////////////////////////////////////////////////////////
69
+ // Pull Request: run MegaLinter and Validation in parallel on every PR //
70
+ ///////////////////////////////////////////////////////////////////////////////
71
+ stage('Pull Request Checks') {
72
+ when { changeRequest() }
73
+ parallel {
74
+
75
+ ////////////////////////////////////////////////////////////
76
+ // Run MegaLinter to detect quality and security issues //
77
+ ////////////////////////////////////////////////////////////
78
+ stage('MegaLinter') {
79
+ steps {
80
+ withCredentials([
81
+ // Optional API reporter credentials (omit if unused)
82
+ string(credentialsId: 'NOTIF_API_URL', variable: 'NOTIF_API_URL', optional: true),
83
+ string(credentialsId: 'NOTIF_API_BASIC_AUTH_USERNAME', variable: 'NOTIF_API_BASIC_AUTH_USERNAME', optional: true),
84
+ string(credentialsId: 'NOTIF_API_BASIC_AUTH_PASSWORD', variable: 'NOTIF_API_BASIC_AUTH_PASSWORD', optional: true),
85
+ ]) {
86
+ // Run MegaLinter as a sibling container (Docker socket must be mounted in the agent)
87
+ // All available variables: https://megalinter.io/latest/config-file/
88
+ sh '''
89
+ docker pull oxsecurity/megalinter-salesforce:latest
90
+ docker run --rm \
91
+ -v "${WORKSPACE}:/tmp/lint" \
92
+ -e DEFAULT_WORKSPACE=/tmp/lint \
93
+ -e VALIDATE_ALL_CODEBASE=true \
94
+ -e API_REPORTER=true \
95
+ -e NOTIF_API_URL="${NOTIF_API_URL}" \
96
+ -e NOTIF_API_BASIC_AUTH_USERNAME="${NOTIF_API_BASIC_AUTH_USERNAME}" \
97
+ -e NOTIF_API_BASIC_AUTH_PASSWORD="${NOTIF_API_BASIC_AUTH_PASSWORD}" \
98
+ oxsecurity/megalinter-salesforce:latest || true
99
+ '''
100
+ }
54
101
  }
55
- }
56
- when { changeRequest() }
57
- steps {
58
- sh '/entrypoint.sh'
59
- }
60
- post {
61
- always {
62
- archiveArtifacts allowEmptyArchive: true, artifacts: 'mega-linter.log,megalinter-reports/**/*', defaultExcludes: false, followSymlinks: false
102
+ post {
103
+ always {
104
+ archiveArtifacts allowEmptyArchive: true, artifacts: 'mega-linter.log,megalinter-reports/**/*', defaultExcludes: false, followSymlinks: false
105
+ }
63
106
  }
64
107
  }
65
- }
66
- stage('Validation') {
67
- agent {
68
- docker {
69
- // If rate limits reached, use ghcr.io/hardisgroupcom/sfdx-hardis:latest
70
- image 'hardisgroupcom/sfdx-hardis:latest'
108
+
109
+ ///////////////////////////////////////////////////////////////////////
110
+ // Validate deployment on the target org (check-only, no side-effect) //
111
+ ///////////////////////////////////////////////////////////////////////
112
+ stage('Validation') {
113
+ steps {
114
+ script {
115
+ def currentBranch = env.GIT_BRANCH?.replaceAll('^(refs/heads/|origin/)', '') ?: ''
116
+ if (currentBranch.startsWith('auto-fix/')) {
117
+ // Skip sf hardis commands on auto-fix branches to avoid recursive runs
118
+ echo "[sfdx-hardis] Skipping sf hardis commands on auto-fix branch ${currentBranch}"
119
+ } else {
120
+ withCredentials([
121
+ // ----------------------------------------------------------------
122
+ // MANUAL: Add one pair of credentials per deployment org.
123
+ // The credential ID must match the variable name expected by sfdx-hardis.
124
+ // Examples - duplicate and adapt for each org:
125
+ //
126
+ // string(credentialsId: 'SFDX_CLIENT_ID_INTEGRATION', variable: 'SFDX_CLIENT_ID_INTEGRATION'),
127
+ // string(credentialsId: 'SFDX_CLIENT_KEY_INTEGRATION', variable: 'SFDX_CLIENT_KEY_INTEGRATION'),
128
+ // string(credentialsId: 'SFDX_CLIENT_ID_UAT', variable: 'SFDX_CLIENT_ID_UAT'),
129
+ // string(credentialsId: 'SFDX_CLIENT_KEY_UAT', variable: 'SFDX_CLIENT_KEY_UAT'),
130
+ // string(credentialsId: 'SFDX_CLIENT_ID_PREPROD', variable: 'SFDX_CLIENT_ID_PREPROD'),
131
+ // string(credentialsId: 'SFDX_CLIENT_KEY_PREPROD', variable: 'SFDX_CLIENT_KEY_PREPROD'),
132
+ // string(credentialsId: 'SFDX_CLIENT_ID_MAIN', variable: 'SFDX_CLIENT_ID_MAIN'),
133
+ // string(credentialsId: 'SFDX_CLIENT_KEY_MAIN', variable: 'SFDX_CLIENT_KEY_MAIN'),
134
+ // ----------------------------------------------------------------
135
+ // Technical org auth URL (optional - used for DevHub or scratch org workflows)
136
+ string(credentialsId: 'SFDX_AUTH_URL_TECHNICAL_ORG', variable: 'SFDX_AUTH_URL_TECHNICAL_ORG', optional: true),
137
+ // Notification credentials (optional - pipeline will NOT crash if missing)
138
+ string(credentialsId: 'SLACK_TOKEN', variable: 'SLACK_TOKEN', optional: true),
139
+ string(credentialsId: 'SLACK_CHANNEL_ID', variable: 'SLACK_CHANNEL_ID', optional: true),
140
+ string(credentialsId: 'NOTIF_EMAIL_ADDRESS', variable: 'NOTIF_EMAIL_ADDRESS', optional: true),
141
+ // JIRA integration (optional)
142
+ string(credentialsId: 'JIRA_HOST', variable: 'JIRA_HOST', optional: true),
143
+ string(credentialsId: 'JIRA_EMAIL', variable: 'JIRA_EMAIL', optional: true),
144
+ string(credentialsId: 'JIRA_TOKEN', variable: 'JIRA_TOKEN', optional: true),
145
+ string(credentialsId: 'JIRA_PAT', variable: 'JIRA_PAT', optional: true),
146
+ // AI coding agent credentials (optional - auto-fix deployment errors)
147
+ string(credentialsId: 'ANTHROPIC_API_KEY', variable: 'ANTHROPIC_API_KEY', optional: true),
148
+ string(credentialsId: 'OPENAI_API_KEY', variable: 'OPENAI_API_KEY', optional: true),
149
+ string(credentialsId: 'GEMINI_API_KEY', variable: 'GEMINI_API_KEY', optional: true),
150
+ // Git provider tokens (optional - allow coding agents to push branches and open PRs)
151
+ string(credentialsId: 'GITHUB_TOKEN', variable: 'GITHUB_TOKEN', optional: true),
152
+ string(credentialsId: 'CI_SFDX_HARDIS_GITLAB_TOKEN', variable: 'CI_SFDX_HARDIS_GITLAB_TOKEN', optional: true),
153
+ string(credentialsId: 'CI_SFDX_HARDIS_BITBUCKET_TOKEN', variable: 'CI_SFDX_HARDIS_BITBUCKET_TOKEN', optional: true),
154
+ string(credentialsId: 'CI_SFDX_HARDIS_AZURE_TOKEN', variable: 'CI_SFDX_HARDIS_AZURE_TOKEN', optional: true),
155
+ ]) {
156
+ sh '''
157
+ if [ -n "${GITHUB_TOKEN:-}" ] || [ -n "${CI_SFDX_HARDIS_GITLAB_TOKEN:-}" ] || [ -n "${CI_SFDX_HARDIS_BITBUCKET_TOKEN:-}" ] || [ -n "${CI_SFDX_HARDIS_AZURE_TOKEN:-}" ]; then
158
+ git config user.email "sfdx-hardis-bot@cloudity.com"
159
+ git config user.name "sfdx-hardis Bot"
160
+ echo "[sfdx-hardis] Coding-agent git auth prerequisites found"
161
+ else
162
+ echo "[sfdx-hardis] Skipping coding-agent git auth setup: no provider token variable is set"
163
+ fi
164
+ '''
165
+ sh 'sf hardis:auth:login'
166
+ sh 'sf hardis:project:deploy:smart --check'
167
+ }
168
+ }
169
+ }
71
170
  }
72
- }
73
- when { changeRequest() }
74
- //Validation on the appropriate org
75
- steps {
76
- script {
77
- sh '''
78
- CURRENT_BRANCH=$(echo "${GIT_BRANCH}" | sed -E 's#^refs/heads/##; s#^origin/##')
79
- if [ "${CURRENT_BRANCH#auto-fix/}" != "${CURRENT_BRANCH}" ]; then
80
- echo "[sfdx-hardis] Skipping sf hardis commands on auto-fix branch ${CURRENT_BRANCH}"
81
- exit 0
82
- fi
83
- '''
84
- sh '''
85
- if [ -n "${GITHUB_TOKEN:-}" ] || [ -n "${CI_SFDX_HARDIS_GITLAB_TOKEN:-}" ] || [ -n "${CI_SFDX_HARDIS_BITBUCKET_TOKEN:-}" ] || [ -n "${CI_SFDX_HARDIS_AZURE_TOKEN:-}" ] || [ -n "${SYSTEM_ACCESSTOKEN:-}" ]; then
86
- git config user.email "sfdx-hardis-bot@cloudity.com"
87
- git config user.name "sfdx-hardis Bot"
88
- echo "[sfdx-hardis] Coding-agent git auth prerequisites found"
89
- else
90
- echo "[sfdx-hardis] Skipping coding-agent git auth setup: no provider token variable is set"
91
- fi
92
- '''
93
- sh 'sf hardis:auth:login'
94
- sh 'sf hardis:project:deploy:smart --check'
171
+ post {
172
+ always {
173
+ archiveArtifacts allowEmptyArchive: true, artifacts: 'hardis-report/**', defaultExcludes: false, followSymlinks: false
174
+ }
95
175
  }
96
176
  }
97
- post {
98
- always {
99
- archiveArtifacts allowEmptyArchive: true, artifacts: 'hardis-report', defaultExcludes: false, followSymlinks: false
100
- }
177
+
178
+ } // end parallel Pull Request Checks
179
+ } // end Pull Request Checks
180
+
181
+ /////////////////////////////////////////////////////////////////////////////////
182
+ // Deploy to the target org when a commit lands on a deployment branch //
183
+ /////////////////////////////////////////////////////////////////////////////////
184
+ stage('Deployment') {
185
+ when {
186
+ allOf {
187
+ expression { DEPLOYMENT_BRANCHES.contains(env.BRANCH_NAME_CLEAN) }
188
+ not { changeRequest() }
101
189
  }
102
190
  }
103
- stage('Deployment') {
104
- agent {
105
- docker {
106
- // If rate limits reached, use ghcr.io/hardisgroupcom/sfdx-hardis:latest
107
- image 'hardisgroupcom/sfdx-hardis:latest'
108
- }
109
- }
110
- //MANUAL: add your major branch if necessary
111
- when {
112
- allOf {
113
- anyOf {
114
- branch: 'integration' //Example
115
- branch: 'uat' //Example
116
- branch: 'preprod' //Example
117
- branch: 'main' //Example
118
- };
119
- not { changeRequest() }
120
- }
121
- }
122
- //deploy on the appropriate org
123
- steps {
124
- script {
125
- sh '''
126
- CURRENT_BRANCH=$(echo "${GIT_BRANCH}" | sed -E 's#^refs/heads/##; s#^origin/##')
127
- if [ "${CURRENT_BRANCH#auto-fix/}" != "${CURRENT_BRANCH}" ]; then
128
- echo "[sfdx-hardis] Skipping sf hardis commands on auto-fix branch ${CURRENT_BRANCH}"
129
- exit 0
130
- fi
131
- '''
132
- sh '''
133
- if [ -n "${GITHUB_TOKEN:-}" ] || [ -n "${CI_SFDX_HARDIS_GITLAB_TOKEN:-}" ] || [ -n "${CI_SFDX_HARDIS_BITBUCKET_TOKEN:-}" ] || [ -n "${CI_SFDX_HARDIS_AZURE_TOKEN:-}" ] || [ -n "${SYSTEM_ACCESSTOKEN:-}" ]; then
134
- git config user.email "sfdx-hardis-bot@cloudity.com"
135
- git config user.name "sfdx-hardis Bot"
136
- echo "[sfdx-hardis] Coding-agent git auth prerequisites found"
137
- else
138
- echo "[sfdx-hardis] Skipping coding-agent git auth setup: no provider token variable is set"
139
- fi
140
- '''
141
- sh 'sf hardis:auth:login'
142
- sh 'sf hardis:project:deploy:smart'
191
+ steps {
192
+ script {
193
+ def currentBranch = env.GIT_BRANCH?.replaceAll('^(refs/heads/|origin/)', '') ?: ''
194
+ if (currentBranch.startsWith('auto-fix/')) {
195
+ // Skip sf hardis commands on auto-fix branches to avoid recursive runs
196
+ echo "[sfdx-hardis] Skipping sf hardis commands on auto-fix branch ${currentBranch}"
197
+ } else {
198
+ withCredentials([
199
+ // ----------------------------------------------------------------
200
+ // MANUAL: Add one pair of credentials per deployment org.
201
+ // Same credential pairs as in the Validation stage above.
202
+ //
203
+ // string(credentialsId: 'SFDX_CLIENT_ID_INTEGRATION', variable: 'SFDX_CLIENT_ID_INTEGRATION'),
204
+ // string(credentialsId: 'SFDX_CLIENT_KEY_INTEGRATION', variable: 'SFDX_CLIENT_KEY_INTEGRATION'),
205
+ // string(credentialsId: 'SFDX_CLIENT_ID_UAT', variable: 'SFDX_CLIENT_ID_UAT'),
206
+ // string(credentialsId: 'SFDX_CLIENT_KEY_UAT', variable: 'SFDX_CLIENT_KEY_UAT'),
207
+ // string(credentialsId: 'SFDX_CLIENT_ID_PREPROD', variable: 'SFDX_CLIENT_ID_PREPROD'),
208
+ // string(credentialsId: 'SFDX_CLIENT_KEY_PREPROD', variable: 'SFDX_CLIENT_KEY_PREPROD'),
209
+ // string(credentialsId: 'SFDX_CLIENT_ID_MAIN', variable: 'SFDX_CLIENT_ID_MAIN'),
210
+ // string(credentialsId: 'SFDX_CLIENT_KEY_MAIN', variable: 'SFDX_CLIENT_KEY_MAIN'),
211
+ // ----------------------------------------------------------------
212
+ // Technical org auth URL (optional - used for DevHub or scratch org workflows)
213
+ string(credentialsId: 'SFDX_AUTH_URL_TECHNICAL_ORG', variable: 'SFDX_AUTH_URL_TECHNICAL_ORG', optional: true),
214
+ // Notification credentials (optional - pipeline will NOT crash if missing)
215
+ string(credentialsId: 'SLACK_TOKEN', variable: 'SLACK_TOKEN', optional: true),
216
+ string(credentialsId: 'SLACK_CHANNEL_ID', variable: 'SLACK_CHANNEL_ID', optional: true),
217
+ string(credentialsId: 'NOTIF_EMAIL_ADDRESS', variable: 'NOTIF_EMAIL_ADDRESS', optional: true),
218
+ // JIRA integration (optional)
219
+ string(credentialsId: 'JIRA_HOST', variable: 'JIRA_HOST', optional: true),
220
+ string(credentialsId: 'JIRA_EMAIL', variable: 'JIRA_EMAIL', optional: true),
221
+ string(credentialsId: 'JIRA_TOKEN', variable: 'JIRA_TOKEN', optional: true),
222
+ string(credentialsId: 'JIRA_PAT', variable: 'JIRA_PAT', optional: true),
223
+ // AI coding agent credentials (optional - auto-fix deployment errors)
224
+ string(credentialsId: 'ANTHROPIC_API_KEY', variable: 'ANTHROPIC_API_KEY', optional: true),
225
+ string(credentialsId: 'OPENAI_API_KEY', variable: 'OPENAI_API_KEY', optional: true),
226
+ string(credentialsId: 'GEMINI_API_KEY', variable: 'GEMINI_API_KEY', optional: true),
227
+ // Git provider tokens (optional - allow coding agents to push branches and open PRs)
228
+ string(credentialsId: 'GITHUB_TOKEN', variable: 'GITHUB_TOKEN', optional: true),
229
+ string(credentialsId: 'CI_SFDX_HARDIS_GITLAB_TOKEN', variable: 'CI_SFDX_HARDIS_GITLAB_TOKEN', optional: true),
230
+ string(credentialsId: 'CI_SFDX_HARDIS_BITBUCKET_TOKEN', variable: 'CI_SFDX_HARDIS_BITBUCKET_TOKEN', optional: true),
231
+ string(credentialsId: 'CI_SFDX_HARDIS_AZURE_TOKEN', variable: 'CI_SFDX_HARDIS_AZURE_TOKEN', optional: true),
232
+ ]) {
233
+ sh '''
234
+ if [ -n "${GITHUB_TOKEN:-}" ] || [ -n "${CI_SFDX_HARDIS_GITLAB_TOKEN:-}" ] || [ -n "${CI_SFDX_HARDIS_BITBUCKET_TOKEN:-}" ] || [ -n "${CI_SFDX_HARDIS_AZURE_TOKEN:-}" ]; then
235
+ git config user.email "sfdx-hardis-bot@cloudity.com"
236
+ git config user.name "sfdx-hardis Bot"
237
+ echo "[sfdx-hardis] Coding-agent git auth prerequisites found"
238
+ else
239
+ echo "[sfdx-hardis] Skipping coding-agent git auth setup: no provider token variable is set"
240
+ fi
241
+ '''
242
+ sh 'sf hardis:auth:login'
243
+ sh 'sf hardis:project:deploy:smart'
244
+ }
143
245
  }
144
246
  }
145
- post {
146
- always {
147
- archiveArtifacts allowEmptyArchive: true, artifacts: 'hardis-report', defaultExcludes: false, followSymlinks: false
148
- }
247
+ }
248
+ post {
249
+ always {
250
+ archiveArtifacts allowEmptyArchive: true, artifacts: 'hardis-report/**', defaultExcludes: false, followSymlinks: false
149
251
  }
150
252
  }
151
253
  }
254
+
255
+ } // end stages
256
+
257
+ post {
258
+ always {
259
+ cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenSuccess: true)
260
+ }
152
261
  }
262
+
153
263
  }
@@ -15,6 +15,11 @@
15
15
  <members>*</members>
16
16
  <name>ConnectedApp</name>
17
17
  </types>
18
+ <!-- External Client Apps (API 59.0+): OAuth consumer key and secret are org-specific and must never be overwritten -->
19
+ <types>
20
+ <members>*</members>
21
+ <name>ExtlClntAppGlobalOauthSettings</name>
22
+ </types>
18
23
  <types>
19
24
  <!-- Once a dashboard is published, it is always managed directly in production -->
20
25
  <members>*</members>
@@ -25,8 +30,13 @@
25
30
  <members>*</members>
26
31
  <name>FlowDefinition</name>
27
32
  </types>
33
+ <!-- External Credentials (Named Credentials v2, API 57.0+): auth protocol and named principals are org-specific -->
34
+ <types>
35
+ <members>*</members>
36
+ <name>ExternalCredential</name>
37
+ </types>
28
38
  <types>
29
- <!-- Name Credentials can contain auth info that are different between dev, uat, preprod and prod: let's not overwrite them ! -->
39
+ <!-- Named Credentials can contain auth info that differs between dev, uat, preprod and prod: let's not overwrite them ! -->
30
40
  <members>*</members>
31
41
  <name>NamedCredential</name>
32
42
  </types>
@@ -0,0 +1,20 @@
1
+ # =============================================================
2
+ # Salesforce Monitoring - Git attributes
3
+ # Normalize line endings to LF on all platforms.
4
+ # =============================================================
5
+
6
+ # All text files: store as LF
7
+ * text=auto eol=lf
8
+
9
+ # Binary files - no diff, no merge
10
+ *.png binary
11
+ *.jpg binary
12
+ *.jpeg binary
13
+ *.gif binary
14
+ *.ico binary
15
+ *.svg binary
16
+ *.zip binary
17
+ *.jar binary
18
+ *.pdf binary
19
+ *.xlsx binary
20
+ *.docx binary