Salesforce, Python, SQL, & other ways to put your data where you need it

Need event music? 🎸

Live and recorded jazz, pop, and meditative music for your virtual conference / Zoom wedding / yoga class / private party with quality sound and a smooth technical experience

Deploying Salesforce Field and Object Profile Permissions Without Blowing Up Your Org

16 Oct 2019 🔖 salesforce vscode
💬 EN

Table of Contents

I can’t remember if it was at Forcelandia or on Twitter, and if it was Bonny Hinners or another woman, but I remember hearing an #AwesomeAdmin mention that “change sets are just packages” and that while she grouped things she’d like to deploy from one part of Salesforce to another using Outbound Change Sets, she never used Inbound Change Sets to do the deploy.

Let’s see how that works in practice.

Background

We have about 20 custom profiles in our org, all of whom we want to stay on Classic for a while.

In advance of Winter ‘20, we painstakingly un-checked the Lightning Experience User permission for each and every custom profile in our Production org.

Unfortunately, we didn’t repeat ourselves for every single profile in every single sandbox.

Last week, we deployed several Change Sets from sandboxes to our production org that included new custom fields.

To avoid boring work manually setting permissions for the custom fields, we also made sure that the Outbound Change Set included not only the fields in question, but all Profiles who were supposed to be able to see them.

  • Q: That’s how we could deploy the field-by-field read/edit permissions for those Profiles to production, right?
  • A: Right … and a whole lot of other details about those profiles in addition to their field-by-field read/edit permissions (like whether “Lightning Experience User” was checked).

Ugh.

But there’s hope!

Next time we have a Change Set that includes enough custom fields that we want to deploy their profile-based read/edit permissions, rather than manually checking boxes after deploying the fields on their own, read on to learn what we can do to avoid deploying unwanted aspects of Profiles as part of an Inbound Change Set.


Build an Outbound Change Set

There’s nothing new to learn about building your Outbound Change Set.

The org I’m screenshotting is an “Admin Essentials for Experienced Admin” training org because I’d rather not screenshot my own corporate org, and I need to screenshot org with change set capabilities.

It comes with a custom object called Candidate__c:

Screenshot of the Candidate custom object

On that object is a custom field called Previous_Experience__c set to be editable by all profiles that come with the training org:

Screenshot of the Previous Experience field permissions before changing them

I changed the permissions for Previous_Experience__c to be inaccessible to most profiles, but read-edit for System Administrator and read-only for Read Only.

Screenshot of the Previous Experience field permissions after changing them

  1. Build your Outbound Change Set in a Sandbox (I think you might have to click “Upload” to say that it’s done – not sure – but even if so, you can ignore that you did so – you won’t be importing it with Production’s “Inbound Change Sets” functionality) and then use Workbench via the to get a ZIP file of it.
  2. Go through every “.profile” file in the “profiles” folder of that ZIP file with Notepad++ or even just Notepad and edit it to get rid of anything that isn’t a or tag. (They’re in alphabetical order, so this is a simple highlight-backspace operation).
  3. Save your changes and re-ZIP up the folder.
  4. Log out of Workbench and log back into it with Production (or a higher-level sandbox) and go to https://workbench.developerforce.com/metadataDeploy.php and upload your ZIP file (rather than accepting the original change set via Inbound Change Sets). a. Note: no need to re-do steps 1-3 if you have multiple orgs to deploy it to. Just repeat step 4 for every org you need to deploy to.

I’ve heard people talk about this before but finally had an “aha” moment about what they were doing.

This adds 5 minutes to the usual “change set” process but should make it foolproof with respect to profiles.

There’s one awkward thing to get used to: your deployed changes no longer show up in “Inbound Change Sets.” Instead, they only live in “Deploy History.” I’m pretty sure they should still have names, rather than awkward ID numbers, though, matching the outbound change set’s name.

If you like the “Inbound Change Set” visibility and want to add 5 more minutes, one other thing you could do is do steps 1-3, but in addition to the things described in step 2, delete all the folders except “profiles,” and edit “package.xml” to contain nothing but the “types” tag for “Profile,” as your step 2. That way you’ve built a deployable ZIP of profile field & object permissions only – nothing else. Then go clone your change set from #1 and delete all the Profiles out of it. Then deploy that profile-less clone through “change sets,” and deploy your “profile-only” ZIP through Workbench.

Let me know if you want me to do a 15-minute demo!

Before turning on Lightning Experience

Join me for a journey as I refactor Salesforce Apex trigger handlers, working for cleaner code (fewer “smells”), better implementation of good design principles, and increased use of enterprise-appropriate design patterns.

I started KatieKodes a year ago because I felt I was “outgrowing” my first blog, which was a bit of a public diary as I … to be honest … kind of learned to code on the job.

Inspired by Women Code Heroes, Practical Business Python, and [Real Python](https://realpython.com/}{:target=”_blank”}, I wanted to start over and produce something more “professional.”

I wanted a repository of confident “here’s how you do this” demonstrations and tutorials that I could comfortably include in a resume to show what I already know.

Who knows – maybe at some point, I’ll shuffle these posts away to the old “diary” blog.

But for now, I’m going to be vulnerable and expose my “code smells” as I chronicle my journey to refactor old trigger handlers and write new ones better.


For years, I’ve returned again and again to Dan Appleman’s Advanced Apex Programming.

I eat up sessions like his and Robert Watson’s Dreamforce 2016 session It’s About (CPU) Time: The Dark Art Of Benchmarking.

Don’t be afraid of running multiple for loops over Trigger.new!!!

Take the time to learn what does what, with respect to parameter-passing by value or reference.

For example, String parameters pass by value, not by reference; this passes the asserts:

string doThing(String inString) {
    inString += 'bye';
    return inString;
}
String myStr = 'hi';
String myStr2 = doThing(myStr);
System.assertEquals('hi', myStr); // DID NOT GET MODIFIED
System.assertEquals('hibye', myStr2);
--- ---