Upgrade to Bitbucket Server 4.0
This page describes how to migrate from Stash to Bitbucket Server 4.0. Release 4.1.2 is the first release that is compatible with Bitbucket Server.
Bitbucket Server is the next evolution of Stash, however Atlassian have taken it as an opportunity to bypass their usual API stability policy. As such, you will have to modify your scripts. Atlassian have intimated that this is a one-time change, and after this there will be several years of low friction in the API. If you don’t have any custom scripts, and are only using the simple conditions that come as examples in the plugin, you may well have nothing to do.
If you have any issues please contact us via our Service Desk.
This page is split up into a suggested upgrade procedure, and the possible areas you will need to change.
At the time of writing, the official page explaining the upgrade procedure is here, although there is currently permissioning on this page.
How to Upgrade
First you should create a clone of your production system that you can do a practice upgrade on. Creating staging systems is not well documented, but there is enough information in STASH-5271 and on this answer.
Once you have the staging system created, upgrade it to Bitbucket Server 4. Then install the ScriptRunner plugin.
The static type checker that was recently introduced to ScriptRunner for Jira is now available in ScriptRunner for Bitbucket Server, so you should be able to see quite quickly if you have any problems.
You should open each admin page that lists each extension point, eg pre-receive hooks, listeners etc. Look for code highlighted with red errors, and fix them
The condition script is not currently shown in the overview page, so click edit for each listener or hook etc, and check that the condition shows the green dot of successful compilation.
Test
If practical, test your most important scripts and conditions in your staging server.
Production Upgrade
Finally, make sure that your maintenance window includes enough time to do your production upgrade, and then the modifications to the scripts that you have already tested in your staging server.
Areas of Change
This is not a definitive list, for that see the Atlassian guidelines. However, these are the changes I think you are most likely to have to make.
Package Names
Packages have been renamed from com.atlassian.stash
to com.atlassian.bitbucket
. This will affect you if you have custom scripts, or conditions, that import any classes.
If there are errors in your scripts you will see something like:
You can correct that in this case by just replacing the word stash
with bitbucket
.
Some event classes have changed package too, for example com.atlassian.stash.event.RepositoryCreatedEvent
has moved to com.atlassian.bitbucket.event.repository.RepositoryCreatedEvent
, that is, it’s moved under the repository
package. Same for project events
Another example. If you were using the condition to check a user was in a group, it may have been:
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.stash.user.UserService
import com.atlassian.stash.user.StashAuthenticationContext
def userService = ComponentLocator.getComponent(UserService)
def authContext = ComponentLocator.getComponent(StashAuthenticationContext)
userService.isUserInGroup(authContext.getCurrentUser(), "project-creators")
Now it should be:
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.bitbucket.user.UserService
import com.atlassian.bitbucket.auth.AuthenticationContext
def userService = ComponentLocator.getComponent(UserService)
def authContext = ComponentLocator.getComponent(AuthenticationContext)
userService.isUserInGroup(authContext.getCurrentUser(), "project-creators")
Class Names
Some classes have changed names, for example RepositoryMetadataService
has become RefService
. StashUser
is now BitbucketUser
.
KeyedMessage Behavior Change
com.atlassian.bitbucket.i18n.KeyedMessage
is used to cancel events in listeners. The signature is KeyedMessage(String key, String localisedMessage, String rootMessage)
.
The first parameter is the key, which is used for translating the messages into different languages. Typically in scripts you do not bother with localization, so previously you may have written:
event.cancel(new KeyedMessage(null, "some message", null)
Now all parameters are mandatory, so I suggest you use:
def msg = "some message"
event.cancel(new KeyedMessage("dummy", msg, msg)