Two Years with Salesforce DX: Tips and Tricks Learned Along the Way
Use Salesforce regularly? This webinar recap is for you. Here, Integrate.io's panel of experts explore hot-button Salesforce issues and more.
Two Years with Salesforce DX: Tips and Tricks Learned Along the Way
In this video, Texei’s CTO, Fabien Taillon, goes over all the tips and tricks he can share after working with Salesforce DX for more than two years. Whether you’re new to Salesforce or practically a Salesforce expert who just wants to learn a few little-known workarounds, this video will help you out.
When you watch, you’ll get good ideas on what to do with Profiles, how to deploy metadata that has usernames, how to handle certain push errors, and much more. You’ll learn how and when to clean up metadata you haven’t used in a while, and how to handle permission sets to get the best results. And if you’ve ever struggled with issues involving labels, API names, and other common problems that come up with scratch orgs when using Salesforce DX, you’ll appreciate these tips from Taillon.
Experienced Salesforce developers and new Salesforce users alike can learn a lot from this half-hour video on some common issues Taillon has discovered and solved. Even if the issue you’re having isn’t described here, you’ll get some advice on finding community support to solve your Salesforce DX problems, making this video great to watch when you’re waiting for your support request to be resolved by Salesforce.
VIEW TRANSCRIPT
Hello, Hello and welcome to another X Force Data Summit presentation. Today we have Fabienne Taillon, who's a Salesforce MVP and the CTO of Techse, which is a Salesforce consultancy in France.
He's gonna talk about Salesforce DX and this presentation is more tips and tricks about his learning from actually using it.
And I'm very excited to watch it because I think Salesforce DX is a great new advance in Salesforce, a relatively new. So here's Fabienne.
Hi, everyone, and thank you for being there. So as you said, I'll be showing what I've learned with Salesforce DX during these two or three years using it.
Let's jump into it.
Quickly to introduce myself.
As you said, my name is Fabienne Thayon. I'm a Salesforce MVP for, I think, five years now.
I'm also a CTO at TechSay, and I'm running the Paris Developer Group for maybe five or six years now. I'm also part of the French Touch Dreaming event.
You can follow me on Twitter with this quite easy to remember Twitter.
Let's quickly review the agenda of this presentation. It will be mainly two parts. The first part is around the general tips.
How you should start, what you should do and shouldn't do. And then the second part is more looking at specific issues like this specific metadata isn't working. How could you work with it with DX? For instance, a topic on profiles because it's a big topic with Salesforce DX.
So I wanted to start with this nice quotation from a big philosopher, Yoda, which says, Do or do not, there is no try. So it's a nice quotation for a movie. But I would say that unfortunately for Salesforce DX, it may not be the best thing to do.
Really, what I would say is you don't need to overthink too much and you really need to try it.
Why do I say that? Is that when you try to look at Salesforce DX and look at the documentation, what you may find is mostly basic examples.
You will see stuff on how to create scratch org, push and pull metadata and only documentation on basic stuff on what's working actually. You won't have information about how to create a scratch org with all the metadata from the production environment or stuff like that.
Documentation is pretty basic.
And then on the other side, we also have lots of series mostly driven by the community. So including some blog posts I've written myself that will tell you what the theory and what you should do to work on DX.
From time to time, this kind of stuff may be quite complicated. Like how you should decompose your org in several packages, refactor a lot of stuff to make it work. It may be a little bit frightening before if you need to start and think about all of this kind of stuff. Obviously, it could be a goal to achieve at the very end of your move to DX, but it shouldn't be a showstopper.
Here is the thing, something you need to remember is when you move to DX, you may think that I want to go to this step and do everything with DX and everything should be perfect and automated and everything, which is the goal, of course. But remember where you are now. For instance, profile may be an issue, but you have lots of customers when I ask them to say, but even now we are not deploying profiles, are checking changes manually in production, which isn't good, but this means that it shouldn't be a showstopper if DX doesn't handle profiles at the very first iteration because the customer isn't already deploying profiles today.
Don't aim at something one hundred percent perfect from the beginning, but look at where you are now because you may be using change set with lots of metadata missing. You may have a lot of manual steps to do already. One of the question I have is, I am creating a scratch org, but I don't have any data to play with it. Okay, but do you have any data in your developer sandbox?
No, I don't have data in the developer sandbox. So actually it's the same issues, but when you talk about moving to DX, you may expect everything working from step one, which may not be the case and it shouldn't be a showstopper because it's already not the case from what you are using today.
Really, is my first advice, is don't overthink, try stuff, and really start more on iterate. You don't need to have one hundred percent perfect stuff from the beginning. Start with something, start with a small scratch org, maybe add everything in the repo or whatever, but don't aim for your one hundred percent perfect goal from the very beginning.
Another advice would be that you shouldn't put everything in your repo.
I've been working with a customer that created a quite impressive scratch org actually. It's almost like a sandbox. They have one hundred percent as the same metadata as in their production org, which may be cool, but it takes a lot of time to create.
Plus they also have all the standard layouts and everything that they don't even use. It doesn't really make sense to have everything in this scratch org. In the repos, they have all standard objects, even though they are using maybe ten only.
So that sounds really makes sense.
Plus if you have maybe, I don't know, twenty applications in your production environment, that doesn't mean you need to install them in your Scratchog. You need to only install the one that you will really need in the Scratchog and that's it. Because you may have some application that will help you clean or export stuff from your production org and it doesn't make sense in the scratch org, which will be a development environment.
Next point is that this is a good opportunity to clean what you don't need anymore. Because when you start to create a scratch org, you will, for instance, talking about AppExchange, you will see that maybe there are ten of them that you don't see anymore, and you can just remove from production actually. So just go ahead and remove them.
Also, from time to time, you will just see some objects and see that there is no connection with anything. You go to production, look at how many records that are in the table, and it's just empty actually. When you start digging deeper and you just see that it was a test from five years ago and it was never deleted. This is a good opportunity to see what is still in production, but shouldn't be in the scratch org and moreover should be clean from production.
Some of the stuff I've seen is like a failing process builder. When you create a scratch org for the first time, you will take all the metadata from your production, try to push on the scratch org, except if you are very, very, very lucky, you will have lots of errors because you will be missing some feature that are not activated.
You forgot to include one metadata or whatever. There's lots of reason for this. From time to time, you will see that some metadata, even if everything is perfect, won't deploy. You will get an error and you can scratch your head forever and try to understand why. And then you go to production, you open, instance, Process Builder and you click Edit and Save and it won't save again. So you have already sometimes in production metadata that is not valid anymore.
And what does it mean? It means that first you can remove it from your scratcher or maybe fix it in production. But most likely, it's something that was never used and never cleaned. So it's a good opportunity to clean this kind of metadata both from your repo and from your production environment.
Then the thing to remember is that the Scratchog, it's not a copy of production. It's a development environment, so you don't need to put everything inside the scratch org. For instance, if you think about lists your reports, it could be in the scratch org or maybe not. You may think about who is the owner of this kind of metadata. If someone needs to change a report or at least you, should it be an admin that will change it in production because it's fast and there is no need to ask for the development team? Or is it something that the dev team will handle?
If the dev team is handling these kind of things, it's in the repo. Otherwise, it should be only in production. So what I usually do is I may not take list view or reports, except if they are referenced in the metadata like Flexi page or stuff like that. But otherwise, put these reports on these views in the repository, in the Scratcher because I don't want someone from the business to come to see me and say, Hey, change one thing in the report. They should be able to change it directly in production.
You really need to think about what should be in the repo and what should not be in the repo depending on who is the owner of this kind of metadata.
Then the last thing which I will talk about just after is you should only add what you able to update and deploy from the scratch org. For instance, one of the issues with metadata that we need to deploy with scratch org, so I'm just switching to the more specific issues with DX, is that some metadata are referencing some usernames.
When you create a scratch org, there will be only one user. It is a generic user from the scratch org and you don't have any other user that are existing in your production environment. So if one of your metadata is referencing one user, you won't be able to deploy it because it will just throw an error saying that this user isn't present in the org.
So there are a few things you can do about this.
So first is refactoring because some of the it doesn't work for all the metadata. For some of them, you can replace or hard coded username by either a queue or a public group, which makes sense actually because you will have a reference to a queue or a public group that will be emptying your scratch org. This is part of your package and your project, But then it's up to the admin in production to select who is part of this group who should receive an email, who is the approver or whatever.
And it shouldn't be linked to a version of your application because it's just switching one user with another one or whatever. So I think it makes sense to remove every time it's possible, opcode into username with a pure public group that will be handled by an admin in production.
But unfortunately, there are some stuff that doesn't work yet maybe because the good thing with DX also is that release after release, it's improving. There are a few things like when you try to update an owner for a record, if this specific record doesn't allow you to set a queue as owner, you won't have any other opportunities and aren't coding a username in this specific area. It could be a process builder or field update, workflow field update.
Here you have two options.
It's either you can script something like say, hey, when I deploy this metadata to the scratch org, I can on the fly replace some stuff from this metadata with the username from the scratch org. But does it really make sense actually? Because it's your development environment. And even if it's deployed, you can't change it, if there is a user story that say you should replace this guy by this guy, and you can't anyway do it in the scratch org.
Does it make sense to have it in the scratch org? Maybe not. So if you have lots of dependencies on this specific action, of course, add it and try to script something to replace users on the fly. Otherwise, it's just one small field update that you don't really need that you will have to either update the metadata manually or do it manually in production.
It doesn't make sense to add to the repo on the scratch org, so it's up to you. There are some stuff coming from Salesforce to try to handle this kind of use case, but I think it's supposed to start in summer, but I don't think it will be there before one year. So again, it's stuff that are coming and for now you should just handle this way, either replace it or just don't put it in the report.
One very good thing with DX is that as everything is in your repo, it's not the org anymore that is the reference. The source of truth is the repo.
You can script whatever you want actually.
This means that if you find any issue, you can create some code to script it and try to replace it on the fly during your deployment process, for instance. What I would recommend actually is to don't script it with, I don't know, PowerShell or whatever if you're using Azure DevOps or stuff like that. Create a custom SFDX plugin. So if you're using SFDX, you already know Salesforce official CLI tool.
You can create your own plugin on this same architecture and you can install your plugin in the SFDX in the Salesforce CLI tool directly.
There are several advantages with that, which is you can reuse it for several projects.
Also, gives you lots of stuff already out of the box. With the official Salesforce tool, you've connected to, I don't know, ten orgs, for instance. Well, all these connections are already done and given to your plugin. You don't have to handle connections anymore. This is part of the framework given by the CLI from Salesforce.
And so you will have access to your username, your connection. You can just with one line do a a SQL query to your org. You have some UI sugar, like a spinner or whatever. So don't go for a specific script in whatever shell or proper shell or whatever. Just do a custom SFDX plugin. I think it's a way to go for this kind of script.
Next one is profiles.
Profile is still a little bit tricky to be honest, so it's not a one hundred percent solution, but let's see what we did.
How does it work? First, if you look at the metadata API documentation profiles are designed to retrieve and deploy access rights from components in the same package. If I retrieve a profile with one field, I will get the field level security for this specific field. But then if I retrieve it again with two other field, the first field will be removed from the XML and the two other one that I've just retrieved will be in XML file, which doesn't work very well with the X push and pull where it just partial retrieve each time.
So it's not easy to have a one hundred percent complete profile with all the access rights you want. So when you look at the documentation and blog posts from Salesforce, what you see is they recommend to move to permission set. And if you know how permission set and profiles are working, you may be like a really Because that doesn't really work for all use case. Why?
Permission ID is cool because if I retrieve a profile, if you give me the access rights from all the metadata I'm retrieving at the same time. But permission set, it will give me the whole permission set all the time. So no issues about stuff missing or I'm sure of what I will get into this permission set. But not everything is in the permission set.
The main thing missing is Persia Assignment. If you deploy only permission sets, you won't deploy all the page layout assignment from your construct to your product and some other stuff like the default application or default record type for an object. And actually, this makes sense because you have only one profile. You can say this is a default application. But if you have ten permission set, that's where each permission set says, hey, this is a default application, there is no default application anymore. It will never be in the permission section.
So you have to find out as a way to on this kind of stuff.
So what we did is, so first, we are moving everything we can to a permission set. So it's already a lot of things. User permission, field permission, object permission, etcetera, Apex class permission.
I guess the link to a very good blog post from Salesforce developer that lists all the metadata. Well, all the tags in the profile metadata. And it will tell you if it's possible to move it to a permission set on that. So you can see what was on my previous slide, which is a few stuff like a layout assignment that are not available in permission set.
So first, helps you to move everything you can to permission set where you will be sure you will never have any user issues with this kind of thing. But then what about the remaining like page layout assignment? So we created a custom SFDX plugin, which is in our textile custom plugin, which is you can still link on GitHub. It's an open source one and you can use it for free.
And so how does it work? So I called it skinny profiles that you be sure that when you use it, you are not expecting to retrieve a full profile.
So the idea is really you move everything you can to permission set, but then I still need to retrieve all the other stuff.
But there is no way with the metadata API to get the full profile, except if I retrieve everything that I need at the same time. So what the command is doing, it's either it's reading your local repo and looking for all profiles, record types, apps, and layouts it will find in your repo. Behind the scene, it will create a package. Xml and retrieve everything. And at the end, it will only save in your local files as a profile you requested and the access rights that are profile specific, which are page data segment and default type and default app. And all the other stuff that could bring in the profile that you don't want because it's part of the permission set, it should be removed.
With this command, you are sure that you will get the profile you want. So it's not one hundred percent perfect because that means that at the end of your work, before committing everything, you need to think about running this command manually, otherwise you may miss some stuff.
There are some other things also that when you create a profile from scratch the first time, if some permission are not part of the metadata, Salesforce will just set them to true by default. So you may have a little difference with this command.
While it's open source, I was thinking of maybe adding some stuff to false anywhere to be sure they're under checked in production.
It's open source, so you can try to use it and try to do some pull requests if you think you have a good way to improve it.
This way, we tried it on, I think, two projects for now and it was working. Again, I said it's one hundred percent perfect, but it's still better than solution from Salesforce, which is not just profile.
So just one last topic on a very specific issue Salesforce is so I'm often using pre or post push to avoid some Salesforce bugs. So there are some strange stuff from time to time. I don't really know when, to be honest.
When I deploy everything in one shot, I will get an error saying that there is no record type ID field because I think that in the same deployment, I don't know how it gets deployed behind the scene, but maybe the record type ID field for a new object isn't created before some other metadata, you can't see it or whatever. So from time to time, I'm just doing a prep push before my whole push of all my metadata to just create the record type ID and then I can push everything else. So there are some other stuff, but I will have a specific look on the standard value set.
For instance, I'm working with some orgs that are in French.
When I go to production, if I go to a standard value set, let's say opportunity status, So I will have a label.
So Gagne means one.
So you will ask two things, the label on the API name. So in my production org, obviously the label and API name are the same here. It's Gagne and Gagne.
But the thing is that when I create a scratch org, when I ask a scratch org to be created in French, that's not the way it gets created. It's created with Gagne as a label, but still one as the API name.
That doesn't work well with deployment because if I deploy Gagne and Gagne, which is the metadata from my production environment to the scratch org, it won't replace the existing values in the scratch org. It will say, as there is already a value which has a label Gagne, but a different API name. I can't have two values with the same label. Do something with it and just it's crushed.
I think it's more like bug of the metadata API, but still it doesn't work. What you can do, what I'm doing, I don't say it's the best solution, but it's working. I'm doing a pre push like I did for the record type ID, and I'm just deploying.
So this is, for instance, opportunity status, a dummy value. So what we do, will deploy this value in the scratcher. So Gagne one will be just deactivated, and the value in the scratch chart will be my dummy value, and then I will be able to deploy my real metadata into the scratch chart. So obviously, this kind of trick is not perfect, but it's working. It enables you to create the scratch chart, And obviously, as a DX is getting better and better release after release, this is the kind of thing that I will just remove as soon as I get as I get fixed.
So one last slide, which is you should really go to the community. So if you interested links are the metadata coverage reports.
So you can see all metadata from Salesforce and you can see is our support team in the metadata API in a lot packages in the source tracking is there is no issues or not. It's really useful and you can filter per API version.
Next is CLI issues and GitHub. So there a specific repo from the CLI where there is no code inside. But if you see an issue on any CLI command from Salesforce, you can go there and create an issue on this specific repo from Salesforce and they are looking at it and trying to fix it. Hopefully, they will open source of CLI at some point, but in the meantime, it's a good opportunity to give feedback to Salesforce team without going to creating the case all the time. Well, the good thing is to do both actually create a case and go to get up crazy issue. And then there is a trailblazer community where there is a DX group where you can ask your question because there are already lots of people like me and some other that may answer you. Otherwise, people from Salesforce are looking at it and can can help you maybe with your with our issues.
So just a small recap of what we've seen here. First thing is really don't overthink. Start doing stuff even even if it's perfect. If you're at one hundred percent, you will never never do it.
Don't put everything in your report, look at what you really need and what may be clean from the production org. You need to script what you need because that's a good opportunity to avoid some manual steps you may have today in your org creation or deployment. And then go to the community to ask a question and also share your workarounds if you found some for your issues. And that's it. Thank you.
Thank you Fabienne.
I have a couple questions on that duplicate, just to get an idea of how responsive Salesforce is. That duplicate label thing you showed, yay yay and then one, that looks like just a bug, right?
Yes.
Have they acknowledged that as a bug and given a timeframe that it's gonna be fixed or No.
So I think I created a case for almost every issue I found I never really got any timeframe or anything for this kind of stuff. I don't know how it works behind the scene.
For instance, this standard value sets, which are a standard Salesforce pick list, they didn't get a lot of love recently. So there are still some standard pick list that don't have any API. So I think that like for instance, contract status, if you have some custom values, there is no API for the field. You just need to either do it manually or create a script with Puppeteer or Selenium or whatever tool you can script is better than nothing.
I guess they should fix this kind of stuff. But they also need to first complete all the missing APIs for this kind of metadata. So maybe we'll get there, but I didn't get any answer for when it should come.
How about the Have you reported any command line CLI bugs? Have you found gotten to their GitHub? Do you find that they're fixing that more quickly?
Yeah. So Yeah, exactly.
So I think that they are more responsive on the CLI GitHub repo.
I don't know if it's because from other stuff, I'm going to case and support, maybe it's slower to get to the engineering team. Whereas when you go to GitHub, they're answering quite fast. That doesn't mean that they will fix it immediately because from time to time, it's just depending on another team. If it's on Salesforce server side, they just need to wait for another team to fix it and deploy it in the next release or two.
So it could be slow anyway. But you will get some answer, actually. So maybe they will just tell you that you will need to wait for three months, but at least you will get an answer. So it's definitely a good place to go.
And there is already one part of the CLI that is open source, so not everything but one small part. And you can just I think I fixed one issue mostly for fun to play with it. I was able to do a pull request and fix the issue myself. So fully, once I open through the whole CLI, that doesn't mean that you have to fix all Salesforce bug yourself, but if you need to lose five hours to create a case and do call with the support and everything, from time to time for small bugs, it would be easier to just fix it yourself with a pull request.
Right, right, great. Well, thanks so much for the presentation. I wanted to let everybody know, anybody who's watched this presentation, haven't watched the presentation that was given by Bash in.
Bash is a developer or administrator and he gives an overview of Salesforce DX. So those two presentations complement each other. So thanks again Fabienne, it's a great presentation, great real world knowledge about Salesforce DX.
Thank you for having me.