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

13

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
    Commented Feb 1, 2018 at 16:23
  • NB: This is not compatible with 2GP.
    – Phil W
    Commented 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'
    ORDER BY MajorVersion DESC, MinorVersion DESC
    LIMIT 1

The reason for the ORDER BY is that sometimes Salesforce reports both a (0, 0) version and an (x, y) version when it should only report the latter.

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

We 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
2
  • 1
    The post install context's version is the "old version" you are upgrading from. There's no access to the version being installed in the post install script unless you hard-code it in your apex or in some custom metadata that is part of the install.
    – Phil W
    Commented Jul 24, 2023 at 10:38
  • 1
    good point. Actually we ended up hard-coding version in the code and autoincrement it by ci/cd process
    – Patlatus
    Commented Jul 25, 2023 at 11:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .