Creating a Bitbucket Server plugin is great, but if you’re like me, you probably immediately find yourself wanting to know not how to get into a code file, but rather how to get something to show up in the server.
If you have to write the entire plugin without ever once testing it, that would be a terrible experience both for you, and for the server administrator that has to deal with you.
Luckily, Atlassian has considered this problem.
We’re first going to create an actual Bitbucket Server plugin. Next we’ll fix some issues that exist within the template. Finally we’ll look at running and debugging the plugin. We’ll do all of this before we start trying to understand any of the code. This way you wont be lead through the process of learning esoteric code objects before you even know how to run the code.
Also, if you’re lead through the process of making a plugin and then at the end you run it for the first time, you you will have undoubtedly made a mistake and you’ll be more frustrated with your learning path.
Create the plugin
Since we’re good and have already set up our development machine, we’ll just get right into running commands
1 |
atlas-create-bitbucket-plugin |
This will start asking you a series of questions
GroupID
This is your artifact group. It corresponds to your maven groupid
If you still don’t really know what that means, and you don’t do a lot of Java development, Maven is a build and dependency management system for Java. Think of it as something similar to mashing MSBuild + Nuget or LLVM + Cocoapods together into one thing. Or some other build system and dependency management system if you don’t do c# or iOS.
If you do Android, then think of Maven as Gradle (and ignore the fact that Gradle was largely created to replace Maven)
When you add a dependency to your project, you’ll have a block of xml like this
1 2 3 4 5 6 |
<dependency> <groupId>com.atlassian.bitbucket.server</groupId> <artifactId>bitbucket-api</artifactId> <scope>provided</scope> <version>${bitbucket.version}</version> </dependency> |
The group id is basically “who is the organization that is creating this thing”
ArtifactId
This is the artifact id. If you paid attention to the blurb above, you’ll see it right inside of the xml clip.
Within a group, you will publish different artifacts. So think of this as “Which specific product that my organization publishes is this”
Version
Version of your plugin. Default is 1.0-SNAPSHOT
Package
This one is the actual package that your code is going to live in. If you’re not a Java expert, this one right here is your Namespace
I didn’t feel like being creative, and I thought it might be useful to see where these things come into play while we poke around. So i just used groupid, artifactid, and package_name for the GroupID, ArtifactID, and Package, respectively. The version I kept default.
In a normal plugin you’d want to do something more along the lines of
1 2 3 |
com.company.department name_of_plugin groupid (default) |
But the most important thing to know of all, if you’re building a plugin for yourself, that isn’t going on the Atlassian Market, It doesn’t really matter too much what you put.
Fix some issues with the template
Now that we’ve spent far too much time discussing the answers to the terminal prompts, let’s go ahead and fix the mistakes Atlassian made.
At this point, we’re ready to go ahead and open the folder up in our IDE of choice. And we’ll take a look at the pom.xml
file.
This file is telling Maven how to build our product. And somehow it’s wrong already.
Bitbucket Server Version
How in the world did they make a command that asks us so many questions without asking what is arguably the most important one. What version of Bitbucket Server are we even trying to make the plugin for?!
When you run the command, it’ll just be on whatever version was new at the time. For me, its 5.16.0. But when you’re building a plugin in an enterprise environment you probably don’t have control over what version of Bitbucket Server you’re on. And you probably don’t have too much say when it comes to getting the whole company to update the server just because your plugin defaulted to a particular version
In pom.xml
just look for the xml tag <bitbucket.version>
and change that to whatever version your server is actually running.
When we get around to running the plugin later, the locally running Bitbucket Server will even run this same version.
Why doesn’t it build?
If you’re like me, you saw the sentence saying to open the project in your chosen IDE, and ignored everything else got really frustrated that it didn’t compile and then looked over and saw this header.
I believe that if you exclusively compile and run from the Atlassian SDK that everything will work (for now) but if you want to have any kind of autocompletion or happy good IDE features, you’re going to want to fix the pom.xml
dependencies
First off, when the IDE does a maven restore or whatever it’s called, it will fail. Immediately. The reason is because it’s missing the repositories. It’s like if you were to publish a nuget package to your own locally hosted repository, and then you hadn’t added it to the list of sources for nuget to look through. Nuget would look at nuget.org, and maven would look at… maven.something. Look, I’m not a Java person, ok? I know Java, but that doesn’t mean I know everything in the Java ecosystem.
Add this wherever you is convenient in pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<repositories> <repository> <releases> <enabled>true</enabled> <checksumPolicy>warn</checksumPolicy> </releases> <snapshots> <enabled>true</enabled> <updatePolicy>never</updatePolicy> <checksumPolicy>warn</checksumPolicy> </snapshots> <id>atlassian-public</id> <url>https://maven.atlassian.com/repository/public</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <releases> <enabled>true</enabled> <checksumPolicy>warn</checksumPolicy> </releases> <snapshots> <updatePolicy>never</updatePolicy> <checksumPolicy>warn</checksumPolicy> </snapshots> <id>atlassian-public</id> <url>https://maven.atlassian.com/repository/public</url> </pluginRepository> </pluginRepositories> |
I put if after all the config stuff, and before any of the dependencies, but i don’t know if Maven cares about order or not. I put it there, and it worked. I’m not going to Google _everything_1 for you.
After that, you’re going to need to find your dependencies and put this one in too
1 2 3 4 5 |
<dependency> <groupId>com.atlassian.bitbucket.server</groupId> <artifactId>bitbucket-page-objects</artifactId> <scope>provided</scope> </dependency> |
If you don’t do that, you won’t be able to compile once you start putting the dependency injection annotations in.
atlassian-plugin.xml
At this point, we should be able to compile, we should have no more red squiggly lines in the code, and we should be fairly happy.
However, it is at this point, right before we talk about running and debugging, that I want to take a moment to talk about the atlassian-plugin.xml file
This file is what tells Bitbucket Server how your plugin ties into their plugin architected application.
You can write as much code as you want, but if you don’t tell Bitbucket Server what to do with your code, it just won’t do anything for you.
Because we haven’t put anything in there yet, there’s just going to be the default from the template. Which means there’s really nothing to see when we run, and no code to debug. Or at least not that i can figure out where is in bitbucket server.
Run
From within the directory that was created by atlas-create-bitbucket-plugin
you need to run the command atlas-run
If you are not in the same folder, you’ll get an error about maven not knowing what to do. That’s because you have to be in the same folder as the pom file.
The first time you run this, it will take a while. Now’s a good time to get up, stretch, get a coffee, whatever floats your boat.
Once the command is finally done, open up a browser to
http://localhost:7990/bitbucket Log in with admin/admin
There’s already a project and repo that should be created by default. You can also create new ones as needed. You now have Bitbucket Server running locally with the plugin that you (sort of) created!
Debug
From this point, debugging couldn’t be simpler. Unless it was, in which case, it would be simpler.
You likely noticed that we used the terminal to run atlas-run
instead of clicking run in our IDE. I think that technically some IDEs can be configured to do atlas-run
when you click run, but that will depend on your IDE.
To debug, you also can’t just click debug. Instead what you’ll have to do is run atlas-debug
and configure your IDE to attach to a remote debugger.
Atlassian has good enough directions for this here. If you’re using IntelliJ then follow the directions for “IDEA”
Once you create a debug target, you just have to run atlas-debug
and then click debug in your IDE. It’s really quite simple.
It is unfortunate that there’s nothing to see, and nowhere to debug right now, but we do now know how to run and debug. We can also build, and as we work through the process of creating an actual plugin with real code, we’ll go in with the knowledge of how to build and check things along the way.
Can we take a moment to talk about how _this_ is a much better emphasis than this. Why are italics even a thing? they don’t emphasize things, they look fancy ↩