We're developing applications for AppExchange and are trying to figure out the best way to do development and release management. There are several issues around this:
1) Package Prefixes. We are developing code in unmanaged mode and releasing as managed, so we have to add all the package prefixes into the code. Is there a way to do this dynamically at runtime? Right now we're开发者_JAVA技巧 using an Ant script, which stops us benefitting from the force.com IDE plugin.
2) Resource files... We are doing some ajax-ey stuff and as a result have a few different resource files we upload, some of which are multiple file resources (zip files). Has anyone automated the building of these resources using ANT, and does that work well?
Our environment seems very fragile and works for some developers and not others; have other people had this problem? How did you resolve it?
I hate to say it, but it sounds like you've settled on the best approach that I know of. The Salesforce packaging environment can be a total nightmare to work with. Once your managed package has a prefix, there's really no going back to a plain package without one unless you script it like you've done. So you'll find the package name peppered throughout your code, which the system will add for you.
I've found the best way to work with it is to keep a "pure" version of your app, which will install cleanly into a dev org from within Ant. Once you have the code in Ant, it can be added into "normal" source control. It doesn't seem like too many larger scale apps have been built in Salesforce with multiple team members, because as far as I can tell, there isn't much support for a workflow that includes source code control. They tried adding some type of release management to a dev org configuration, which is now in beta, but it didn't seem that good at all.
I think Ant using the Salesforce Force.com migration tool is the way to go for the most part. Then, however, once you want to make a managed package, you're sort of stuck with that code base frozen, with that prefix, where you'll then have to do packaging releases (from beta, etc) from within the packaging system itself. The best way there is to refresh to sandbox (hard limit of once a month!!), then have developers pull out of that sandbox and deploy into individual dev orgs, which then can be merged periodically into a "group dev org", before deploying back into the Sandbox (using Force.com IDE or Ant), then into Production.
The whole process is basically a complete disaster. Salesforce is so close to having a super powerful platform, but a lot of the time feels like an awesome sports car without a steering wheel.
As far as static resources, those you should be able to automate in a relatively straightforward way using Eclipse, so that you can deploy those separately in one step. The API should support it, too.
I have worked on some rather large Apex code bases (I think, and hope), and there is really no apparent elegant solution, I'm afraid. You'll be stuck with strange combinations of deploying using Ant in some cases, Eclipse others, etc.
Coming from other development environments, it's often befuddling and just strange. For example, it's perplexing that you can't easily dump the database in one step while keeping track of relationships between objects and then "import" it into another org in one step. We actually had to write a tool that would make it easy to extract all data while traversing object relationships, load all data, recursively delete data, etc. from a xls file because we needed an easy way to test in orgs.
BTW, dev orgs are basically throw away orgs. We create dozens of them for different testing purposes and to keep different versions and configurations.
Sorry I couldn't give you better news. There might be more of a guru on here who can point to an elegant way to manage packaging, and I'll be as interested in you as the answer! You can email me at suprasphere --- at --- gmail if you want to commiserate! :)
We've recently switched to using a Prefix Manager instead of doing ant substitutions.
Here is our code.
public class PrefixMgr {
private static string objPrefix = null;
public static string getObjPrefix() {
if(objPrefix == null) {
try {
Database.query( 'select MyColumn__c from my_prefix__MySmallTable__c' );
objPrefix = 'my_prefix__';
}
catch(Exception e) {
objPrefix = '';
}
}
return objPrefix;
}
public static string getAppPrefix() {
return 'my_prefix__';
}
public static string getObjName(string inp) {
return getObjPrefix() + inp;
}
}
Basically this attempts a query (one time) against a table with the prefixed name. If it does not exist, then we are in unmanaged mode with no package prefixes. If it does succeed, then we set the prefix appropriately. getObjName is a convenience because PrefixMgr.getObjName('MyObject__c')
is easier to read (esp in a string concat) than PrefixMgr.getObjPrefix() + 'MyObject__c'
.
Interested in thoughts and comments.
精彩评论