[SalesForce] AppExchange Private Listing

I have an app which has a base managed package and two extension packages. I used three developer editions to develop these three packages. We don't want a public listing on the AppExchange for our app, so I didn't go through the ISV partner process initially. Now, we are planning to add more components and functionalities to our app in the future. But recently I realized that I can't push upgrades with these developer editions. So, I've been going through the ISVForce Guide and have created a Partner Developer Edition and migrated all of the base package components to this org, and created two Partner Developer Edition orgs for the two extension packages. I've been struggling with some questions on this process for which I couldn't find answers online. Can I list all three packages (1 base and 2 extensions) on AppExchange with one business org? If this is not possible, do I have to register our company as a partner three times and use three different business orgs (one for each package)? Can I still use LMA and push upgrades if the app is free and doesn't have a public listing? Does the app need to pass the security review before we can invite our clients to install this app from the private listing? I'd appreciate if anyone can let me know other limitations/headaches that I need to keep in mind here. Thanks in advance!

Best Answer

The Org Zoo

First you have to register only once as partner. Then I see really no need for your migration of the packaging org for your base-package. The one Enterprise Org is purely for administration usage and typically not for development. Usually you would like to install the LMA and use the Environment Hub there.

You can leave the developer orgs just where you started the development initially. If your ISV process is completed, you can simply log a case and the support will upgrade your original DE orgs to all the specs as if they would have been created via the hub or partner portal.

So to be clear: you need 3 DE orgs and not 1 EE plus 2 DE for the pure development of your app.

Push Flavours

If you have your partner process completed, you have this feature by default. Maybe you have to log an additional case for those of your DE orgs form you pre-partner-time. Unfortunately you get only a "light version" by default. Those push upgrades even for partners come in two flavors: Push-Minor and Push-Major. With push-minor you can only change existing components, which is in fact not very helpful for most use cases. And for push major - and that's the sad truth - you need to pass the security review.

You can read a bit more on that here:

Since I'm unhappy with that situation, I plan to development an automatic pull-upgrade mechanism which eventually might overcome this limitation. MetadateAPI should make it possible.

Extension Models

Now a few words to extension packages: in my experience the way the platform deals with extensions brings you more problems than benefits. You get dependent packages by installing the base package into the extension (DE) org and then starting to develop stuff there using components or apex of the base org. If if you update classes in the base org you need not only need upgrade the base package in the extension org, but also to manually update the version number. Developing simultaneously base and extension felt so uncomfortable and time consuming that I gave up this approach totally.

An other point you have to keep in mind is that you should try to have all your DEs on a single pod (like na9 or eu3). You find everywhere that it does not matter on which pod you are - but that's only the half truth. If you upload a package you get it immediately for install on the same pod. On all other pods, you have to wait 5 to 10 minutes before your installer-link becomes usable. If you need to upgrade it often, this will eat up a lot of time. To move orgs afterwards between pods is hard an will be mostly rejected by the support. Then you have to do it manually.

But instead I use a different approach for extensions. And I use it heavily and in many projects.

What I do now is to create a couple of independent packages - each one in a separate DE org. At least in the eyes of the platform I keep them unrelated. I get this by only touching the objects and fields dynamically and by the pure usage of dynamic SOQL. You can't do everything dynamically in Salesforce - but a lot! Apex helper classes I usually have as redundant copies in all orgs. In case of updates I deploy them to all orgs. I make extensive usage of the schema functions. Needless to say that I consume MetadataAPI and ToolingAPI like a junkie in all projects.

This part I can't really recommend for beginners but in my most recent projects I'm creating the entire data-modell dynamically using MetadataAPI/ToolingAPI after install. So even if the client uninstalls the packages - he still has his data in his org - without costly ETL or data-migration.

I also tend to write wrapper classes to get a less verbose apex code especially for the schema functions. The buildin syntax sucks. I published some of my helper classes here: https://github.com/UweHeim/xt

What you get is that the platform will become blind for your dependencies now. You can install, update and uninstall each packages as you like. The platform does not bother you any more by preventing it. Of course you can break now a lot things, of course as a tradeoff you loose all help from the platform and you have to deal with all unmet dependencies dynamically and on your own.

You can have a look at CodeFusion, which is a private managed package (as you like it) and has also two extension packages (as you plan). This is the base:

And here are the extensions:

This is a free and native developer IDE which I plan to opensouce in the future.

I try to keep the packages as loosly coupled as even possible.

Related Topic