Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In CI/CD YAML scripts, Skip Deployments/Destructive if package.xml is an empty placeholder #154

Closed
WaseemAliSabeel opened this issue Jun 21, 2021 · 8 comments
Assignees
Labels
enhancement New feature or request

Comments

@WaseemAliSabeel
Copy link

Is your proposal related to a problem?

Yes, to avoid Deployments and Destructives where the package.xml or destructiveChanges.xml is just an empty placeholder with no metadata type contents in it.

Description - While using this Fantastic tool in a CI/CD automated pipeline, I have configured the steps in a YAML file as instructed in Repo's Readme.
An observation is that whenever in any of our delta commits, if we are changing any file outside of force-app folder, the sfdx sgd:source:delta command works as expected(which is great!) and it leads to generation of an empty placeholder package.xml and an empty placeholder destructiveChanges.xml in the changed-sources Output directory.
Even this is fine and expected behaviour.

However, now, when we execute the commands to perform sfdx:force:source:deploy for delta deployment & subsequently sfdx force:mdapi:deploy for destructive deployment, it triggers an Empty Deployment job and we can see the Jobs running in Setup-> Deployment Status with 0/0 components.

Describe the solution you'd like

The desired solution would be to see if the generated files (specifically destructiveChanges.xml file) are an empty placeholder just like -

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
     <version>52.0</version>
</Package>

without any Metadata Types in it, can we conditionally control to Not Execute sfdx force:mdapi:deploy for destructive deployment ?

And on similar lines, if the output package.xml file is also like this empty placeholder, how to not execute the sfdx:force:source:deploy command for the same ?


I understand that this is not inherently part of the Plugin as such because the plugin did its job perfectly to find metadata deltas and it was as expected.
But in case of empty metadata deltas identified in these contexts, how to not Execute the deployment commands in a CI/CD pipeline using YAML scripts ?
Any thoughts / YAML code snippets around this ask please ?
YAML Script

Describe alternatives you've considered

None.
At the moment, as part of my Script In the Image shared, a second deployment job fires for the generated empty placeholder destructiveChanges.xml file.

Additional context

This Ask / Enhancement Request is in regards of using the sfdx-git-delta plugin in a CI/CD pipeline context with no manual intervention.

@WaseemAliSabeel WaseemAliSabeel added the enhancement New feature or request label Jun 21, 2021
@scolladon
Copy link
Owner

Hi @WaseemAliSabeel !

Thanks for this very well described request! And for your interest in the plugin.

What I understand is that you would like to have a way to detect if package.xml or destructiveChanges.xml are empty in order to not execute the deploy in those cases, right ?

If this is the case you might be interested in a tool like xq which allow you to write jq query on xml.
This way you would be able to ask if there are members in the package.xml, and if not then not execute the deploy.

Ex:

# returns "null" or the list of types
$xq . < changed-sources/destructiveChanges.xml | jq '.Package.types | if type=="array" then .[] else . end'

I hope it helps

@WaseemAliSabeel
Copy link
Author

WaseemAliSabeel commented Jun 23, 2021

Thank you for following up, @scolladon !
I tried to install xq in my bash script in YAML steps. It had a prerequisite to install jq
Followed those steps, still am unable to install jq & xq to be able to call these commands.

sudo apt-get install jq;
pip3 install yq;

Can you please assist me in using these libraries or plugins as expected in the YAML execution steps ?
(Sorry, but I do not know how to work with Bash commands)

Output of cat /etc/os-release =
NAME = "Debian GNU/Linux"
VERSION_ID="10"

output of bash --version =
GNU bash, version 5.0.3(1)-release (x86_64-pc-linux-gnu)

@WaseemAliSabeel
Copy link
Author

Ok, After a little bit digging around-
I used below steps to successfully Install jq & yq -

apt-get update;
echo "****** jq Version ******";
jq --version;
echo y | apt install python3-pip;
echo "****** pip3 Version ******";
pip3 --version;
echo y | pip3 install yq;
echo "****** yq Version ******";
yq --version;
echo "****** Installing sfdx-cli with Plugins ******";
npm install sfdx-cli --global;
echo y | sfdx plugins:install sfdx-git-delta;
echo "****** sfdx Version ******";
sfdx --version;
sfdx plugins --core;

jq version = jq-1.6
yq version = 2.12.2

Now, when I execute your stated xq command as follows -

cat changed-sources/package/package.xml;
cat changed-sources/destructiveChanges/destructiveChanges.xml;
xq . > changed-sources/package/package.xml | jq '.Package.types | if type=="array" then.[] else . end';
echo "****** Deploying added and modified metadata ******";
sfdx force:source:deploy --checkonly --json --verbose --loglevel fatal --targetusername CI-SBX -x changed-sources/package/package.xml;
echo "****** Deleting removed metadata  ******";
echo xq . > changed-sources/destructiveChanges/destructiveChanges.xml | jq '.Package.types | if type=="array" then.[] else . end';
sfdx force:mdapi:deploy  --checkonly --json --loglevel fatal --targetusername CI-SBX --deploydir changed-sources/destructiveChanges;

