diff --git a/README.md b/README.md index d773593b..c5d32585 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ - [Prerequisites](#prerequisites) - [Installation](#installation) - [How to use it?](#how-to-use-it) -- [`sfdx sgd:source:delta -f [-t ] [-r ] [-i ] [-D ] [-s ] [-W] [-o ] [-a ] [-d] [-n ] [-N ] [--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) +- [`sf sgd source delta -f [-t ] [-r ] [-i ] [-D ] [-s ] [-W] [-o ] [-a ] [-d] [-n ] [-N ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]`](#sf-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-tracedebuginfowarnerrorfataltracedebuginfowarnerrorfatal) - [Windows users](#windows-users) - [CI/CD specificity](#cicd-specificity) - [Git LFS support](#git-lfs-support) @@ -61,15 +61,15 @@ ## TL;DR ```sh -sfdx plugins:install sfdx-git-delta +sf plugins install sfdx-git-delta ``` ```sh -sfdx sgd:source:delta --to "HEAD" --from "HEAD~1" --output "." +sf sgd source delta --to "HEAD" --from "HEAD~1" --output "." ``` ```sh -sfdx force:source:deploy -x package/package.xml --postdestructivechanges destructiveChanges/destructiveChanges.xml +sf project deploy start -x package/package.xml --post-destructive-changes destructiveChanges/destructiveChanges.xml ``` ## What is SFDX-Git-Delta? @@ -112,16 +112,16 @@ It's also important to implement a way to switch back to full deployment in case The plugin requires git command line on the running environment. **Node v16.20.0 or above is required**. -To check if Salesforce CLI runs under a supported node version for SGD, run `sfdx --version`. You should see a node version above v.16.20.0 to use SGD. +To check if Salesforce CLI runs under a supported node version for SGD, run `sf --version`. You should see a node version above v.16.20.0 to use SGD. -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`). +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 @salesforce/cli --global`). ### Installation -SGD is a Salesforce CLI plugin (`sfdx sgd:source:delta`). Run the following command to install it: +SGD is a Salesforce CLI plugin (`sf sgd source delta`). Run the following command to install it: ```sh -sfdx plugins:install sfdx-git-delta +sf plugins install sfdx-git-delta ``` 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. @@ -133,15 +133,15 @@ If you run your CI/CD jobs inside a Docker image, you can add the plugin to your ## How to use it? -* [`sfdx sgd:source:delta -f [-t ] [-r ] [-i ] [-D ] [-s ] [-W] [-o ] [-a ] [-d] [-n ] [-N ] [--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) +* [`sf sgd source delta -f [-t ] [-r ] [-i ] [-D ] [-s ] [-W] [-o ] [-a ] [-d] [-n ] [-N ] [--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) -## `sfdx sgd:source:delta -f [-t ] [-r ] [-i ] [-D ] [-s ] [-W] [-o ] [-a ] [-d] [-n ] [-N ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]` +## `sf sgd source delta -f [-t ] [-r ] [-i ] [-D ] [-s ] [-W] [-o ] [-a ] [-d] [-n ] [-N ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]` Generate the sfdx content in source format and destructive change from two git commits ``` USAGE - $ sfdx sgd:source:delta -f [-t ] [-r ] [-i ] [-D ] [-s ] [-W] + $ sf sgd source delta -f [-t ] [-r ] [-i ] [-D ] [-s ] [-W] [-o ] [-a ] [-d] [-n ] [-N ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] @@ -200,15 +200,13 @@ If you run SGD on a Windows system, use double quotes [to prevent the terminal t You should also avoid using the "^" character ([shorthand for parent commit in git](https://git-scm.com/docs/git-rev-parse#Documentation/git-rev-parse.txt-emltrevgtltngtemegemHEADv1510em)) because it is the [escape character in Windows](https://ss64.com/nt/syntax-esc.html#:~:text=include%20the%20delimiters.-,Escape%20Character,-%5E%20%20Escape%20character.). So instead of: ```sh -sfdx sgd:source:delta --from "HEAD^" # wrong git shortcut with windows because it uses "^" syntax +sf sgd source delta --from "HEAD^" # wrong git shortcut with windows because it uses "^" syntax ```` You should write: ```sh -sfdx sgd:source:delta --from "HEAD~1" # right git shortcut with windows because it does not use "^", it uses "~n" syntax +sf sgd source delta --from "HEAD~1" # right git shortcut with windows because it does not use "^", it uses "~n" syntax ``` - - ### CI/CD specificity In CI/CD pipelines, for most of the CI/CD providers, the checkout operation fetch only the last commit of the branch currently evaluated. @@ -223,7 +221,7 @@ This applies to both `--from` and `--to` parameters as they both accept git poin Example comparing `HEAD` with a `development` branch when the CI clone the repository with `origin` set as reference to the remote: ```sh -sfdx sgd:source:delta --to "HEAD" --from "origin/development" --output . +sf sgd source delta --to "HEAD" --from "origin/development" --output . ``` Use global variable when you need to easily switch sgd version (`vX.X.X` format) or channel (`stable`, `latest`, `latest-rc`) in your pipeline, without having to commit a new version of your pipeline. @@ -232,7 +230,7 @@ Example with [github action](https://docs.github.com/en/actions/learn-github-act ```yaml - name: Install SGD - run: echo y | sfdx plugins:install "sfdx-git-delta@${{ vars.SGD_VERSION }}" + run: echo y | sf plugins install "sfdx-git-delta@${{ vars.SGD_VERSION }}" ``` ### Git LFS support @@ -256,21 +254,21 @@ Here are examples of how to compare the content of different branches: For example, if you have commit `fbc3ade6` in branch `develop` and commit `61f235b1` in branch `main`: ```sh -sfdx sgd:source:delta --to fbc3ade6 --from 61f235b1 --output . +sf sgd source delta --to fbc3ade6 --from 61f235b1 --output . ``` - **Comparing branches (all changes)** Comparing all changes between the `develop` branch and the `main` branch: ```sh -sfdx sgd:source:delta --to develop --from main --output . +sf sgd source delta --to develop --from main --output . ``` - **Comparing branches (from a common ancestor)** 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): ```sh -sfdx sgd:source:delta --to develop --from $(git merge-base develop main) --output . +sf sgd source delta --to develop --from $(git merge-base develop main) --output . ``` ## Walkthrough @@ -300,14 +298,14 @@ So let’s do it! From the project repo folder, the CI pipeline will run the following command: ```sh -sfdx sgd:source:delta --to "HEAD" --from "HEAD~1" --output . +sf sgd source delta --to "HEAD" --from "HEAD~1" --output . ``` which means: > Analyze the difference between HEAD (latest commit) and HEAD~1 (previous commit), and output the result in the current folder. -The `sfdx sgd:source:delta` command produces 2 useful artifacts: +The `sf sgd source delta` command produces 2 useful artifacts: **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. @@ -326,12 +324,12 @@ Note: it is also possible to generate a **source** folder containing added/chang The simplest option to deploy the incremental changes is to use `force:source:deploy` command with `-x` parameter: ```sh -sfdx force:source:deploy -x package/package.xml --postdestructivechanges destructiveChanges/destructiveChanges.xml +sf project deploy start -x package/package.xml --post-destructive-changes destructiveChanges/destructiveChanges.xml ``` And voilà! 🥳 -However, keep in mind that 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 doesn't get stuck by a failed destructive change. +However, keep in mind that the above command will fail if the destructive change was supposed to be executed before the deployment (i.e. as `--pre-destructive-changes`), or if a warning occurs during deployment. Make sure to protect your CI/CD pipeline from those scenarios, so that it doesn't get stuck by a failed destructive change. If needed, you can also split the added/modified metadata deployment from the deleted/renamed metadata deployment, as in the below examples: @@ -342,7 +340,7 @@ echo "--- package.xml generated with added and modified metadata ---" cat package/package.xml echo echo "---- Deploying added and modified metadata ----" -sfdx force:source:deploy -x package/package.xml +sf project deploy start -x package/package.xml ``` Use the `destructiveChanges` folder to deploy only the destructive changes: @@ -352,7 +350,7 @@ echo "--- destructiveChanges.xml generated with deleted metadata ---" cat destructiveChanges/destructiveChanges.xml echo echo "--- Deleting removed metadata ---" -sfdx force:mdapi:deploy -d destructiveChanges --ignorewarnings +sf project deploy start --pre-destructive-changes destructiveChanges/destructiveChanges.xml --manifest destructiveChanges/package.xml --ignore-warnings ``` ## Advanced use-cases @@ -369,7 +367,7 @@ Let's use this option with our previous example: ```sh mkdir changed-sources -sfdx sgd:source:delta --to "HEAD" --from "HEAD~1" --output changed-sources/ --generate-delta +sf sgd source delta --to "HEAD" --from "HEAD~1" --output changed-sources/ --generate-delta ``` It generates the `package` and `destructiveChanges` folders, and copies added/changed files in the output folder. @@ -385,13 +383,13 @@ _Content of the output folder when using the --generate-delta option, with the s > # move HEAD to the wanted past commit > $ git checkout > # You can omit --to, it will take "HEAD" as default value -> $ sfdx sgd:source:delta --from "HEAD~1" --output changed-sources/ --generate-delta +> $ sf sgd source delta --from "HEAD~1" --output changed-sources/ --generate-delta > ``` Then it is possible to deploy the `change-sources` folder using `force:source:deploy` command with `-p` parameter: ```sh -sfdx force:source:deploy -p change-sources +sf project deploy start -p change-sources ``` ### Exclude some metadata only from destructiveChanges.xml @@ -413,7 +411,7 @@ The Custom\_\_c object appears in the `package.xml` and in `destructiveChanges.x # destructiveignore *Custom\_\_c.object-meta.xml -$ sfdx sgd:source:delta --from commit --ignore-destructive destructiveignore +$ sf sgd source delta --from commit --ignore-destructive destructiveignore ``` @@ -441,7 +439,7 @@ Consider the following: # .destructiveinclude *generated/foo -$ sfdx sgd:source:delta --from commit --include-destructive .destructiveinclude +$ sf sgd source delta --from commit --include-destructive .destructiveinclude ``` The path matchers in includes file must follow [`gitignore`](https://git-scm.com/docs/gitignore#:~:text=The%20slash%20/%20is%20used%20as%20the%20directory%20separator.) spec and accept only unix path separator `/` (even for windows system). @@ -468,7 +466,7 @@ $ tree ├── ... # scope the delta generation only to the unpackaged folder -$ sfdx sgd:source:delta --from commit --source force-app/unpackaged +$ sf sgd source delta --from commit --source force-app/unpackaged ``` > The ignored patterns specified using `--ignore [-i]` and `--ignore-destructive [-D]` still apply. @@ -476,7 +474,7 @@ $ sfdx sgd:source:delta --from commit --source force-app/unpackaged ### Generate a comma-separated list of the added and modified Apex classes -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. +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 `sf project deploy start --testlevel RunSpecifiedTests` command, for example. To cover this need, parse the content of the package.xml file produced by SGD using [yq](https://github.com/kislyuk/yq): `xq . < package/package.xml | jq '.Package.types | [.] | flatten | map(select(.name=="ApexClass")) | .[] | .members | [.] | flatten | map(select(. | index("*") | not)) | unique | join(",")'` @@ -491,7 +489,7 @@ To avoid starting a failing deployment, test files content before execution: # run deploy command only if the generated package contains metadata if grep -q '' ./package/package.xml ; then echo "---- Deploying added and modified metadata ----" - sfdx force:source:deploy -x package/package.xml + sf project deploy start -x package/package.xml else echo "---- No changes to deploy ----" fi diff --git a/package.json b/package.json index 23445449..f28c63da 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "author": "Sebastien Colladon ", "dependencies": { "@salesforce/command": "^5.3.9", - "@salesforce/core": "^8.5.3", + "@salesforce/core": "^8.5.4", "async": "^3.2.6", "fast-xml-parser": "^4.5.0", "fs-extra": "^11.2.0", @@ -230,12 +230,12 @@ "@types/async": "^3.2.24", "@types/jest": "^29.5.12", "@types/mocha": "^10.0.7", - "@types/node": "^22.5.2", + "@types/node": "^22.5.3", "benchmark": "^2.1.4", "chai": "^4.3.10", "husky": "^9.1.5", "jest": "^29.7.0", - "knip": "^5.29.1", + "knip": "^5.29.2", "lint-staged": "^15.2.10", "mocha": "^10.7.3", "nyc": "^17.0.0", @@ -245,7 +245,7 @@ "ts-node": "^10.9.2", "tslib": "^2.7.0", "typescript": "^5.5.4", - "wireit": "^0.14.8", + "wireit": "^0.14.9", "yarn-audit-fix": "^10.0.9", "yarn-upgrade-all": "^0.7.4" }, diff --git a/yarn.lock b/yarn.lock index 48a628d6..b2941980 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2028,7 +2028,7 @@ __metadata: languageName: node linkType: hard -"@salesforce/core@npm:^8.5.1, @salesforce/core@npm:^8.5.3": +"@salesforce/core@npm:^8.5.1": version: 8.5.3 resolution: "@salesforce/core@npm:8.5.3" dependencies: @@ -2054,6 +2054,32 @@ __metadata: languageName: node linkType: hard +"@salesforce/core@npm:^8.5.4": + version: 8.5.4 + resolution: "@salesforce/core@npm:8.5.4" + dependencies: + "@jsforce/jsforce-node": ^3.4.1 + "@salesforce/kit": ^3.2.2 + "@salesforce/schemas": ^1.9.0 + "@salesforce/ts-types": ^2.0.10 + ajv: ^8.17.1 + change-case: ^4.1.2 + fast-levenshtein: ^3.0.0 + faye: ^1.4.0 + form-data: ^4.0.0 + js2xmlparser: ^4.0.1 + jsonwebtoken: 9.0.2 + jszip: 3.10.1 + pino: ^9.3.2 + pino-abstract-transport: ^1.2.0 + pino-pretty: ^11.2.2 + proper-lockfile: ^4.1.2 + semver: ^7.6.3 + ts-retry-promise: ^0.8.1 + checksum: 68a3552f0ae73a1ea07ca56a3308c21094e645e5cbf8991bdca4b6faeb19f05ad1fd8eb06a7bf51fe6bdcf156829836c21bbb079d0894ca9ae3ee610471d1358 + languageName: node + linkType: hard + "@salesforce/dev-config@npm:^4.1.0": version: 4.1.0 resolution: "@salesforce/dev-config@npm:4.1.0" @@ -2724,12 +2750,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^22.5.2": - version: 22.5.2 - resolution: "@types/node@npm:22.5.2" +"@types/node@npm:^22.5.3": + version: 22.5.3 + resolution: "@types/node@npm:22.5.3" dependencies: undici-types: ~6.19.2 - checksum: 5e47839dd1919b39927a5552137ded5d3f18d9ff7729083ba851d640a6a0997ee747b9e2cf4c8a1f8418ad92ef7f0ada4fdc2d005dad2efb39fa80a5c7f6d23d + checksum: 50a5075e4e8bc874a9fe962447341b6b49bd79cf2801fadd3e31d2bda60decba8d907e3150887afc9f883d819cc42c7e862fffc934049d37cb5589e0a2afbcc1 languageName: node linkType: hard @@ -6917,9 +6943,9 @@ __metadata: languageName: node linkType: hard -"knip@npm:^5.29.1": - version: 5.29.1 - resolution: "knip@npm:5.29.1" +"knip@npm:^5.29.2": + version: 5.29.2 + resolution: "knip@npm:5.29.2" dependencies: "@nodelib/fs.walk": 1.2.8 "@snyk/github-codeowners": 1.1.0 @@ -6943,7 +6969,7 @@ __metadata: bin: knip: bin/knip.js knip-bun: bin/knip-bun.js - checksum: 4028f4baba77c0a6cfe9ca814aa66e751b824d063e8f3f3039bd47543b29337ca55d1e6a3bcbd2bcdc9364284b9e26ca778141a7b5a6d93f010c33fa3dcfb297 + checksum: c1c9abf9f6438c17f854c52adc7f294d07991632a7a45675c0213815546556b74fc7ac9cd3b7fd3eca2bd6c816fa973e212a4b38c0dc87e0826ea63635d5e2b6 languageName: node linkType: hard @@ -9161,7 +9187,7 @@ __metadata: "@oclif/dev-cli": ^1.26.10 "@salesforce/cli-plugins-testkit": ^5.3.28 "@salesforce/command": ^5.3.9 - "@salesforce/core": ^8.5.3 + "@salesforce/core": ^8.5.4 "@salesforce/dev-config": ^4.1.0 "@salesforce/ts-sinon": ^1.4.26 "@stryker-mutator/core": ^8.5.0 @@ -9170,7 +9196,7 @@ __metadata: "@types/async": ^3.2.24 "@types/jest": ^29.5.12 "@types/mocha": ^10.0.7 - "@types/node": ^22.5.2 + "@types/node": ^22.5.3 async: ^3.2.6 benchmark: ^2.1.4 chai: ^4.3.10 @@ -9180,7 +9206,7 @@ __metadata: ignore: ^5.3.2 isomorphic-git: ^1.27.1 jest: ^29.7.0 - knip: ^5.29.1 + knip: ^5.29.2 lint-staged: ^15.2.10 lodash: ^4.17.21 mocha: ^10.7.3 @@ -9192,7 +9218,7 @@ __metadata: ts-node: ^10.9.2 tslib: ^2.7.0 typescript: ^5.5.4 - wireit: ^0.14.8 + wireit: ^0.14.9 xmlbuilder2: ^3.1.1 yarn-audit-fix: ^10.0.9 yarn-upgrade-all: ^0.7.4 @@ -10469,9 +10495,9 @@ __metadata: languageName: node linkType: hard -"wireit@npm:^0.14.8": - version: 0.14.8 - resolution: "wireit@npm:0.14.8" +"wireit@npm:^0.14.9": + version: 0.14.9 + resolution: "wireit@npm:0.14.9" dependencies: brace-expansion: ^4.0.0 chokidar: ^3.5.3 @@ -10480,7 +10506,7 @@ __metadata: proper-lockfile: ^4.1.2 bin: wireit: bin/wireit.js - checksum: 028fc0d9151cb7d2ebd2da8b981aa21091913655602f2e3e92ca5add811cb5881276f6d9d27db408af6b52357924f8682c1b058968ec4989c20bd25a746d44ac + checksum: 2e2d539bc37e0d68bde5a1fef0d9bdd393e88f525e514fa50885d96eb455dd58f8cf5d5ae8a9bc7f6ee4aba4e6006f0f1e10406a3e25171e16a8d6904e35617d languageName: node linkType: hard