sfdx-git-delta 4.12.0 → 5.0.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.
- package/CHANGELOG.md +30 -0
- package/README.md +176 -120
- package/lib/commands/sgd/source/delta.js +8 -8
- package/lib/commands/sgd/source/delta.js.map +1 -1
- package/lib/main.d.ts +2 -2
- package/lib/main.js +16 -18
- package/lib/main.js.map +1 -1
- package/lib/metadata/metadataManager.d.ts +1 -1
- package/lib/metadata/metadataManager.js +8 -8
- package/lib/metadata/metadataManager.js.map +1 -1
- package/lib/metadata/v54.json +1321 -0
- package/lib/service/botHandler.js +9 -9
- package/lib/service/botHandler.js.map +1 -1
- package/lib/service/customObjectHandler.d.ts +1 -1
- package/lib/service/customObjectHandler.js +21 -17
- package/lib/service/customObjectHandler.js.map +1 -1
- package/lib/service/inFileHandler.d.ts +5 -5
- package/lib/service/inFileHandler.js +34 -34
- package/lib/service/inFileHandler.js.map +1 -1
- package/lib/service/inFolderHandler.js +11 -13
- package/lib/service/inFolderHandler.js.map +1 -1
- package/lib/service/inResourceHandler.d.ts +1 -1
- package/lib/service/inResourceHandler.js +22 -22
- package/lib/service/inResourceHandler.js.map +1 -1
- package/lib/service/inTranslationHandler.js +6 -6
- package/lib/service/inTranslationHandler.js.map +1 -1
- package/lib/service/standardHandler.d.ts +10 -10
- package/lib/service/standardHandler.js +46 -29
- package/lib/service/standardHandler.js.map +1 -1
- package/lib/service/subCustomObjectHandler.js +9 -9
- package/lib/service/subCustomObjectHandler.js.map +1 -1
- package/lib/service/typeHandlerFactory.js +2 -2
- package/lib/service/typeHandlerFactory.js.map +1 -1
- package/lib/service/waveHandler.js +2 -2
- package/lib/service/waveHandler.js.map +1 -1
- package/lib/utils/asyncFilter.d.ts +2 -0
- package/lib/utils/asyncFilter.js +3 -0
- package/lib/utils/asyncFilter.js.map +1 -0
- package/lib/utils/childProcessUtils.d.ts +2 -2
- package/lib/utils/childProcessUtils.js +21 -9
- package/lib/utils/childProcessUtils.js.map +1 -1
- package/lib/utils/cliHelper.d.ts +4 -2
- package/lib/utils/cliHelper.js +51 -23
- package/lib/utils/cliHelper.js.map +1 -1
- package/lib/utils/fileGitDiff.d.ts +1 -1
- package/lib/utils/fileGitDiff.js +7 -7
- package/lib/utils/fileGitDiff.js.map +1 -1
- package/lib/utils/packageConstructor.js +11 -4
- package/lib/utils/packageConstructor.js.map +1 -1
- package/lib/utils/repoGitDiff.d.ts +19 -5
- package/lib/utils/repoGitDiff.js +83 -51
- package/lib/utils/repoGitDiff.js.map +1 -1
- package/lib/utils/repoSetup.d.ts +6 -3
- package/lib/utils/repoSetup.js +17 -20
- package/lib/utils/repoSetup.js.map +1 -1
- package/lib/utils/typeUtils.js +3 -3
- package/lib/utils/typeUtils.js.map +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +10 -14
- package/bin/cli +0 -57
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [5.0.1](https://github.com/scolladon/sfdx-git-delta/compare/v5.0.0...v5.0.1) (2022-03-16)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* path resolution for master detail fields ([#264](https://github.com/scolladon/sfdx-git-delta/issues/264)) ([5aa12c1](https://github.com/scolladon/sfdx-git-delta/commit/5aa12c1573a79aadb3495083d217d0cbb28e24d3))
|
|
11
|
+
|
|
12
|
+
## [5.0.0](https://github.com/scolladon/sfdx-git-delta/compare/v4.12.1...v5.0.0) (2022-03-11)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### ⚠ BREAKING CHANGES
|
|
16
|
+
|
|
17
|
+
* sgd single node executable is not shipped anymore
|
|
18
|
+
|
|
19
|
+
### Features
|
|
20
|
+
|
|
21
|
+
* decommissionate sgd ([#221](https://github.com/scolladon/sfdx-git-delta/issues/221)) ([ecd146f](https://github.com/scolladon/sfdx-git-delta/commit/ecd146f0e6480f68bbf08362e3a535c7f0fe24ba))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Bug Fixes
|
|
25
|
+
|
|
26
|
+
* pull request CI base commit ([#253](https://github.com/scolladon/sfdx-git-delta/issues/253)) ([163ee52](https://github.com/scolladon/sfdx-git-delta/commit/163ee5245ce79bbcb44323bfb249b7437d88c51c))
|
|
27
|
+
|
|
28
|
+
### [4.12.1](https://github.com/scolladon/sfdx-git-delta/compare/v4.12.0...v4.12.1) (2022-01-05)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Bug Fixes
|
|
32
|
+
|
|
33
|
+
* spawn buffer size ([#236](https://github.com/scolladon/sfdx-git-delta/issues/236)) ([9944c43](https://github.com/scolladon/sfdx-git-delta/commit/9944c43a470c53fd3796e8d9f79f55a205695f2b))
|
|
34
|
+
|
|
5
35
|
## [4.12.0](https://github.com/scolladon/sfdx-git-delta/compare/v4.11.0...v4.12.0) (2021-12-17)
|
|
6
36
|
|
|
7
37
|
|
package/README.md
CHANGED
|
@@ -1,8 +1,58 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+

|
|
2
|
+
[](https://badgen.net/npm/v/sfdx-git-delta)
|
|
3
|
+
[](https://codeclimate.com/github/scolladon/sfdx-git-delta/maintainability)
|
|
4
|
+
[](https://codecov.io/gh/scolladon/sfdx-git-delta)
|
|
5
|
+
[](https://snyk.io//test/github/scolladon/sfdx-git-delta?targetFile=package.json)
|
|
6
|
+
[](https://badgen.net/npm/dw/sfdx-git-delta)
|
|
7
|
+
[](https://gitter.im/sfdx-git-delta/community)
|
|
8
|
+
|
|
9
|
+
<br />
|
|
10
|
+
<div align="center">
|
|
11
|
+
|
|
12
|
+
<h3 align="center">SFDX-Git-Delta </h3>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
Generate salesforce deployment content from two git commits!
|
|
16
|
+
<br />
|
|
17
|
+
<a href="https://github.com/scolladon/sfdx-git-delta/issues/new?assignees=scolladon&labels=bug&template=issue.md">Report Bug</a>
|
|
18
|
+
·
|
|
19
|
+
<a href="https://github.com/scolladon/sfdx-git-delta/issues/new?assignees=scolladon&labels=enhancement&template=enhancement.md">Request Feature</a>
|
|
20
|
+
</p>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<!-- TABLE OF CONTENTS -->
|
|
24
|
+
<details>
|
|
25
|
+
<summary>Table of Contents</summary>
|
|
26
|
+
|
|
27
|
+
- [TL;DR;](#tldr)
|
|
28
|
+
- [What is SFDX-Git-Delta?](#what-is-sfdx-git-delta)
|
|
29
|
+
- [Is SGD for you?](#is-sgd-for-you)
|
|
30
|
+
- [Getting Started](#getting-started)
|
|
31
|
+
- [Prerequisites](#prerequisites)
|
|
32
|
+
- [Installation](#installation)
|
|
33
|
+
- [How to use it?](#how-to-use-it)
|
|
34
|
+
- [`sfdx sgd:source:delta -f <string> [-t <string>] [-r <filepath>] [-i <filepath>] [-D <filepath>] [-s <filepath>] [-W] [-o <filepath>] [-a <number>] [-d] [-n <filepath>] [-N <filepath>] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]`](#sfdx-sgdsourcedelta--f-string--t-string--r-filepath--i-filepath--d-filepath--s-filepath--w--o-filepath--a-number--d--n-filepath--n-filepath---json---loglevel-tracedebuginfowarnerrorfataltracedebuginfowarnerrorfatal)
|
|
35
|
+
- [Windows users](#windows-users)
|
|
36
|
+
- [Use cases](#use-cases)
|
|
37
|
+
- [Walkthrough](#walkthrough)
|
|
38
|
+
- [Execute sgd](#execute-sgd)
|
|
39
|
+
- [Deploy the delta metadata](#deploy-the-delta-metadata)
|
|
40
|
+
- [Advanced use-cases:](#advanced-use-cases)
|
|
41
|
+
- [Generate a folder containing only the added/modified sources:](#generate-a-folder-containing-only-the-addedmodified-sources)
|
|
42
|
+
- [Exclude some metadata only from destructiveChanges.xml:](#exclude-some-metadata-only-from-destructivechangesxml)
|
|
43
|
+
- [Explicitly including specific files for inclusion or destruction regardless of diff:](#explicitly-including-specific-files-for-inclusion-or-destruction-regardless-of-diff)
|
|
44
|
+
- [Scoping delta generation to a specific folder](#scoping-delta-generation-to-a-specific-folder)
|
|
45
|
+
- [Generate a comma-separated list of the added and modified Apex classes:](#generate-a-comma-separated-list-of-the-added-and-modified-apex-classes)
|
|
46
|
+
- [Use the module in your own node application](#use-the-module-in-your-own-node-application)
|
|
47
|
+
- [Changelog](#changelog)
|
|
48
|
+
- [Built With](#built-with)
|
|
49
|
+
- [Versioning](#versioning)
|
|
50
|
+
- [Authors](#authors)
|
|
51
|
+
- [Contributing](#contributing)
|
|
52
|
+
- [License](#license)
|
|
53
|
+
</details>
|
|
54
|
+
|
|
55
|
+
## TL;DR
|
|
6
56
|
|
|
7
57
|
```sh
|
|
8
58
|
sfdx plugins:install sfdx-git-delta
|
|
@@ -13,29 +63,18 @@ sfdx sgd:source:delta --to "HEAD" --from "HEAD^" --output "."
|
|
|
13
63
|
```
|
|
14
64
|
|
|
15
65
|
```sh
|
|
16
|
-
|
|
17
|
-
cat package/package.xml
|
|
18
|
-
echo
|
|
19
|
-
echo "---- Deploying added and modified metadata ----"
|
|
20
|
-
sfdx force:source:deploy -x package/package.xml
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
```sh
|
|
24
|
-
echo "--- destructiveChanges.xml generated with deleted metadata ---"
|
|
25
|
-
cat destructiveChanges/destructiveChanges.xml
|
|
26
|
-
echo
|
|
27
|
-
echo "--- Deleting removed metadata ---"
|
|
28
|
-
sfdx force:mdapi:deploy -d destructiveChanges --ignorewarnings
|
|
66
|
+
sfdx force:source:deploy -x package/package.xml --postdestructivechanges destructiveChanges/destructiveChanges.xml
|
|
29
67
|
```
|
|
30
68
|
|
|
31
69
|
## What is SFDX-Git-Delta?
|
|
32
70
|
|
|
33
|
-
**SFDX-Git-Delta** (
|
|
71
|
+
**SFDX-Git-Delta** (_a.k.a. **SGD**_) helps Salesforce Architects and Developers do 2 things with their source deployments:
|
|
34
72
|
|
|
35
|
-
|
|
36
|
-
2. **Automate destructive deployments**, by listing the deleted (or renamed) metadata in a destructiveChanges.xml
|
|
73
|
+
- **Make deployments faster**: identify the changed metadata since a reference commit.
|
|
37
74
|
|
|
38
|
-
|
|
75
|
+
- **Automate destructive deployments**: build the destructiveChanges.xml from the deleted (or renamed) metadata
|
|
76
|
+
|
|
77
|
+
Have a look at this post on the Salesforce Developers Blog to dive into it: [Optimizing Unpackaged Deployments Using a Delta Generation Tool](https://developer.salesforce.com/blogs/2021/01/optimizing-unpackaged-deployments-using-a-delta-generation-tool.html).
|
|
39
78
|
|
|
40
79
|

|
|
41
80
|
|
|
@@ -43,17 +82,16 @@ To get a better understanding of what SGD is for, take a look at this post on th
|
|
|
43
82
|
|
|
44
83
|
If you are not a Salesforce Architect or Developer, probably not, _sorry_.
|
|
45
84
|
|
|
46
|
-
If you are a Technical Architect or Developer, then it’s a very useful tool for you, when
|
|
85
|
+
If you are a Technical Architect or Developer, then it’s a very useful tool for you, when meting 3 conditions below:
|
|
47
86
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
➕
|
|
52
|
-
Your metadata is not packaged (in other words, your repo contains all the unmanaged metadata of the project).
|
|
87
|
+
1. Your Salesforce project uses a git repo as the source of truth.
|
|
88
|
+
2. You use the Source (DX) format in the repo.
|
|
89
|
+
3. Your metadata is unmanaged (in other words, you are not building a managed or unlocked package).
|
|
53
90
|
|
|
54
91
|
SGD is designed to be part of a CI/CD pipeline (Jenkins, Bitbucket Pipelines, GitLab CI, GitHub Actions, Azure DevOps...) that handles the deployment of the sources to the Salesforce org(s).
|
|
55
92
|
|
|
56
|
-
Pro
|
|
93
|
+
Pro tip: Make sure your pipeline works **before** implementing delta deployments. Otherwise it will just make it harder to debug your pipeline.
|
|
94
|
+
It's also important to implement a way to switch back to full deployment in case the delta deployment does not behave as expected.
|
|
57
95
|
|
|
58
96
|
**DISCLAIMER:**
|
|
59
97
|
|
|
@@ -61,9 +99,18 @@ Pro tips: If you are in the process of building your CI/CD pipeline, make sure y
|
|
|
61
99
|
|
|
62
100
|
👷 Use it at your own risk, wear a helmet, and test it first before adding it to your pipeline 🔥
|
|
63
101
|
|
|
64
|
-
##
|
|
102
|
+
## Getting Started
|
|
103
|
+
|
|
104
|
+
### Prerequisites
|
|
105
|
+
|
|
106
|
+
The plugin requires git command line on the running environment.
|
|
65
107
|
|
|
66
|
-
|
|
108
|
+
**Node v14.6.0 or above is required**.
|
|
109
|
+
To check if Salesforce CLI runs under a supported node version for SGD, run `sfdx --version`. You should see a node version above v.14.6.0 to use SGD.
|
|
110
|
+
|
|
111
|
+
If you encounter this issue whereas the node version is OK on the running environment, try to [install the Salesforce CLI via npm](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_install_cli.htm#sfdx_setup_install_cli_npm) (`npm install sfdx-cli --global`).
|
|
112
|
+
|
|
113
|
+
### Installation
|
|
67
114
|
|
|
68
115
|
SGD is a Salesforce CLI plugin (`sfdx sgd:source:delta`). Run the following command to install it:
|
|
69
116
|
|
|
@@ -73,17 +120,9 @@ sfdx plugins:install sfdx-git-delta
|
|
|
73
120
|
|
|
74
121
|
Because this plugin is not signed, you will get a warning saying that "This plugin is not digitally signed and its authenticity cannot be verified". This is expected, and you will have to answer `y` (yes) to proceed with the installation.
|
|
75
122
|
|
|
76
|
-
If you run your CI/CD jobs inside a Docker image, you can add the plugin to your image
|
|
77
|
-
|
|
78
|
-
⚠️ The Salesforce CLI plugin is now the only supported way to install SGD. There used to be another way to install it directly through yarn or npm. The legacy `sgd` command is now deprecated and will be decommissioned soon.
|
|
79
|
-
|
|
80
|
-
### Prerequisites
|
|
81
|
-
|
|
82
|
-
Git command line is required on the system where the command line is running.
|
|
123
|
+
If you run your CI/CD jobs inside a Docker image, you can add the plugin to your image (such as in [this example](https://github.com/mehdisfdc/sfdx-cli-gitlab)).
|
|
83
124
|
|
|
84
|
-
|
|
85
|
-
To make sure that the Salesforce CLI is using the expected node version for SGD, run `sfdx --version` before attempting to install the SGD plugin: if you see a node version below v14.6.0 in the output, you'll need to fix it first.
|
|
86
|
-
If you encounter this issue while having installed the correct version of node on your system, try to [install the Salesforce CLI via npm](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_install_cli.htm#sfdx_setup_install_cli_npm) (`npm install sfdx-cli --global`) rather than with another installer.
|
|
125
|
+
⚠️ The Salesforce CLI plugin is now the only supported way to install SGD. There used to be another way to install it using yarn or npm. The legacy `sgd` command is now deprecated and decommissioned.
|
|
87
126
|
|
|
88
127
|
## How to use it?
|
|
89
128
|
|
|
@@ -110,7 +149,7 @@ OPTIONS
|
|
|
110
149
|
-W, --ignore-whitespace ignore git diff whitespace (space,
|
|
111
150
|
tab, eol) changes
|
|
112
151
|
|
|
113
|
-
-a, --api-version=api-version [default:
|
|
152
|
+
-a, --api-version=api-version [default: 54] salesforce API version
|
|
114
153
|
|
|
115
154
|
-d, --generate-delta generate delta files in [--output]
|
|
116
155
|
folder
|
|
@@ -142,20 +181,47 @@ OPTIONS
|
|
|
142
181
|
this command invocation
|
|
143
182
|
```
|
|
144
183
|
|
|
145
|
-
_See code: [src/commands/sgd/source/delta.ts](https://github.com/scolladon/sfdx-git-delta/blob/
|
|
184
|
+
_See code: [src/commands/sgd/source/delta.ts](https://github.com/scolladon/sfdx-git-delta/blob/v5.0.1/src/commands/sgd/source/delta.ts)_
|
|
146
185
|
<!-- commandsstop -->
|
|
147
186
|
|
|
148
|
-
###
|
|
187
|
+
### Windows users
|
|
188
|
+
|
|
189
|
+
If you run SGD on a Windows system, use double quotes [to prevent the terminal to interpret parameters](https://github.com/scolladon/sfdx-git-delta/issues/134)
|
|
190
|
+
|
|
191
|
+
### Use cases
|
|
149
192
|
|
|
150
|
-
|
|
193
|
+
Any git sha pointer is supported: commit sha, branch, tag, git expression (HEAD, etc.).
|
|
151
194
|
|
|
152
|
-
|
|
195
|
+
Here are examples of how to compare the content of different branches:
|
|
196
|
+
|
|
197
|
+
- **Comparing between commits in different branches**
|
|
198
|
+
For example, if you have commit `fbc3ade6` in branch `develop` and commit `61f235b1` in branch `main`:
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
sfdx sgd:source:delta --to fbc3ade6 --from 61f235b1 --output .
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
- **Comparing branches (all changes)**
|
|
205
|
+
Comparing all changes between the `develop` branch and the `main` branch:
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
sfdx sgd:source:delta --to develop --from main --output .
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
- **Comparing branches (from a common ancestor)**
|
|
212
|
+
To compare the `develop` branch since its common ancestor with the `main` branch (i.e. ignoring the changes performed in the `main` branch after `develop` creation):
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
sfdx sgd:source:delta --to develop --from $(git merge-base develop main) --output .
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Walkthrough
|
|
153
219
|
|
|
154
220
|
Let’s take a look at the following scenario:
|
|
155
221
|
|
|
156
|
-
> **_The CI pipelines deploys the sources to Production anytime there is a new commit in the
|
|
222
|
+
> **_The CI pipelines deploys the sources to Production anytime there is a new commit in the main branch._**
|
|
157
223
|
|
|
158
|
-
In our example, the latest commit to
|
|
224
|
+
In our example, the latest commit to main is composed of:
|
|
159
225
|
|
|
160
226
|
- _Apex Class added:_ TriggerHandler
|
|
161
227
|
- _Apex Class added:_ TriggerHandler_Test
|
|
@@ -167,11 +233,11 @@ In our example, the latest commit to master is composed of:
|
|
|
167
233
|
In this situation, we would expect the CI pipeline to:
|
|
168
234
|
|
|
169
235
|
1. **Deploy to Production only 3 classes** (no matter how much metadata is present in the force-app folder): `TriggerHandler`, `TriggerHandler_Test`, and `TestDataFactory`
|
|
170
|
-
2. **Delete from Production 1
|
|
236
|
+
2. **Delete from Production 1 class**: `AnotherTriggerFramework`
|
|
171
237
|
|
|
172
238
|
So let’s do it!
|
|
173
239
|
|
|
174
|
-
###
|
|
240
|
+
### Execute sgd
|
|
175
241
|
|
|
176
242
|
From the project repo folder, the CI pipeline will run the following command:
|
|
177
243
|
|
|
@@ -185,21 +251,33 @@ which means:
|
|
|
185
251
|
|
|
186
252
|
The `sfdx sgd:source:delta` command produces 2 usefull artifacts:
|
|
187
253
|
|
|
188
|
-
**1) A `package.xml` file, inside a `package` folder.** This `package.xml` file contains
|
|
254
|
+
**1) A `package.xml` file, inside a `package` folder.** This `package.xml` file contains just the added/changed metadata to deploy to the target org.
|
|
189
255
|
|
|
190
256
|
_Content of the `package.xml` file in our scenario:_
|
|
191
257
|

|
|
192
258
|
|
|
193
|
-
**2) A `destructiveChanges.xml` file, inside a `destructiveChanges` folder.** This `destructiveChanges.xml` file contains
|
|
259
|
+
**2) A `destructiveChanges.xml` file, inside a `destructiveChanges` folder.** This `destructiveChanges.xml` file contains just the removed/renamed metadata to delete from the target org. Note: the `destructiveChanges` folder also contains a minimal package.xml file, because deploying destructive changes requires a package.xml (even an empty one).
|
|
194
260
|
|
|
195
261
|
_Content of the `destructiveChanges.xml` file in our scenario:_
|
|
196
262
|

|
|
197
263
|
|
|
198
|
-
|
|
264
|
+
Note: it is also possible to generate a **source** folder containing added/changed metadata with the [`--generate-delta (-d)`](#scoping-delta-generation-to-a-specific-folder) parameter. See the "Advanced use-cases" section for more examples.
|
|
199
265
|
|
|
200
|
-
### Deploy
|
|
266
|
+
### Deploy the delta metadata
|
|
201
267
|
|
|
202
|
-
The
|
|
268
|
+
The simplest option to deploy the delta changes is to use `force:source:deploy`:
|
|
269
|
+
|
|
270
|
+
```sh
|
|
271
|
+
sfdx force:source:deploy -x package/package.xml --postdestructivechanges destructiveChanges/destructiveChanges.xml
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
And voilà! 🥳
|
|
275
|
+
|
|
276
|
+
However, keep in mind thate the above command will fail if the destructive change was supposed to be executed before the deployment (i.e. as `--predestructivechanges`), or if a warning occurs during deployment. Make sure to protect your CI/CD pipeline from those scenarios, so that it don't get stuck by a failed destructive change.
|
|
277
|
+
|
|
278
|
+
If needed, you can also split the added/modified metadata deployment from the deleted/renamed metadata deployment, as in the below examples:
|
|
279
|
+
|
|
280
|
+
Use the `package/package.xml` file to deploy only the added/modified metadata:
|
|
203
281
|
|
|
204
282
|
```sh
|
|
205
283
|
echo "--- package.xml generated with added and modified metadata ---"
|
|
@@ -209,9 +287,7 @@ echo "---- Deploying added and modified metadata ----"
|
|
|
209
287
|
sfdx force:source:deploy -x package/package.xml
|
|
210
288
|
```
|
|
211
289
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
The CI pipeline can use the `destructiveChanges` folder to deploy the corresponding destructive change:
|
|
290
|
+
Use the `destructiveChanges` folder to deploy only the destructive changes:
|
|
215
291
|
|
|
216
292
|
```sh
|
|
217
293
|
echo "--- destructiveChanges.xml generated with deleted metadata ---"
|
|
@@ -221,42 +297,13 @@ echo "--- Deleting removed metadata ---"
|
|
|
221
297
|
sfdx force:mdapi:deploy -d destructiveChanges --ignorewarnings
|
|
222
298
|
```
|
|
223
299
|
|
|
224
|
-
And voilà! 🥳
|
|
225
|
-
|
|
226
|
-
### Diff between branches:
|
|
227
|
-
|
|
228
|
-
SGD works with any git sha pointer: commit sha, branch, tag, git expression (HEAD, etc.).
|
|
229
|
-
|
|
230
|
-
Here are 3 examples showing how you can compare the content of different branches:
|
|
231
|
-
|
|
232
|
-
**1) Comparing between commits in different branches**
|
|
233
|
-
For example, if you have commit `fbc3ade6` in branch `develop` and commit `61f235b1` in branch `master`:
|
|
234
|
-
|
|
235
|
-
```
|
|
236
|
-
sfdx sgd:source:delta --to fbc3ade6 --from 61f235b1 --output .
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
**2) Comparing branches (all changes)**
|
|
240
|
-
Comparing all changes between the `develop` branch and the `master` branch:
|
|
241
|
-
|
|
242
|
-
```
|
|
243
|
-
sfdx sgd:source:delta --to develop --from master --output .
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
**3) Comparing branches (from a common ancestor)**
|
|
247
|
-
Comparing changes performed in the `develop` branch since its common ancestor with the `master` branch (i.e. ignoring the changes performed in the `master` branch after `develop` was created):
|
|
248
|
-
|
|
249
|
-
```
|
|
250
|
-
sfdx sgd:source:delta --to develop --from $(git merge-base develop master) --output .
|
|
251
|
-
```
|
|
252
|
-
|
|
253
300
|
## Advanced use-cases:
|
|
254
301
|
|
|
255
302
|
### Generate a folder containing only the added/modified sources:
|
|
256
303
|
|
|
257
|
-
Using a package.xml
|
|
304
|
+
Using a package.xml for deployment is the simplest approach to delta deployments. But in some cases you may want to have only the actual recently changed source files.
|
|
258
305
|
|
|
259
|
-
One example is to speed up object deployments: the package.xml approach will
|
|
306
|
+
One example is to speed up object deployments: the package.xml approach will deploy the entire sub-folder for a given object. Having a copy of the actual sources added/modified allows you to deploy only those components.
|
|
260
307
|
|
|
261
308
|
This is where the `--generate-delta (-d)` option comes handy!
|
|
262
309
|
|
|
@@ -267,17 +314,17 @@ mkdir changed-sources
|
|
|
267
314
|
sfdx sgd:source:delta --to "HEAD" --from "HEAD^" --output changed-sources/ --generate-delta
|
|
268
315
|
```
|
|
269
316
|
|
|
270
|
-
|
|
317
|
+
It generates the `package` and `destructiveChanges` folders, and copies added/changed files in the output folder.
|
|
271
318
|
|
|
272
319
|
_Content of the output folder when using the --generate-delta option, with the same scenario as above:_
|
|
273
320
|
|
|
274
321
|

|
|
275
322
|
|
|
276
|
-
> ⚠️
|
|
277
|
-
> If you need to use it with `--to (-t)` pointing to another commit than "HEAD",
|
|
323
|
+
> ⚠️ Use `--generate-delta (-d)` when `--to (-t)` value is set to "HEAD" or to the "HEAD commit SHA".
|
|
324
|
+
> If you need to use it with `--to (-t)` pointing to another commit than "HEAD", checkout that commit first. Exemple:
|
|
278
325
|
>
|
|
279
326
|
> ```sh
|
|
280
|
-
> # move HEAD to past commit
|
|
327
|
+
> # move HEAD to the wanted past commit
|
|
281
328
|
> $ git checkout <not-HEAD-commit-sha>
|
|
282
329
|
> # You can omit --to, it will take "HEAD" as default value
|
|
283
330
|
> $ sfdx sgd:source:delta --from "HEAD^" --output changed-sources/ --generate-delta
|
|
@@ -285,15 +332,18 @@ _Content of the output folder when using the --generate-delta option, with the s
|
|
|
285
332
|
|
|
286
333
|
### Exclude some metadata only from destructiveChanges.xml:
|
|
287
334
|
|
|
288
|
-
The `--ignore [-i]` parameter allows you to specify an [ignore file](https://git-scm.com/docs/gitignore)
|
|
289
|
-
element on the diff to ignore.
|
|
290
|
-
|
|
335
|
+
The `--ignore [-i]` parameter allows you to specify an [ignore file](https://git-scm.com/docs/gitignore) to filter the
|
|
336
|
+
element on the diff to ignore. SGD ignores every diff line matching the pattern from the ignore file specified in the `--ignore [-i]`. `package.xml` generation, `destructiveChanges.xml` generation and `--delta-generate` will ignore those lines.
|
|
337
|
+
|
|
338
|
+
Sometimes you may need to have two different ignore policies. One for the `package.xml` and another one for `destructiveChanges.xml` files. This is where the `--ignore-destructive [-D]` option comes handy!
|
|
339
|
+
Use the `--ignore-destructive` parameter to specify a dedicated ignore file to handle deletions. It will apply to metadata listed in the `destructiveChanges.xml`. In other words, this will override the `--ignore [-i]` parameter for deleted items.
|
|
291
340
|
|
|
292
|
-
|
|
341
|
+
Consider the following:
|
|
293
342
|
|
|
294
|
-
|
|
343
|
+
- a repository containing many sub-folders (force-app/main, force-app/sample, etc)
|
|
344
|
+
- a commit deleting the Custom\_\_c object from one folder and modifying the Custom\_\_c object from another folder. This is a Modification and a Deletion events.
|
|
295
345
|
|
|
296
|
-
|
|
346
|
+
The Custom\_\_c object appears in the `package.xml` and in `destructiveChanges.xml` and fail the deployment. This is a situation where your may want to use the `--ignore-destructive [-D]` parameter! Add the Custom\_\_c object pattern in an ignore file and pass it in the CLI parameter:
|
|
297
347
|
|
|
298
348
|
```sh
|
|
299
349
|
# destructiveignore
|
|
@@ -303,24 +353,28 @@ $ sfdx sgd:source:delta --from commit --ignore-destructive destructiveignore
|
|
|
303
353
|
|
|
304
354
|
```
|
|
305
355
|
|
|
306
|
-
Note
|
|
356
|
+
Note: when only using the `--ignore [-i]` parameter (and not `--ignore-destructive [-D]`) the plugin will apply it to added/changed/deleted elements.
|
|
307
357
|
|
|
308
358
|
### Explicitly including specific files for inclusion or destruction regardless of diff:
|
|
309
359
|
|
|
310
|
-
The `--include [-n]` parameter allows you to specify a file based on [micromatch glob matching](https://github.com/micromatch/micromatch)
|
|
360
|
+
The `--include [-n]` parameter allows you to specify a file based on [micromatch glob matching](https://github.com/micromatch/micromatch) to include specific files. Regardless whether they appears in the diff or not.
|
|
361
|
+
Like the `--ignore` flag, this file defines a list of glob file matchers to always include `git` aware files in the `package.xml` package.
|
|
362
|
+
SGD will include every line matching the pattern from the include file specified in the `--include [-n]`.
|
|
311
363
|
|
|
312
|
-
As with `--ignore`,
|
|
364
|
+
As with `--ignore`, you may need different policies for the `package.xml` and `destructiveChanges.xml` files. This is where the `--include-destructive [-N]` option comes handy!
|
|
313
365
|
|
|
314
|
-
Use the `--include-destructive` parameter to specify a dedicated include file to handle deletions
|
|
366
|
+
Use the `--include-destructive` parameter to specify a dedicated include file to handle deletions. Related metadata will appear in the `destructiveChanges.xml` output. Here, you will show which files should the `destructiveChanges.xml` should include .
|
|
367
|
+
Consider the following:
|
|
315
368
|
|
|
316
|
-
|
|
369
|
+
- a repository containing many sub-folders (force-app/main,force-app/sample, etc)
|
|
370
|
+
- a CI/CD platform generating a `force-app/generated/foo` file the `source:deploy` command should not include.
|
|
371
|
+
You can create a file with a line matching this new file and specify this file using the `--include-destructive [-N]` parameter.
|
|
317
372
|
|
|
318
373
|
```sh
|
|
319
|
-
# destructiveinclude
|
|
374
|
+
# .destructiveinclude
|
|
320
375
|
*generated/foo
|
|
321
376
|
|
|
322
|
-
$ sfdx sgd:source:delta --from commit --include-destructive destructiveinclude
|
|
323
|
-
|
|
377
|
+
$ sfdx sgd:source:delta --from commit --include-destructive .destructiveinclude
|
|
324
378
|
```
|
|
325
379
|
|
|
326
380
|
### Scoping delta generation to a specific folder
|
|
@@ -328,8 +382,8 @@ $ sfdx sgd:source:delta --from commit --include-destructive destructiveinclude
|
|
|
328
382
|
The `--source [-s]`parameter allows you to specify a folder to focus on, making any other folder ignored.
|
|
329
383
|
It means the delta generation will only focus on the dedicated folder.
|
|
330
384
|
|
|
331
|
-
For example, consider a repository containing
|
|
332
|
-
This repository contains
|
|
385
|
+
For example, consider a repository containing many sub-folders (force-app/package, force-app/unpackaged, etc).
|
|
386
|
+
This repository contains packaged (deployed via package) and unpackaged (deployed via CLI) sources.
|
|
333
387
|
You only want to apply delta generation for the unpackaged sources.
|
|
334
388
|
|
|
335
389
|
```sh
|
|
@@ -352,11 +406,10 @@ $ sfdx sgd:source:delta --from commit --source force-app/unpackaged
|
|
|
352
406
|
|
|
353
407
|
### Generate a comma-separated list of the added and modified Apex classes:
|
|
354
408
|
|
|
355
|
-
Depending on your testing strategy, [you may
|
|
356
|
-
|
|
357
|
-
To cover this requirement, you can use a tool such as [yq](https://github.com/kislyuk/yq) to parse the content of the package.xml file produced by SGD:
|
|
409
|
+
Depending on your testing strategy, [you may want to generate a comma-separated list of the added and modified Apex classes](https://github.com/scolladon/sfdx-git-delta/issues/126). This list can feed the `sfdx force:source:deploy --testlevel RunSpecifiedTests` command, for example.
|
|
410
|
+
To cover this need, parse the content of the package.xml file produced by SGD using [yq](https://github.com/kislyuk/yq):
|
|
358
411
|
|
|
359
|
-
`xq . < package/package.xml | jq '.Package.types |
|
|
412
|
+
`xq . < package/package.xml | jq '.Package.types | [.] | flatten | map(select(.name=="ApexClass")) | .[] | .members | [.] | flatten | map(select(. | index("*") | not)) | unique | join(",")'`
|
|
360
413
|
|
|
361
414
|
### Use the module in your own node application
|
|
362
415
|
|
|
@@ -366,13 +419,13 @@ If you want to embed sgd in your node application, install it has a dependency f
|
|
|
366
419
|
yarn add sfdx-git-delta
|
|
367
420
|
```
|
|
368
421
|
|
|
369
|
-
Then use the
|
|
422
|
+
Then use the JavaScript module
|
|
370
423
|
|
|
371
424
|
```js
|
|
372
425
|
// sample/app.js
|
|
373
426
|
const sgd = require('sfdx-git-delta')
|
|
374
427
|
|
|
375
|
-
const work = sgd({
|
|
428
|
+
const work = await sgd({
|
|
376
429
|
to: '', // commit sha to where the diff is done. [default : "HEAD"]
|
|
377
430
|
from: '', // (required) commit sha from where the diff is done. [default : git rev-list --max-parents=0 HEAD]
|
|
378
431
|
output: '', // source package specific output. [default : "./output"]
|
|
@@ -389,9 +442,12 @@ console.log(JSON.stringify(work))
|
|
|
389
442
|
*/
|
|
390
443
|
```
|
|
391
444
|
|
|
445
|
+
## Changelog
|
|
446
|
+
|
|
447
|
+
[changelog.md](/CHANGELOG.md) is available for consultation.
|
|
448
|
+
|
|
392
449
|
## Built With
|
|
393
450
|
|
|
394
|
-
- [commander](https://github.com/tj/commander.js/) - The complete solution for node.js command-line interfaces, inspired by Ruby's commander.
|
|
395
451
|
- [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) - Validate XML, Parse XML to JS/JSON and vise versa, or parse XML to Nimn rapidly without C/C++ based libraries and no callback
|
|
396
452
|
- [fs-extra](https://github.com/jprichardson/node-fs-extra) - Node.js: extra methods for the fs object like copy(), remove(), mkdirs().
|
|
397
453
|
- [ignore](https://github.com/kaelzhang/node-ignore#readme) - is a manager, filter and parser which implemented in pure JavaScript according to the .gitignore spec 2.22.1.
|
|
@@ -400,19 +456,19 @@ console.log(JSON.stringify(work))
|
|
|
400
456
|
|
|
401
457
|
## Versioning
|
|
402
458
|
|
|
403
|
-
[SemVer](http://semver.org/)
|
|
459
|
+
Versioning follows [SemVer](http://semver.org/) specification.
|
|
404
460
|
|
|
405
|
-
## Authors
|
|
461
|
+
## Authors
|
|
406
462
|
|
|
407
463
|
- **Sebastien Colladon** - Developer - [scolladon](https://github.com/scolladon)
|
|
408
464
|
- **Mehdi Cherfaoui** - Tester - [mehdisfdc](https://github.com/mehdisfdc)
|
|
409
465
|
|
|
410
466
|
## Contributing
|
|
411
467
|
|
|
412
|
-
Contributions are what make the trailblazer community such an amazing place. I regard this component as a way to inspire and learn from others. Any contributions you make are **
|
|
468
|
+
Contributions are what make the trailblazer community such an amazing place. I regard this component as a way to inspire and learn from others. Any contributions you make are **appreciated**.
|
|
413
469
|
|
|
414
470
|
See [contributing.md](/CONTRIBUTING.md) for sgd contribution principles.
|
|
415
471
|
|
|
416
472
|
## License
|
|
417
473
|
|
|
418
|
-
This project is
|
|
474
|
+
This project license is MIT - see the [LICENSE.md](LICENSE.md) file for details
|
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const command_1 = require("@salesforce/command");
|
|
4
4
|
const core_1 = require("@salesforce/core");
|
|
5
5
|
const sgd = require("../../../main");
|
|
6
|
-
const
|
|
7
|
-
const
|
|
6
|
+
const { TO_DEFAULT_VALUE, REPO_DEFAULT_VALUE, SOURCE_DEFAULT_VALUE, OUTPUT_DEFAULT_VALUE, } = require('../../../utils/cliHelper');
|
|
7
|
+
const { sfdc: { latestApiVersion }, } = require('../../../../package.json');
|
|
8
8
|
// Initialize Messages with the current plugin directory
|
|
9
9
|
core_1.Messages.importMessagesDirectory(__dirname);
|
|
10
10
|
const COMMAND_NAME = 'delta';
|
|
@@ -21,7 +21,7 @@ class SourceDeltaGenerate extends command_1.SfdxCommand {
|
|
|
21
21
|
warnings: [],
|
|
22
22
|
};
|
|
23
23
|
try {
|
|
24
|
-
const jobResult = sgd({
|
|
24
|
+
const jobResult = await sgd({
|
|
25
25
|
to: this.flags.to,
|
|
26
26
|
from: this.flags.from,
|
|
27
27
|
output: this.flags.output,
|
|
@@ -52,7 +52,7 @@ SourceDeltaGenerate.flagsConfig = {
|
|
|
52
52
|
to: command_1.flags.string({
|
|
53
53
|
char: 't',
|
|
54
54
|
description: messages.getMessage('toFlag'),
|
|
55
|
-
default:
|
|
55
|
+
default: TO_DEFAULT_VALUE,
|
|
56
56
|
}),
|
|
57
57
|
from: command_1.flags.string({
|
|
58
58
|
char: 'f',
|
|
@@ -62,7 +62,7 @@ SourceDeltaGenerate.flagsConfig = {
|
|
|
62
62
|
repo: command_1.flags.filepath({
|
|
63
63
|
char: 'r',
|
|
64
64
|
description: messages.getMessage('repoFlag'),
|
|
65
|
-
default:
|
|
65
|
+
default: REPO_DEFAULT_VALUE,
|
|
66
66
|
}),
|
|
67
67
|
ignore: command_1.flags.filepath({
|
|
68
68
|
char: 'i',
|
|
@@ -75,7 +75,7 @@ SourceDeltaGenerate.flagsConfig = {
|
|
|
75
75
|
source: command_1.flags.filepath({
|
|
76
76
|
char: 's',
|
|
77
77
|
description: messages.getMessage('sourceFlag'),
|
|
78
|
-
default:
|
|
78
|
+
default: SOURCE_DEFAULT_VALUE,
|
|
79
79
|
}),
|
|
80
80
|
'ignore-whitespace': command_1.flags.boolean({
|
|
81
81
|
char: 'W',
|
|
@@ -84,12 +84,12 @@ SourceDeltaGenerate.flagsConfig = {
|
|
|
84
84
|
output: command_1.flags.filepath({
|
|
85
85
|
char: 'o',
|
|
86
86
|
description: messages.getMessage('outputFlag'),
|
|
87
|
-
default:
|
|
87
|
+
default: OUTPUT_DEFAULT_VALUE,
|
|
88
88
|
}),
|
|
89
89
|
'api-version': command_1.flags.number({
|
|
90
90
|
char: 'a',
|
|
91
91
|
description: messages.getMessage('apiVersionFlag'),
|
|
92
|
-
default: parseFloat(
|
|
92
|
+
default: parseFloat(latestApiVersion),
|
|
93
93
|
}),
|
|
94
94
|
'generate-delta': command_1.flags.boolean({
|
|
95
95
|
char: 'd',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delta.js","sourceRoot":"","sources":["../../../../src/commands/sgd/source/delta.ts"],"names":[],"mappings":";;AAAA,iDAAwD;AACxD,2CAA2C;AAE3C,qCAAoC;AACpC,MAAM,
|
|
1
|
+
{"version":3,"file":"delta.js","sourceRoot":"","sources":["../../../../src/commands/sgd/source/delta.ts"],"names":[],"mappings":"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"}
|