9

In my managed package I have a Setup page that should only display setup steps relevant for the currently installed version of my package.

I know in InstallHandler implementations there are way to ask for the Version but how would I do that from a regular Apex class?

3 Answers 3

12

You can use System.requestVersion, which returns the version of your package. See Version for more details, but I'll also include the snippet from there here:

if (System.requestVersion() == new Version(1,0))
{
    // Do something
}
if ((System.requestVersion().major() == 1) 
     && (System.requestVersion().minor() > 0)
     && (System.requestVersion().minor() <=9))
{
    // Do something different for versions 1.1 to 1.9
}
else if (System.requestVersion().compareTo(new Version(2,0)) >= 0)
{
    // Do something completely different for versions 2.0 or greater
}
2
  • 3
    And what if patch version is installed (e.g. 2.1.12). Is there any way to get the last segment, i.e. patch portion (.12) as well right from Apex? According to docs System.requestVersion().patch() always returns null.
    – wesaw
    Feb 1, 2018 at 16:23
  • NB: This is not compatible with 2GP.
    – Phil W
    Jun 23, 2022 at 9:15
4

Because System.requestVersion (see @sfdcfox's answer) throws an uncatchable exception on a scratch org for package development, you cannot use this code on that scratch org and any unit tests covering such code will fail. See this idea for details.

The documentation for Version actually states (up to apex API version 55 at least):

The value returned by the System.requestVersion method is an instance of this class with a two-part version number containing a major and a minor number. Since the System.requestVersion method doesn’t return a patch number, the patch number in the returned Version object is null.

Since System.requestVersion().patch() is thus always null, you may want to just do a namespace prefix query like this:

SELECT MajorVersion, MinorVersion FROM Publisher WHERE NamespacePrefix = 'namespace'

It is also worth noting that System.requestVersion is not compatible with 2GP managed packages, as covered here.

In the scratch org this will return 0 and 0, but at least that is better than suffering from an exception and having to do special case code to avoid uncatchable exceptions as covered in this other Q&A.

For the specific handling for a post-install page, where you want to guarantee having the patch version, I would suggest you update your installer to save the version it is given in a protected custom setting or custom metadata type record so you have full detail.

2

For 2GMP instead of using System.requestVersion() it is possible to create some custom logic to store the value of Version in PostInstallContext into some protected custom setting.

Then, when needed, the current package version can be read from that custom setting.

Another option would be to maintain the package version as a constant in some apex class and update that line with CI on every package version creation step.

Also, if you have access to Session Id and Tooling API, it is possible to perform Tooling Api query

SELECT Id, SubscriberPackageId, SubscriberPackage.NamespacePrefix,
    SubscriberPackage.Name, SubscriberPackageVersion.Id,
    SubscriberPackageVersion.Name, SubscriberPackageVersion.MajorVersion,
    SubscriberPackageVersion.MinorVersion,
    SubscriberPackageVersion.PatchVersion,
    SubscriberPackageVersion.BuildNumber 
FROM InstalledSubscriberPackage 
ORDER BY SubscriberPackageId

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.