The first two cat commands both display an empty placeholder xml file, with no types in them, It triggers the SFDX deployment Job and errors out saying - "Cannot Convert undefined or null to object"

And on a different try, the SFDX deployment command executed with the empty package.xml and it read on Setup->Deployment Status in the salesforce org -
"package.xml Bad file:Content is not allowed in prolog."

Can you @scolladon help troubleshoot this and help me with appropriate script commands which would lead to -
if(package.xml is NOT empty){
sfdx:force:source:deploy ....
}
if(destructiveChangex.xml is NOT empty){
sfdx force:mdapi:deploy ...
}

Thanks!

@scolladon
Copy link
Owner

Hi,

Something you could try is (I have not testing it myself) :

$ cat changed-sources/package/package.xml
$ cat changed-sources/destructiveChanges/destructiveChanges.xml
$ PACKAGE=`xq . > changed-sources/package/package.xml | jq '.Package.types | if type=="array" then.[] else . end'`
$ echo "****** Deploying added and modified metadata ******"
$ [[ ! -z "$PACKAGE" ]] && sfdx force:source:deploy --checkonly --json --verbose --loglevel fatal --targetusername CI-SBX -x changed-sources/package/package.xml
$ echo "****** Deleting removed metadata  ******"
$ DESTRUCTIVE=`xq . > changed-sources/destructiveChanges/destructiveChanges.xml | jq '.Package.types | if type=="array" then.[] else . end'`
$ [[ ! -z "$DESTRUCTIVE" ]] && sfdx force:mdapi:deploy  --checkonly --json --loglevel fatal --targetusername CI-SBX --deploydir changed-sources/destructiveChanges

You could also use grep to find if there is a type in the xml files (simpler and more easy to setup because it does not need setup installation) :

$ cat changed-sources/package/package.xml
$ cat changed-sources/destructiveChanges/destructiveChanges.xml
$ echo "****** Deploying added and modified metadata ******"
$ [[ ! -z $(grep '<types>' changed-sources/package/package.xml) ]] && sfdx force:source:deploy --checkonly --json --verbose --loglevel fatal --targetusername CI-SBX -x changed-sources/package/package.xml
$ echo "****** Deleting removed metadata  ******"
$ [[ ! -z $(grep '<types>' changed-sources/destructiveChanges/destructiveChanges.xml) ]] && sfdx force:mdapi:deploy  --checkonly --json --loglevel fatal --targetusername CI-SBX --deploydir changed-sources/destructiveChanges

if you need more help please use gitter (this is more suitable for direct communication).

I close this issue then !

@WaseemAliSabeel
Copy link
Author

Thank You for your inputs @scolladon
I got it working to skip the deployment for Empty Package.xml & empty Destructive xml using below snippet.
No need of other plugin utilities.

if grep -q '<types>' changed-sources/package/package.xml;
then
  echo "****** Validating added and modified metadata ******";
  sfdx force:source:deploy --checkonly --json --verbose --targetusername CI-SBX -x changed-sources/package/package.xml;
fi;

if grep -q '<types>' changed-sources/destructiveChanges/destructiveChanges.xml;
then
  echo "****** Validating deletion of removed metadata ******";
  sfdx force:mdapi:deploy --checkonly --json --verbose --wait -1 --targetusername CI-SBX --deploydir changed-sources/destructiveChanges;
fi;

Thanks again. Great Plugin! Keep it active !

@jonny-harte
Copy link

@WaseemAliSabeel which CI are you using? I'm trying to implelent the exact same check using Github Actions but if: grep -q '<members>' package/package.xml doesn't work.

The workflow is not valid. .github/workflows/salesforce-ci.yml (Line: 46, Col: 13): Unrecognized named-value: 'grep'. Located at position 1 within expression: grep -q '' package/package.xml .github/workflows/salesforce-ci.yml (Line: 50, Col: 13): Unrecognized named-value: 'grep'. Located at position 1 within expression: grep -q '' destructiveChanges/destructiveChanges.xml

@WaseemAliSabeel
Copy link
Author

@jonny-harte I guess you should be using if grep -q '<types>'
and not if grep -q '<members>'

Because the package xml is structured like-

<types>
        <members>first</members>
        <members>second ...</members>
        <name>MetadataType</name>
    </types> 

When I implemented this plugin, I was using Screwdriver CICD tool https://screwdriver.cd/

@nikhileshmishra
Copy link

@WaseemAliSabeel When there is any deletion , I can see the changes in destructiveChanges/destructiveChanges.xml file ,
But when we r deploying ,it shows
image
My question is , when we deploy the destructive components
what can we expect to see in logs & sandbox ?

In my logs , i could see below 0/0 . Is it correct ?
or it should show the actual number of components deleted. Even in my sandbox ,i see 0/0 components .

Can u please share ,how it looks alike for your destructive deployments .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants