Patch organizations

Just a short note on the “Patch Organization” feature that I used today for first time. Having got this turned on in your packaging org by logging a case, this extra “Patch Organization” tab appears for your package:

This gives you the ability to clone the source code of any version of your package – 3.22 in this screen shot – into a new org (that keeps the same namespace) and then modify it to create new versions e.g. 3.22.1, 3.22.2 etc. These versions can then be packaged and distributed in the normal way. So you can provide small fixes to customers that are using one version of your package while isolating those customers from other changes as your package evolves. But note that there are limits on the changes allowed – this is not a full-blown branching mechanism.

For more information, see e.g. the ISVforce Guide.

Advertisements

“Check all” in permission set and profile UI

I just started using the new permission sets mechanism. The first setting I needed to make was to enable full create, read and edit permission on a custom object that has 34 fields. Naturally the permissions default to unchecked. Checking three check boxes for the read/create/edit object-level permissions was one thing. But having to check close to 68 check boxes for read/edit field-level permissions was another. Across the 30 or so custom objects we use there are close to 1000 fields and with several permission sets needed overall thats an awful lot of tedious clicks and a step towards RSI.

The problem is that there is no “check all” feature for the field-level permissions, even though the UI is brand new. Supporting large scale development requires specific consideration – here are some examples from Eclipse’s past: large-scale development issues – but that does not seem to be a priority in the Force.com web tooling. Another example of UI that is painful when the scale goes up is picklist value deletion. This involves several clicks per value, not a problem if you are deleting a few values but a while ago I needed to delete a few hundred values…

The work-around I am using for the permission sets is to use the Check All extension to Chrome. This adds a button to the right of the URL text box that displays a menu that includes “Check All” and “Uncheck All” options that apply to all check boxes in the current page. Not perfect but better than nothing.

Note that if you have a small number of profile or permission set changes to make across many profiles or permission sets this Editing Profiles Using Profile Lists mechanism should help.

Continuous integration performance problem and solution

The performance of one of the orgs that we use for Continuous integration had never been good and as we added unit tests became more and more unacceptable. With 224 tests added, each “build” (each deploy and test run) was taking 75 minutes, about 10x longer than expected. The performance problem could also be repeated when just interactively running a single test.

Thanks to Salesforce Partner Premier Support we now have the problem worked around. The cause of the problem was the pattern we use to access custom settings in our Apex code. We reference custom settings via a class that initializes each setting to its default values if Manage/New has not been used on the custom setting in the org:

global with sharing class CustomSettings {
    global static DateConversionFactors__c getDateConversionFactors() {
        if (DateConversionFactors__c.getInstance() == null) {
            upsert new DateConversionFactors__c(SetupOwnerId = UserInfo.getOrganizationId());
        }
        return DateConversionFactors__c.getInstance();
    }
    // Other similar methods for other custom settings
}

This approach allows code that references custom settings to be cleaner because that code will never be supplied with a null object; it also avoids customers having to manually set up all the custom settings.

In a normal org (where the custom settings have not had Manage/New used on them) the upsert only happens the first time the method is called. But if the method is called in a unit test, the upsert is automatically rolled back at the end of the test method so that the upsert overhead is incurred every time the method is called. With a typical unit test creating multiple objects, the triggers on those objects referencing multiple custom settings, and each custom setting upsert taking about 3 seconds to upsert (for whatever reason), this overhead was killing performance.

The work-around was simple – just use Manage/New interactively on every custom setting in the org. The result: 10 minutes to run the build instead of 75 minutes.