Introduction
You are reading reference documentation for the Bamboo Java Specs library. The Bamboo Specs library allows you to define plan configuration as code and send it to Bamboo to have corresponding plans created or updated automatically. You can read more information about Bamboo Specs feature here. In case you are looking for detailed documentation about specific method or class, you can find it in Bamboo Specs JavaDocs.
Version information
This reference documentation is based on Bamboo Specs library version 6.4.0, which is intended for Bamboo version 6.4.0 and higher.
Feedback
In case you found a bug, would like to suggest an improvement or just would like to share your impression about this documentation, please do not hesitate to report it our issue tracker.
Bamboo Specs Reference
Go back to Bamboo Specs reference
Project
Project project = new Project()
.key("PROA")
.name("Project A")
.description("My Project A with all A-plans");
A project is a collection of plans. Projects enable you to easily group and identify plans which are logically related to each other. They are especially useful when generating reports across multiple plans.
A project:
- Has one, or more, plans.
- Provides reporting (using the wallboard, for example) across all plans in the project.
- Provides links to other applications.
You can create a new project when creating a plan.
Plan
Plan plan = new Plan(project, "My Plan One", "PLAN1")
.description("This is an example of a plan")
.enabled(true)
.stages(stage1)
.triggers(scheduledTrigger)
.planBranchManagement(planBranchManagement)
.dependencies(planDependencies)
.linkedRepositories(myGitRepo)
.planRepositories(myBitbucketRepo)
.variables(var1, var2);
A plan defines everything about your continuous integration build process in Bamboo.
A plan:
- Has a single stage, by default, but can be used to group jobs into multiple stages.
- Processes a series of one or more stages that are run sequentially using the same repository.
- Specifies the default repository.
- Specifies how the build is triggered, and the triggering dependencies between the plan and other plans in the project.
- Specifies notifications of build results.
- Specifies who has permission to view and configure the plan and its jobs.
- Provides for the definition of plan variables.
Every plan belongs to a project.
Plan branches
Plan branches are used to represent a branch in your version control repository, with the plan branch using the same build configuration as your plan. Tools such as Git and Mercurial encourage a practice called feature branching, where a developer can use a new branch to work in isolation from his or her team members before merging their changes back into main line development.
With plan branches in Bamboo:
- Any new branch created in the repository can be automatically built and tested using the same build configuration as that of the parent plan.
- Any branches deleted from the repository can be deleted automatically from Bamboo according to the settings.
- You have the flexibility to individually configure branch plans, by overriding the parent plan, if required.
- Optionally, changes from the feature branch can be automatically merged back to the “master” when the build succeeds.
You can create plan branches manually or automatically. The branch configuration can be provided on the plan level and customized on the branch level. The settings provided in the branch configuration override the settings provided for the plan.
Automatic branch management
Plan branches can be created and deleted automatically based on the updates in the primary source repository. Automatic branch management is available for Git, Mercurial, and Subversion. For other repository types, you can use manual branching. You can override the default settings for a branch, such as values of the variables. By default, automatic branch management is:
- disabled for branches that you create manually
- enabled for branches that are created automatically
You can specify how often Bamboo checks the primary source repository for new or deleted branches. The default value is 300 seconds. You can also override the branch deletion settings.
Handling new branches
Create new plans for new branches matching JIRA issue key. Build triggers are inherited from the master plan.
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new GitRepository()
.name("my-repo")
.url("ssh://git@bitbucket.org:my-company/my-repo.git")
.branch("master"))
.planBranchManagement(new PlanBranchManagement()
.createForVcsBranchMatching("^JIRA-[0-9]+")
.triggerBuildsLikeParentPlan());
- do not create new branches (default) - Bamboo will not create new plan branches automatically when new branches are detected in the primary source repository
- create for all new branches - to create a plan branch for each new branch detected in the primary source repository use the
planBranchCreation
method withnew PlanBranchCreation()
- create for selected branches - to create a plan branch for each new branch detected in the primary source repository that
matches the regular expression that you provided use
planBranchCreation()
with thenew PlanBranchCreation().matchingPattern()
Handling deleted branches
Create plan branches for all new branches in the repository. Delete plans 30 days after a repository branch is deleted.
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new GitRepository()
.name("my-repo")
.url("ssh://git@bitbucket.org:my-company/my-repo.git")
.branch("master"))
.planBranchManagement(new PlanBranchManagement()
.createForVcsBranch()
.delete(new BranchCleanup()
.whenRemovedFromRepositoryAfterDays(30)));
- do not delete (default) - if a branch in the primary source repository was deleted, Bamboo does not automatically delete the corresponding plan branch
- with a daily cleanup - if a branch in the primary source repository was deleted, the corresponding plan
branch is removed with a daily cleanup that happens daily at 3 AM (server time) - use
removedBranchCleanup
withnew BranchCleanup()
- after period of time - if a branch in the primary source repository was deleted, Bamboo deletes the
corresponding plan branch after N days - use
removedBranchCleanup
withnew BranchCleanup().periodInDays(N)
Handling inactive branches
Create plan branches for all new branches in the repository. Delete plans after 30 days of no activity on a repository branch.
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new GitRepository()
.name("my-repo")
.url("ssh://git@bitbucket.org:my-company/my-repo.git")
.branch("master"))
.planBranchManagement(new PlanBranchManagement()
.createForVcsBranch()
.delete(new BranchCleanup()
.whenInactiveInRepositoryAfterDays(30)));
- do not delete (deafult) - if a branch in the primary source repository is inactive, Bamboo does not automatically delete the corresponding plan branch
- delete after period of inactivity - If a branch in the primary source repository is inactive, Bamboo deletes the corresponding plan branch if no commits are detected for the specified period. The value must be higher than 0 and is specified in days.
Manual branch management
Create three separate plans for ‘master’, ‘release_1_0’ and ‘integration’ branches.
List<Plan> plans = new ArrayList<>();
for (String branch : Arrays.asList("master", "release_1_0", "integration")) {
Plan plan = new Plan(project, planName(branch), planKey(branch)).planRepositories(new GitRepository().name("my-repo").url("ssh://git@bitbucket.org:my-company/my-repo.git").branch(branch));
plans.add(plan);
};
Bamboo UI allows to not only set up automatic plan branch creation for new branches detected in a repository, but also to manually create plan branches for already existing ones. Bamboo Specs does not have an option to manually specify plan branches at the moment. You would have to use Bamboo UI to manually create branches after plan is created.
Alternatively, you could create separate plans for each branch. Keep in mind that using this approach you won’t be able to use Bamboo branch-specific features (for instance to see them on the “Branch view” page).
Automatic branch merging
Bamboo provides two merging models if you choose to automate your branch merging. Automatic merging has few limitations:
- it can only be used with Git and Mercurial repositories.
- it can only be used with branches that were configured in Bamboo
- it cannot be used with the Git implementation embedded in Bamboo - you have to set up native Git
Branch updater
Create a plan building the ‘master’ branch. Automatically create plan branches for all feature branches as soon as these branches are created. Merge the master branch into a feature branch and build the merge result. Push a merge commit into the feature branch on a successful build.
Plan plan = new Plan(project, "Features with master", "MASTER")
.stages(new Stage("Stage 1")
.jobs(new Job("Job1", "JOB1")))
.planRepositories(new GitRepository()
.name("my-repo")
.url("ssh://git@bitbucket.org:my-company/my-repo.git")
.branch("master"))
.planBranchManagement(new PlanBranchManagement()
.createForVcsBranchMatching("feature/.*")
.branchIntegration(new BranchIntegration()
.integrationBranchKey("MASTER")
.gatekeeper(false)
.pushOnSuccessfulBuild(true)));
A branch repository is kept up-to-date with changes to master. The Branch updater should be used when you want to:
- Automatically merge changes from the team’s master branch into your feature branch, after a successful build of the master branch.
- Get notified when the changes on your feature branch are no longer compatible with the team’s master branch.
Gatekeeper
Create a plan building the ‘master’ branch. Automatically create a plan branch for the ‘integration’ branch as soon as this branch is created. Merge the integration branch into ‘master’ branch and build the merge result. Push a merge commit into the master on a successful build.
Plan plan = new Plan(project, "Integration into master", "MASTER")
.stages(new Stage("Stage 1")
.jobs(new Job("Job1", "JOB1")))
.planRepositories(new GitRepository()
.name("my-repo")
.url("ssh://git@bitbucket.org:my-company/my-repo.git")
.branch("master"))
.planBranchManagement(new PlanBranchManagement()
.createForVcsBranchMatching("integration")
.branchIntegration(new BranchIntegration()
.integrationBranchKey("MASTER")
.gatekeeper(true)
.pushOnSuccessfulBuild(true)));
In Gatekeeper the default repository is only updated with changes in the branch that have built successfully. The Gatekeeper should be used when you want to:
- Automatically merge your feature branch back into the team’s master branch, after a successful build of the merged changes from both branches.
- Get notified when a build of combined changes from both branches fails, preventing the feature branch from being merged back into the team’s master branch.
Branch notifications
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new GitRepository()
.name("my-repo")
.url("ssh://git@bitbucket.org:my-company/my-repo.git")
.branch("master"))
.planBranchManagement(new PlanBranchManagement()
.createForVcsBranch()
.notificationForCommitters());
You can get build notifications from branch plans just as you do for master plans. You can choose one of the following options:
- notify committers and people who have favorited this branch
- use the plan’s notification settings
- do not send notifications for branches
Overriding branch settings
Whether a plan branch is created automatically or manually, the master plan maintains the structure and configuration of it’s branch plans. However, you can use Bamboo UI and go to the configuration pages to override settings in a branch plan, see Branch details configuration chapter for more details.
Plan permissions
PlanPermissions planPermission = new PlanPermissions(projectKey, planKey)
.permissions(new Permissions()
.userPermissions("user1", PermissionType.CLONE)
.userPermissions("user2", PermissionType.ADMIN, PermissionType.EDIT)
.groupPermissions("group1", PermissionType.CLONE)
.groupPermissions("group2", PermissionType.ADMIN, PermissionType.EDIT)
.loggedInUserPermissions(PermissionType.VIEW)
.anonymousUserPermissionView());
Plan permissions allow a user to control access to the functions of the build plan. These include viewing, editing, building, cloning and administering a build plan. These are the same permissions which can be accessed from the build plan configuration page.
- View - view the plan and its builds.
- Edit - view and edit the configuration of the plan and its jobs, not including permissions or stages.
- Build - trigger a manual build, or suspend and resume the plan.
- Clone - clone the plan.
- Admin - edit all aspects of the plan including permissions and stages.
Plan permissions can be set for:
- specific users
- specific groups
- logged in users
- anonymous users
Defaults
PlanPermissions planPermission = new PlanPermissions(projectKey, planKey)
.addDefaultPermissions();
Sets the plan permissions to defaults:
- VIEW for logged in users
- VIEW for anonymous users
Publishing
BambooServer server = new BambooServer(bambooUrl, userPasswordCredentials);
server.publish(planPermission());;
Plan permission is a top level Bamboo Spec entity (like Plan or Deployment) and needs to be published to the Bamboo instance.
Stage
Stage stage = new Stage("My Stage")
.description("This is a manual stage")
.jobs(job)
.manual(true);
Stages group (or ‘map’) jobs to individual steps within a plan’s build process. For example, you may have an overall plan build process that comprises a compilation step, followed by several test steps, followed by a deployment step. You can create separate Bamboo stages to represent each of these steps.
A stage:
- Shall have at least one job
- Processes its jobs in parallel, on multiple agents (where available).
- Must successfully complete all its jobs before the next stage in the plan can be processed.
- May produce artifacts that can be made available for use by a subsequent stage.
Each plan should contain at least one stage.
Job
A job which runs few tasks, generates and uses artifacts and has some build requirements.
Job job = new Job("My Job", "JOB1")
.tasks(tasks)
.artifacts(testReportArtifact)
.artifactSubscriptions(warArtifact)
.requirements(osLinux);
A Bamboo job is a single build unit within a plan. One or more jobs can be organized into one or more stages. The jobs in a stage can all be run at the same time, if enough Bamboo agents are available. A job is made up of one or more tasks.
A job:
- Processes a series of one or more tasks that are run sequentially on the same agent.
- Controls the order in which tasks are performed.
- Collects the requirements of individual tasks in the job, so that these requirements can be matched with agent capabilities.
- Defines the artifacts that the build will produce.
- Can use artifacts produced in a previous stage.
Each plan should contain at least one job.
Tasks
A job with two build tasks and one final task
Job job = new Job("Job", "JOB")
.tasks(new VcsCheckoutTask()
.addCheckoutOfDefaultRepository(), new ScriptTask()
.fileFromPath("build.sh"))
.finalTasks(new ScriptTask()
.fileFromPath("cleanup.sh"));
A task is a small discrete unit of work, such as source code checkout or running a script. Tasks are configured within the scope of a job and run on a Bamboo working directory.
Tasks can be designated as build tasks or final tasks in a job:
build tasks will run sequentially in the order specified in the job; if a build task fails, all subsequent tasks will not be executed
final tasks will run sequentially, once the build tasks have completed; final tasks will always be executed, regardless of whether any build tasks or other final tasks fail; final tasks will be executed even if you stopped the build manually
A task may make use of an executable if required.
Task: Artifact Downloader
A task downloading all artifacts produced by plan “PROJECTKEY-PLANKEY” to the working directory as well as an artifact called “an artifact” to a folder called “subdirectory”.
DownloadItem downloadAllArtifacts = new DownloadItem()
.allArtifacts(true);
DownloadItem downloadSpecificArtifact = new DownloadItem()
.artifact("an artifact")
.path("subdirectory");
PlanIdentifier planIdentifier = new PlanIdentifier("PROJECTKEY", "PLANKEY");
ArtifactDownloaderTask artifactDownloaderTask = new ArtifactDownloaderTask()
.description("My artifact downloader task")
.sourcePlan(planIdentifier)
.artifacts(downloadAllArtifacts, downloadSpecificArtifact);
The task which copies Bamboo shared artifacts to a specified folder. This task allows sharing artifacts between different build plans. For example, you may want to run acceptance tests on a particular build from a different plan by sharing the same WAR from one plan to another without rebuilding it each time.
In order to configure the task:
select a plan that produces the artifact(s)
add
DownloadItem
objects, that is, a combination of item to be downloaded and path it should be downloaded to. You can add as many of those as required.
In order to specify single download request:
pick an artifact to download by passing its name. You can also request downloading all artifacts at once, as shown in the first example.
define a path of a folder artifact(s) should be downloaded to. The path can be either absolute or relative to the working directory. If not specified, artifacts are downloaded directly to the working directory.
Task: Clean Working Directory
A task cleaning working directory after the build.
CleanWorkingDirectoryTask cleanWorkingDirectoryTask = new CleanWorkingDirectoryTask()
.description("My clean working directory task")
.enabled(true);
The task to clean working directory of the job. The task removes all files from the working directory and can be used, for example, to enforce a clean build or to save space on the agent once the build is complete.
Task: Script
Run a script defined inline using a default interpreter, which is a Bash shell as per the shebang line
ScriptTask scriptTask = new ScriptTask()
.inlineBody("#!/bin/bash\necho \'Hello Bamboo!\'");
Run a script from a file with /bin/sh or cmd.exe interpreter
ScriptTask scriptTask = new ScriptTask()
.description("Running a script from a file")
.interpreterBinSh()
.fileFromPath("path/to/my/script.sh");
Run a script with an argument, environment variable and in an ‘abc’ working subdirectory
ScriptTask scriptTask = new ScriptTask()
.interpreterBinSh()
.fileFromPath("ant-build.sh")
.argument("--verbose")
.environmentVariables("ANT_OPTS=-Xmx700m")
.workingSubdirectory("abc");
This task allows to use a script executable. You can use bash on Linux and batch files on Windows.
You can specify which interpreter to use:
- shell (default) - script will be run by an interpreter chosen based on the shebang line of the script
- Windows PowerShell - script will be run by Windows PowerShell
- /bin/sh or cmd.exe - script will be run by /bin/sh or cmd.exe, depending on the operating system
You can either define the script inline using the inlineBody
method or load it from an external file using
the fileFromPath
method.
Additional options you can specify are:
argument - Specify an argument to pass to the script. Arguments that contain spaces must be quoted. You can include variables (see Bamboo variables).
environment variables - additional system environment variables that you want to pass to your build. Existing environment variables are automatically available to the executable. You can also include Bamboo global or build-specific variables (see Bamboo variables). Multiple variables should be separated with spaces. Parameters with spaces must be quoted.
working subdirectory - an alternative subdirectory, relative to the job’s root directory, where Bamboo will run the executable. The root directory contains everything checked out from the job’s configured source repository. If you leave this field blank, Bamboo will look for build files in the root directory. This option is useful if your task has a build script in a subdirectory and the executable needs to be run from within that subdirectory.
Task: Test Results Parser
Test tasks in Bamboo parse test data, and may run tests, using a particular testing framework. Please note:
- Java builder tasks in Bamboo (e.g. Maven) parse test information as part of the task. You do not need to configure a test task, if you have specified that test results will be produced as part of the builder task. However, you can configure a builder task to not produce test results and use a test task to parse the test data instead. For example, you may want to set up one JUnit Parser task to parse test data for a number of Maven tasks after they have executed.
- .NET builder tasks in Bamboo (e.g. NAnt) do not parse test information as part of the task. You must configure a test task (e.g. NUnit Parser), if you want test results from the builder task to be parsed.
Task: JUnit Parser
Scan JUnit test reports from ‘build/test/reports’ and ‘target/test/xml-reports’ directories.
TestParserTask junitParserTask = TestParserTask.createJUnitParserTask()
.description("My JUnit test results parser task")
.resultDirectories("build/test/reports", "target/test/xml-reports");
- result directories - list of Ant patterns matching directories and files to be scanned
- default result directory - use the
**/test-reports/*.xml
pattern - pick-up test results outside of this build - allows the task to scan test result files created before start time of the build; enabling it may be useful if you do not clean the build working directory and perform incremental build and tests and want to aggregate test results from many builds
Task: TestNG Parser
Scan TestNG reports from default location. Pick test results also from previous builds.
TestParserTask junitParserTask = TestParserTask.createTestNGParserTask()
.description("My TestNG test results parser task")
.defaultResultDirectory()
.pickUpTestResultsCreatedOutsideOfThisBuild(true);
- result directories - list of Ant patterns matching directories and files to be scanned
- default result directory - use the
**/testng-results.xml
pattern - pick-up test results outside of this build - allows the task to scan test result files created before start time of the build; enabling it may be useful if you do not clean the build working directory and perform incremental build and tests and want to aggregate test results from many builds
Task: Repository Checkout
A task checking out the default repository to the working directory and a repository called “repositoryName” into a “subdirectory”.
CheckoutItem defaultRepository = new CheckoutItem()
.defaultRepository();
CheckoutItem specificRepository = new CheckoutItem()
.repository("repositoryName")
.path("subdirectory");
VcsCheckoutTask vcsCheckoutTask = new VcsCheckoutTask()
.description("My repository checkout task")
.cleanCheckout(false)
.checkoutItems(defaultRepository, specificRepository);
Task to check out a repository for use by just one job. By default, repositories are checked out to the Bamboo working directory. It’s possible to check out multiple repositories using one task, but in that case order in which repositories are checked out is undefined.
In order to configure the task:
- add
CheckoutItem
objects, that is, a combination of a repository to be checked out and path it should be checked out to. You can add as many of those as required. - decide if task should perform a clean check out. If set, the task will remove contents of each specified folder before checking out the source code.
A repository can be specified by its name or identifier. Repository must be either a plan repository or a linked repository. You can also pick defaultRepository
option, in which case the task checks out the first repository that was added or linked to the plan, regardless of its actual definition.
Paths must be relative to the working directory.
Task: Maven
Simple Maven 3 task running with JDK 1.8.
MavenTask mavenTask = new MavenTask()
.goal("clean install")
.hasTests(false)
.version3()
.jdk("JDK 1.8")
.executableLabel("Maven 3.2");
Apache Maven is a tool used for building and managing Java-based projects. Bamboo provides a dedicated task to execute Maven goals for building, testing and deploying your code.
The most important configuration option for Maven task is the goal to execute. Multiple goals can be specified,
separated by spaces, for example clean install
. It is also possible to pass additional JVM and Maven parameters, such
as -Djava.awt.headless=true
or -Pdatabase.tests
. Bamboo Variables may be included in this field too,
for example clean compile ${bamboo.maven.compile.flags}
.
Two other necessary fields to set are the JDK and the Maven executable. These configuration options indicate which version of Java Development Kit and which version of Apache Maven should be used to execute the task. The options should point to valid Bamboo capabilities.
More detailed documentation of the Maven task can be found here.
Task: Docker CLI
Docker is a tool which automates the running and deployment of applications inside containers. Bamboo provides support for Docker using dedicated DockerCLI task. The Docker CLI task is a task which allows for building, pulling from registry, pushing to registry Docker images and running Docker images. To improve its readability, Docker CLI is split into four separate Bamboo Specs builders.
DockerBuildImageTask
Docker CLI task which builds Docker image.
DockerBuildImageTask dockerBuildImageTask = new DockerBuildImageTask()
.imageName("dockerImage")
.dockerfileInWorkingDir();
Docker CLI task which builds Docker image and Dockerfile is inlined.
DockerBuildImageTask dockerBuildImageTask = new DockerBuildImageTask()
.imageName("dockerImage")
.dockerfile("FROM ubuntu\n RUN echo \"hello!\"");
Docker CLI task which builds Docker image and Dockerfile is retrieved from a file system.
DockerBuildImageTask dockerBuildImageTask = new DockerBuildImageTask()
.imageName("dockerImage")
.dockerfileFromPath(Paths.get(myProject + "/Dockerfile"));
Used to build the Docker image. Dockerfile content can be inlined or it can be retrieved from a working directory of a task.
DockerRunContainerTask
Docker CLI task which runs a hello-world image.
DockerRunContainerTask dockerRunContainerTask = new DockerRunContainerTask()
.imageName("hello-world");
Docker CLI task which runs a HTTPD server.
DockerRunContainerTask dockerRunContainerTask = new DockerRunContainerTask()
.imageName("tomcat:2.2")
.clearVolumeMappings()
.containerWorkingDirectory("")
.detachContainer(true)
.containerName("my-apache-app")
.waitToStart(true)
.serviceURLPattern("http://localhost:${docker.port}")
.appendPortMapping(18080, 8080)
.appendVolumeMapping("${bamboo.working.directory}", "/usr/local/apache2/htdocs/");
Used to run images in a container. This task provide powerful customization options such as:
- detaching containers
- linking other detached containers running in the same Bamboo job
- waiting for a service to start
- container environment variables, command or working directory
- port or volume mappings
Note, by default when builder is created, the container working directory is set to /data and default host-container volume mapping is set to ${bamboo.working.directory} -> /data
DockerPushImageTask
Docker CLI task which pushes a image.
DockerPushImageTask dockerPushImageTask = new DockerPushImageTask()
.customRegistryImage("localhost:5000/hello-world:1.0");
Docker CLI task which pushes a image with explicit authentication.
DockerPushImageTask dockerPushImageTask = new DockerPushImageTask()
.dockerHubImage("hello-world:1.0")
.authentication("dockerHubUsername", "dockerHubPassword", "dockerHubMail");
Task designed to push an image to a Docker registry. You can use it to push your image to both: your own Docker registry and Docker Hub. Please note, if you’re using custom registry you need to specify full repository tag for Docker image, e.g. registry.address:port/namespace/repository:tag.
Docker push by default uses credentials stored in the agent’s ~/.dockercfg, however you may specify explicit username, password and email which will be used to authenticate against Docker registry.
DockerPullImageTask
Docker CLI task to which pulls image with implicit agent’s authentication.
DockerPullImageTask dockerPullImageTask = new DockerPullImageTask()
.customRegistryImage("localhost:5000/hello-world:1.0");
Docker CLI task which pulls image with explicit authentication.
DockerPullImageTask dockerPullImageTask = new DockerPullImageTask()
.dockerHubImage("hello-world:1.0")
.authentication("dockerHubUsername", "dockerHubPassword", "dockerHubMail");
DockerPullImageTask is similar to DockerPushImageTask, however, it’s used for pulling Docker images from the registry.
Parsing test results
Maven 3 task with test parsing enabled.
MavenTask mavenTask = new MavenTask()
.goal("clean install")
.hasTests(false)
.version3()
.hasTests(true)
.testResultsPath("**/my-acceptance-tests/target/surefire-reports/*.xml")
.jdk("JDK 1.8")
.executableLabel("Maven 3.2");
Maven task is capable of parsing test results generated during the build. To configure the task to pick up tests, make sure to enable the feature (as shown in the code sample) and point Bamboo to test reports which will be created. Bamboo will use JUnit test parser to gather test results, so make sure the reports are in the correct format.
Configuring runtime environment
Maven 3 task running in custom working directory, with
MAVEN_OPTS
environment variable set.
MavenTask mavenTask = new MavenTask()
.goal("clean install")
.hasTests(false)
.version3()
.jdk("JDK 1.8")
.executableLabel("Maven 3.2")
.environmentVariables("MAVEN_OPTS=\"-Xmx768m -Xms64m -Dmaven.compiler.fork=true\"")
.workingSubdirectory("maven-working-dir");
The Maven task offers additional flexibility for configuring runtime environment.
There is a possibility of setting environment variables for the build. It’s a common practice to set MAVEN_OPTS
for the build’s execution
(e.g. MAVEN_OPTS="-Xms200m -Xmx700m"
). You can include Bamboo variables for this configuration option
(e.g. MAVEN_OPTS="${bamboo.maven.compile.opts}"
).
Multiple environment variables can be provided, separated with spaces. Parameters with spaces must be quoted. Note that existing environment variables are automatically available and there’s no need to override them.
It is also possible to execute the Maven task in a specific sub-folder of the build’s working directory by providing relative path to it.
Task: NUnit
NUnit is a unit-testing framework for all .Net languages. Bamboo provides support for NUnit with parser and runner tasks.
NUnit Parser
NUnit Parser task in a typical setup.
final TestParserTask nUnitParserTask = TestParserTask.createNUnitParserTask()
.resultDirectories("test-results/*.xml");
.NET builder tasks in Bamboo (e.g. NAnt) do not parse test information as part of the task. You must configure a NUnit Parser task for the test results from the builder task to be parsed.
NUnit Parser task builder works in a very similar way to the JUnit parser task builder.
NUnit Runner
NUnit Runner task in a typical setup.
final NUnitRunnerTask nUnitRunnerTask = new NUnitRunnerTask()
.executable("nunit 2.6.4")
.nUnitVersion2()
.nUnitTestFiles("nunit.tests.dll")
.resultFilename("test-output.xml")
.testsToRun("NUnit.Tests.AssertionTests");
NUnit Runner task runs the tests defined with NUnit framework. NUnit version 3 has been completely rewritten since version 2, so you have to specify version of the executable you wish to use.
Configuring unsupported tasks
The ‘Add Requirement’ task with ‘isLinux=true’ using generic AnyTask
Map<String, String> configuration = new MapBuilder<String, String>()
.put("existingRequirement", "isLinux")
.put("regexMatchValue", "true")
.put("requirementKey", "")
.put("requirementMatchType", "match")
.put("requirementMatchValue", "")
.build();
AnyTask anyTask = new AnyTask(new AtlassianModule("com.atlassian.bamboo.plugin.requirementtask:task.requirements"))
.configuration(configuration);
Not all tasks available in Bamboo have corresponding task classes in Bamboo Specs library. A good example are tasks bundled in third party plugins.
In order to handle an unsupported task use the generic AnyTask class. The AnyTask class requires an identifier of a task module and a set of properties describing task’s settings.
The fastest way to get this data is as follows:
Create a plan in Bamboo. From top menu choose ‘Create’ > ‘Create a new plan’, enter plan name and key, select ‘Link new repository’ with ‘None’ and click ‘Configure plan’.
Add a task you would like to use. Click ‘Add task’ and select a task from list, set all options, click ‘Save’ and next click ‘Create’.
Export plan configuration. From the plan configuration page click ‘Actions’ > ‘View plan as Bamboo Specs’.
Copy generated AnyTask code to your Bamboo Specs. Hint: you may want to encapsulate it in your own class inheriting from the Task class. In case you see an inline comment ‘Bamboo Support for task “Xyz” coming soon’ then it means that this is a plugin bundled with Bamboo and we will deliver appropriate class in one of next Bamboo major or minor releases.
Repositories
This section describes how to configure Bamboo to use repositories. You can specify repositories at the following levels in Bamboo:
- linked – repositories are available to all plans in Bamboo
- plan – repositories are available in one Bamboo plan
Multiple repositories
A plan with two linked and two global repositories.
Plan plan = new Plan(project, planName, planKey)
.linkedRepositories("my-global-repository1")
.linkedRepositories("my-global-repository2")
.planRepositories(new GitRepository()
.name("my-plan-repository1")
.url("ssh://git@bitbucket.org:my-company/my-repository1.git")
.branch("master"))
.planRepositories(new GitRepository()
.name("my-plan-repository2")
.url("ssh://git@bitbucket.org:my-company/my-repository2.git")
.branch("master"));
One or more repositories can be added to a plan. All those repositories will be available to every job in the plan. The first repository in the list is the Plan’s Default Repository.
Plan-local vs linked repositories
Linked repositories are available globally to all plans and jobs configured on the Bamboo server. Doing this can save you from having to reconfigure the source repositories in multiple places if these ever change - any changes to a linked repository are applied to every plan or job that uses that repository.
Creating linked repositories
Currently it is not possible to create new linked repositories from Bamboo Specs.
See Linking to source code repositories how to set up linked repositories using UI. Once linked repository is defined, you can refer it in your code, see chapter below.
Referring linked repositories
Plan plan = new Plan(project, planName, planKey)
.linkedRepositories("my-global-repository");
Once the linked repository is set up you can easily refer to it in your plan configuration.
Creating local repositories
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new GitRepository()
.name("my-plan-repository")
.url("ssh://git@bitbucket.org:my-company/my-repository.git")
.branch("master"));
In case you want to use a repository in only one plan and don’t want to share it, then you can define it as local.
Git
You need to have previously defined a Git capability before you can configure a Git source repository – see Defining a new version control capability.
Note that Bamboo comes with its own built-in Git implementation. However, you need to use native Git to be able to use symbolic links, submodules, automatic branch detection and automatic merging - these are not supported by the built-in Git.
Basic options
In case you are using a linked repository, then you need to provide repository name only.
In case you are creating a local repository definition, you have to provide at least:
name to help identify repository in Bamboo
URL to your Git repository; valid forms are:
- git://host.xz[:port]/path/to/repo.git
- ssh://[user@]host.xz[:port]/path/to/repo.git
- [user@]host.xz[:port]/path/to/repo.git
- http[s]://host.xz[:port]/path/to/repo.git
- /path/to/repo.git
- file:///path/to/repo.git
branch - the name of the branch (or tag) you want to work on
Authentication
In case you have to authenticate you can use several methods.
With SSH authentication (recommended)
Git repository with SSH authentication
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new GitRepository()
.name("my-repository")
.url("ssh://git@bitbucket.org:my-company/my-repository.git")
.branch("master")
.authentication(new SshPrivateKeyAuthentication(sshPrivateKey)
.passphrase(passphrase)));
Provide an SSH private key and provide the SSH passphrase.
With user/password authentication
Git repository with user-password authentication
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new GitRepository()
.name("my-repository")
.url("https://bitbucket.org/my-company/my-repository.git")
.branch("master")
.authentication(new UserPasswordAuthentication(username)
.password(password)));
We advise to not store user and password in the source code, but to read them from a resource file or a system property.
With shared credentials
Git repository with authentication using shared credentials
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new GitRepository()
.name("my-repository")
.url("ssh://git@bitbucket.org:my-company/my-repository.git")
.branch("master")
.authentication(new SharedCredentialsIdentifier("identifier")));
You can store credentials within Bamboo for easier access to repositories. The access details that you provide are available to all plans on your Bamboo server. See Shared credentials for more details.
With no credentials
In case you want to access the repository anonymously, simply do not declare any authentication.
Advanced options
Checkout shallow clone of Git LFS-enabled repository of an ‘integration’ branch. The repository does not use Git submodules.
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new GitRepository()
.name("repository-name-in-bamboo")
.url("ssh://git@bitbucket.org:my-company/my-repository.git")
.branch("integration")
.shallowClonesEnabled(true)
.lfsEnabled(true)
.submodulesEnabled(false));
You can tune repository checkout performance with the following options:
shallow clones - perform shallow clones (i.e. history truncated to a specified number of revisions), this should increase the speed of the initial code checkouts, however if your build depends on the full repository history, we recommend that you do not use this option. Shallow clones are enabled by default.
fetch whole repository - when disabled, Bamboo checks out the current branch (i.e. all commits of the branch); when enabled, Bamboo checks out entire repository (i.e. all commits of all branches)
remote agent cache - when enabled, remote agents will keep repository clones in their caches to speed-up checkout process
Note that not all combinations of the three options above make sense. Reasonable combinations are:
shallow clones | fetch whole repository | remote agent cache | outcome |
---|---|---|---|
true | false | false | the latest revision of given branch is fetched |
false | false | false | all revisions of given branch are fetched |
false | false | true | all revisions of given branch are fetched, an agent caches it |
false | true | false | the entire repository is fetched |
false | true | true | the entire repository is fetched, an agent caches it |
Link the Git repository with Atlassian FishEye.
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new GitRepository()
.name("repository-name-in-bamboo")
.url("ssh://git@bitbucket.org:my-company/my-repository.git")
.branch("master")
.repositoryViewer(new FishEyeRepositoryViewer()
.repositoryName("repository-name-in-fisheye")
.fishEyeUrl("https://fisheye.host:8060/")));
Other options are:
LFS - enables support for Git Large File Storage (LFS), which replaces large files such as audio samples, videos, datasets, and graphics with text pointers inside Git, while storing the file contents on a remote server. To use this option you must have the following:
- Git version 1.8.2 or later installed locally in your environment
- Git LFS 1.2 or later installed.
submodules - select to enable submodules support if these are defined for the repository. If native Git capability is not defined for agent submodules support will be disabled.
repository viewer - if your repository can be viewed in a web browser, select the repository type. This allows links to relevant files to be displayed in the ‘Code Changes’ section of a build result. For more details see:
verbose logs - outputs more verbose logs from git commands
command timeout - how many minutes are given for git commands to finish (default is 180 minutes).
Group commits from 1 minute, trigger build on *.java files only, skip changesets with ‘draft’ in a commit message.
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new GitRepository()
.name("repository-name-in-bamboo")
.url("ssh://git@bitbucket.org:my-company/my-repository.git")
.branch("master")
.changeDetection(new VcsChangeDetection()
.quietPeriodEnabled(true)
.quietPeriod(Duration.ofMinutes(1))
.changesetFilterPatternRegex(".*draft.*")
.filterFilePatternOption(FileFilteringOption.INCLUDE_ONLY)
.filterFilePatternRegex(".*\\.java")));
Change detection options:
quiet period - quiet period allows you to delay building after a single commit is detected, aggregating multiple commits per build
include/exclude files - what files Bamboo uses or ignores to detect changes
exclude changesets - a regular expression to match the commit messages to be excluded
Bitbucket Server Git repository
Atlassian Bitbucket Server hosts Git repositories, so you can define it as a standard Git repository. However, defining such repository as Bitbucket Server gives you many advantages.
When you link a repository hosted in Atlassian’s Bitbucket Server with a build plan in Bamboo, then without any further configuration:
- Bamboo will automatically run a build when changes are pushed to the Bitbucket Server repository, without needing to configure polling.
- Bamboo will automatically update plan branches when a developer pushes a new branch to the repository (or deletes a branch).
- You can click through to Bitbucket Server to see the commit diff for all files that are part of the changeset.
- Bitbucket Server commits that are part of a build are displayed in Bamboo.
- Build results are notified to Bitbucket Server (and displayed for the associated commits and pull requests).
Bitbucket Server and Bamboo only need to have been connected by creating an application link. Repositories in Bitbucket Server are then made available in Bamboo, so it is easy for you to link your Bamboo plan to a Bitbucket Server repository.
When you create a plan that uses a Bitbucket Server source repository, Bamboo will automatically use the repository trigger instead of a polling trigger. This reduces the load on the Bamboo and Bitbucket servers because Bamboo doesn’t need to send poll requests (for each branch of each plan) to the Bitbucket Server every few minutes. Instead, Bitbucket Server will notify Bamboo whenever there is a push to the repository.
Basic options
Minimal Bitbucket Server configuration
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new BitbucketServerRepository()
.name("my-bitbucket-repository")
.server(new ApplicationLink()
.name("bitbucket-server"))
.projectKey("BBSPROJECT")
.repositorySlug("my-repository-slug")
.branch("master"));
In order to configure Bitbucket Server repository provide at least:
- name - a name that identifies this repository within Bamboo
- server - an application link to Bitbucket Server
- project - project name in Bitbucket Server
- repository slug - a repository slug is a URL-friendly version of repository name, automatically generated by Bitbucket for use in the URL. For example if your repository name was ‘føøbar’, in the URL it would become ‘foobar’. Similarly, ‘foo bar’ would become ‘foo-bar’. A repository slug is a part of the clone URL you can find in Bitbucket.
Authentication
Authentication with custom SSH keys
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new BitbucketServerRepository()
.name("my-bitbucket-repository")
.server(bitbucketServerApplink)
.projectKey("BBSPROJECT")
.repositorySlug("my-repository-slug")
.branch("master")
.sshPrivateKey(sshPrivateKey)
.sshPublicKey(sshPublicKey));
Bamboo uses SSH authentication against Bitbucket Server. You can configure:
- ssh private key of the repository (the key can be defined in both Bamboo-encrypted and plain format)
- ssh public key of the repository
You have to provide both private and public key when setting them. If not provided, Bamboo will attempt to generate and install new SSH keys into Bamboo Server instance.
Advanced options
Use shallow clones, enable LFS support and set commit isolation (to trigger a build on every commit)
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new BitbucketServerRepository()
.name("my-bitbucket-repository")
.server(new ApplicationLink()
.name("bitbucket-server"))
.projectKey("BBSPROJECT")
.repositorySlug("my-repository-slug")
.branch("master")
.lfsEnabled(true)
.changeDetection(new VcsChangeDetection()
.commitIsolationEnabled(true))
.shallowClonesEnabled(true)
.fetchWholeRepository(false)
.commandTimeoutInMinutes(30));
Bitbucket Server repository supports the same set of options as Git repository. See the ‘Advanced options’ section for Git for more details.
Creating Bitbucket Server repositories in repository stored specs mode
In RSS mode, you need to define SSH keys and clone url of the repository
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new BitbucketServerRepository()
.name("my-bitbucket-repository")
.server(bitbucketServerApplink)
.projectKey("BBSPROJECT")
.sshCloneUrl("ssh://my.bitbucket.server:7999/BSSPROJECT/my-bitbucket-repository.git")
.repositorySlug("my-repository-slug")
.branch("master")
.sshPrivateKey(sshPrivateKey)
.sshPublicKey(sshPublicKey));
When using specs in interactive mode, the Bamboo server can and fetch the data such as clone url or ssh keys from Bitbucket Server. In RSS mode it’s not possible as user session is not available during automatic update. Therefore the following properties are mandatory when in RSS mode:
- ssh private key of the repository (the key can be defined in both Bamboo-encrypted and plain format)
- ssh public key of the repository
- ssh clone url of this repository, as used by git commands (can be found on repository’s page in Bitbucket Server)
SVN
Currently there is no dedicated builder for SVN repositories, but there is a generic AnyVcsRepository builder.
AtlassianModule atlassianModuleSvn = new AtlassianModule("com.atlassian.bamboo.plugin.system.repository:svnv2");
Map<String, Object> svnConfiguration = ImmutableMap.<String, Object>builder()
.put("repository.svn.useExternals", false)
.put("repository.svn.tag.create.autodetectPath", true)
.put("repository.svn.authType", "password")
.put("repository.svn.username", "")
.put("repository.svn.branch.create.autodetectPath", true)
.put("repository.svn.userPassword", false)
.put("repository.svn.repositoryRoot", "file:///path/to/my/svn/repository")
.build();
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new AnyVcsRepository(atlassianModuleSvn)
.name("my-svn-repository")
.serverConfiguration(svnConfiguration));
Mercurial
Currently there is no dedicated builder for Mercurial repositories, but there is a generic AnyVcsRepository builder.
AtlassianModule atlassianModuleHg = new AtlassianModule("com.atlassian.bamboo.plugins.atlassian-bamboo-plugin-mercurial:mercurial");
Map<String, Object> hgConfiguration = ImmutableMap.<String, Object>builder()
.put("repository.hg.repositoryUrl", "file:///path/to/my/hg/repository")
.put("repository.hg.ssh.compression", false)
.put("repository.hg.verbose.logs", false)
.put("repository.hg.authentication", "BYPASS")
.put("repository.hg.noRepositoryCache", false)
.put("repository.hg.commandTimeout", 180)
.build();
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new AnyVcsRepository(atlassianModuleHg)
.name("my-mercurial-repository")
.serverConfiguration(hgConfiguration));
CVS
Currently there is no dedicated builder for CVS repositories, but there is a generic AnyVcsRepository builder.
AtlassianModule atlassianModuleCvs = new AtlassianModule("com.atlassian.bamboo.plugin.system.repository:cvs");
Map<String, Object> cvsConfiguration = ImmutableMap.<String, Object>builder()
.put("cvsRoot", "/path/to/my/cvs/repository")
.put("password", "")
.put("quietPeriod", 2)
.put("module", "module")
.put("authType", "password")
.put("selectedVersionType", "head")
.build();
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new AnyVcsRepository(atlassianModuleCvs)
.name("my-cvs-repository")
.serverConfiguration(ImmutableMap.of("repository.cvs", cvsConfiguration)));
Artifacts
Artifacts are files created by a job build (e.g. JAR files). Artifact definitions are used to specify which artifacts to keep from a build and are configured for individual jobs. You can also configure artifact sharing between jobs in a plan. For example, you may want to run acceptance tests on a build, and then share the WAR from one job to another, without rebuilding the WAR each time.
Defining an artifact
A ‘Test Reports’ artifact containing XML files
Artifact artifact = new Artifact("Test Reports")
.location("target/reports")
.copyPattern("**/*.xml");
You can specify which artifacts to keep by setting up an artifact definition for the job. The artifacts will be available after each build of a job. You can specify:
- name - name of the artifact; in case artifact is shared, name must be unique within the plan
- location - the directory to find your artifact; it’s a path relative to the workspace directory; do not use the absolute path
- copy pattern - name or Ant pattern of file(s) to keep
See also Pattern matching reference.
Sharing an artifact
Declare a shared artifact
Artifact artifact = new Artifact("Test Reports")
.location("target/reports")
.shared(true);
You can share an artifact among other jobs or plans. Set the ‘shared’ property to true and optionally define jobs subscribing to this artifact.
The artifact from the most recent successful build will be used. If there are no successful builds from the artifact-producing plan or the artifacts have expired, the artifact-consuming job will fail.
Using a shared artifact in another job of the same plan
Create a WAR artifact in the ‘Build’ stage and use it in the ‘Test’ stage
Stage buildStage = new Stage("Build")
.jobs(new Job("Build WAR", "BUILD")
.artifacts(new Artifact("WAR")
.location("target")
.copyPattern("*.war")
.shared(true)));
Stage testStage = new Stage("Test")
.jobs(new Job("Test app", "TEST")
.artifactSubscriptions(new ArtifactSubscription()
.artifact("WAR")
.destination("deploy")));
Plan plan = new Plan(project, planName, planKey)
.stages(buildStage, testStage);
You can share artifacts between jobs in different stages using artifact dependencies. For example, you may want to run acceptance tests on a build, sharing the same WAR from one job to another without rebuilding it each time. Each time the artifact is shared with a subsequent job, it is copied to the job’s agent.
You can refer only to artifacts from jobs in previous stages that have been marked as shared. Destination directory is relative to the build directory. Do not use the absolute path to refer to the destination directory.
Using a shared artifact in another plan
Download all artifacts from another plan
Plan artifact = new Plan(project, planName, planKey)
.stages(new Stage("Stage 1")
.jobs(new Job("Job", "JOB")
.tasks(new ArtifactDownloaderTask()
.sourcePlan(new PlanIdentifier("PROJECTKEY", "PLANKEY"))
.artifacts(new DownloadItem()
.allArtifacts(true)))));
Download selected artifacts from another plan
Plan artifact = new Plan(project, planName, planKey)
.stages(new Stage("Stage 1")
.jobs(new Job("Job", "JOB")
.tasks(new ArtifactDownloaderTask()
.sourcePlan(new PlanIdentifier("PROJECTKEY", "PLANKEY"))
.artifacts(new DownloadItem()
.artifact("WAR"), new DownloadItem()
.artifact("DATA")))));
You have to use the Artifact Downloader Task for this purpose. In this task point to the build plan that is the source of the artifact(s) you need to download. You can either download all artifacts from the plan or selected ones as well as specify target folder for them.
Sharing an artifact to a deployment environment
Bamboo Specs do not support deployment plans at the moment. See Sharing artifacts from a build plan to a deployment environment how to set it up.
Build triggers
Triggering in Bamboo allows plan builds to be started automatically. Bamboo has the following trigger methods.
Polling the repository for changes
Bamboo will poll the selected source code repositories for code changes, using either a specified interval or a schedule. If Bamboo detects code changes, a build of the plan is triggered.
Poll periodically
Plan plan = new Plan(project, planName, planKey)
.triggers(new RepositoryPollingTrigger()
.pollEvery(10, TimeUnit.MINUTES));
You can poll source code repository every N minutes / hours / days for new commits.
Poll daily, weekly or monthly
Plan dailyPlan = new Plan(project, planName, planKey)
.triggers(new RepositoryPollingTrigger()
.pollOnceDaily(LocalTime.of(12, 59)));
Plan weeklyPlan = new Plan(project, planName, planKey)
.triggers(new RepositoryPollingTrigger()
.pollWeekly(LocalTime.of(12, 59), DayOfWeek.SATURDAY, DayOfWeek.SUNDAY));
Plan monthlyPlan = new Plan(project, planName, planKey)
.triggers(new RepositoryPollingTrigger()
.pollMonthly(LocalTime.of(12, 59), 28));
You can define a time schedule when to poll the repository. You can poll daily, on specific days of a week or on specific days of a month.
Poll with cron expression
Plan plan = new Plan(project, planName, planKey)
.triggers(new RepositoryPollingTrigger()
.pollWithCronExpression("0 0/30 9-19 ? * MON-FRI"));
You can also use a cron expression (see Constructing a cron expression in Bamboo).
Repository triggers a build on commit
A plan listening for events from a ‘my-repo’ repository from ‘12.34.56.78’ IP address.
Plan plan = new Plan(project, planName, planKey)
.planRepositories(new GitRepository()
.name("my-repo")
.url("ssh://git@bitbucket.org:my-company/my-repo.git")
.branch("master"))
.triggers(new RemoteTrigger()
.triggerIPAddresses("12.34.56.78"));
Bamboo waits to receive a message about changed code from any of the selected source code repositories. When Bamboo receives such a message, a build of the plan is triggered. This option minimizes server load, because message events are sent only when code changes to a repository are committed. This is the default option when you use a linked Bitbucket Server repository.
See the Repository triggers the build when changes are committed how to set up the trigger on the repository side.
On the Bamboo side, use the triggers(new RemoteTrigger())
on plan definition. By default the remote trigger
will react on all triggering repositories defined in a plan. You can limit it by selecting a subset of repositories.
In case you want Bamboo to trigger on post-commit messages from other than the primary IP address for the repository,
specify it in triggerIPAddresses
.
Notes:
- the repositories listed in remote trigger must be among those declared in a plan
- if you use a Mercurial or Git repository then you must type the IP address of your repository host
- for Bitbucket Cloud the current outbound IP addresses can be found at Access Bitbucket Cloud from Behind a Firewall
- if you’re using the Bitbucket Cloud Bamboo post-push hook, ensure that the user you are using to authenticate triggering the build has the ‘build’ permission on the plan you are attempting to trigger, see also Triggering a Bamboo build from Bitbucket Cloud using Webhooks
Cron-based scheduling
In case of the cron-based scheduling, the build will always run at specified time, no matter whether content of repositories has changed or not.
Schedule with time interval
Plan plan = new Plan(project, planName, planKey)
.triggers(new ScheduledTrigger()
.scheduleEvery(4, TimeUnit.HOURS));
You can schedule a build to run every N minutes / hours / days.
Schedule with daily, weekly or monthly plan
Plan plan = new Plan(project, planName, planKey)
.triggers(new ScheduledTrigger()
.scheduleOnceDaily(LocalTime.of(12, 59)));
Plan plan = new Plan(project, planName, planKey)
.triggers(new ScheduledTrigger()
.scheduleWeekly(LocalTime.of(12, 59), DayOfWeek.SATURDAY));
Plan plan = new Plan(project, planName, planKey)
.triggers(new ScheduledTrigger()
.scheduleMonthly(LocalTime.of(12, 59), 1));
The schedule can be daily (specific time each day), weekly (days per week), monthly (days per month).
Schedule with cron expression
Plan plan = new Plan(project, planName, planKey)
.triggers(new ScheduledTrigger()
.cronExpression("0 0/30 9-19 ? * MON-FRI"));
The schedule can be also expressed using a cron expression.
Conditional build triggers
In Bamboo UI it is possible to define a trigger condition, i.e. that a given trigger will execute only if specified plans are passing. This option is not available in Bamboo Specs at the moment.
See Triggering builds / Conditional build triggers.
Running a build when another plan has successfully completed
A dependency blocking strategy which blocks a trigger if parent’s build is in progress, unless this is a branch plan
Plan plan = new Plan(project, planName, planKey)
.dependencies(new Dependencies()
.configuration(new DependenciesConfiguration()
.enabledForBranches(false)
.blockingStrategy(BLOCK_IF_PARENT_IN_PROGRESS)));
In Bamboo UI it is possible to define build dependencies, i.e. to trigger a plan build when another plan’s build has successfully completed. This option is not available in Bamboo Specs at the moment.
Both in Bamboo UI and Bamboo Specs it is possible to define dependency blocking strategies, such as:
- do not block - when triggered by a source code update, the plan will always be built, regardless of any parent plan build dependencies
- block build if parent builds are queued or in progress - when triggered by a source code update, the plan will not be built if its parent plans are building or are waiting in the build queue
- block build if parent plans have unbuilt changes - when triggered by a source code update, the plan will not be built if its parent plans are building, are waiting in the build queue, or have changes. When Bamboo finds parent plans with source repository changes, those plans will be triggered and your plan will be blocked.
See:
Multiple triggers
You can use many triggers for a single plan. In such case a build will run for a plan whenever condition of any trigger is satisfied.
No triggers
You can of course configure your plan to have no triggers at all. In such case the plan have to be executed manually. This is useful when human decision is required, for instance publishing a new product release.
Requirements
In the example below, the Maven task will implicitly add requirements for Maven and JDK tools. We specify additional requirements on Job level.
MavenTask mavenTask = new MavenTask()
.executableLabel("Maven 3")
.jdk("JDK 1.8")
.goal("clean integration-test");
Job job = new Job(jobName, jobKey)
.tasks(mavenTask)
.requirements(new Requirement("operating.system")
.matchType(MatchType.EQUALS)
.matchValue("Linux"))
.requirements(new Requirement("xvfb"));
Configuring a job with a simple Script task usually requires specifying the requirements manually to ensure necessary capabilities exist on the agent.
ScriptTask scriptTask = new ScriptTask()
.inlineBody("mvn clean test");
Job job = new Job(jobName, jobKey)
.tasks(scriptTask)
.requirements(new Requirement("bamboo.capability.system.jdk.JDK 1.8"))
.requirements(new Requirement("bamboo.capability.system.builder.mvn3.Maven 3"));
It’s not uncommon to run the same build on different platforms, such as operating systems or databases. It’s also not uncommon to run many times with even the same set of tools but with different versions to check the compatibility matrix. In such cases defining proper requirements for a build agent is necessary.
A requirement is specified in a job or a task. A requirement specifies a capability that an agent must have for it to build that job or task. A job inherits all of the requirements specified in its tasks.
There are four types of capabilities in Bamboo that can be specified by job and task requirements:
- Executable capabilities define external programs that can be called by Bamboo, for example Ant, Maven, MSBuild or PHPUnit.
- JDK capabilities define the JDK versions to be used by the job or task.
- Version control capabilities specify the VCS client application that Bamboo should use to check out source code.
- Custom capabilities can be used to control which jobs will be built by a particular agent. For example, if the
builds for a particular job should only run in a Windows environment, you could create a custom capability of
operating.system = Windows
for the appropriate agent(s), and specify it as a requirement for this job.
To learn more, refer to the following documentation pages:
Additionally, in Bamboo variables documentation you may find details on how to refer to various types of capabilities.
Variables
Defining plan variables
Plan plan = new Plan(project, planName, planKey)
.variables(new Variable("maven.goal", "clean install -DskipTests"));
Using variables in tasks
MavenTask mavenTask = new MavenTask()
.executableLabel("Maven 3")
.goal("${bamboo.maven.goal} --batch-mode");
ScriptTask scriptTask = new ScriptTask()
.inlineBody("mvn $bamboo_mvn_goal --batch-mode");
Variables can be used to make values available when building plans in Bamboo.
- Build-specific variables are evaluated by Bamboo dynamically at build time, e.g.
bamboo.buildNumber
. - System variables apply across your entire Bamboo instance and inherit their values from system or environment
variables of the same name, e.g.
system.M2_HOME
. - Global variables are defined across your entire Bamboo instance, and have the same (static) value for every plan that is built by Bamboo.
- Plan variables are similar to global variables, but are defined for specific plans. Plan variables override global variables with the same name.
Variables can be used in configuration fields of tasks. The following format should be used when referencing a variable:
${bamboo.variableName}
- for build-specific, global and plan variables,${system.variableName}
- for system variables.
For Script task Bamboo variables are additionally exported as shell variables. All full stops (periods)
are converted to underscores. For example, the variable bamboo.my.variable
will become $bamboo_my_variable
.
To learn more about Bamboo plan variables, see Bamboo documentation.
Notifications
Defining notifications
Notification notification = new Notification()
.recipients(new UserRecipient("bob"))
.type(new XFailedChainsNotification()
.numberOfFailures(10));
Defining custom notification
Notification notification = new Notification()
.recipients(new AnyNotificationRecipient(new AtlassianModule("my-notification-recipient:plugin"))
.recipientString("recipient-configuration"))
.type(new AnyNotificationType(new AtlassianModule("my-notification-type:plugin"))
.conditionString("type-configuration"));
Defining notification for plan
Plan plan = new Plan(project, planName, planKey)
.notifications(new Notification()
.recipients(new UserRecipient("bob"))
.type(new PlanStatusChangedNotification()), new Notification()
.recipients(new ResponsibleRecipient())
.type(new JobFailedNotification()));
Defining notification for deployment project
Environment environment = new Environment("QA")
.notifications(new Notification()
.recipients(new GroupRecipient("admins"))
.type(new DeploymentFailedNotification()), new Notification()
.recipients(new EmailRecipient("dev@group.com"))
.type(new DeploymentFinishedNotification()));
Notifications in Bamboo are triggered by a range of events involving a plan and its jobs, including build completion, build outcomes and comments being posted against build results. You can configure whether notifications are sent for a particular event for each plan and job, and who they are sent to.
To learn more about Bamboo plan notifications, see Bamboo documentation.
Miscellaneous plugins
Miscellaneous plugins configuration on a plan level. Concurrent builds plugin is configured with a dedicated builder, while Build expiry and Artifact handler are using
AllOtherPluginsConfiguration
.
AllOtherPluginsConfiguration configurationForPlan = new AllOtherPluginsConfiguration()
.configuration(new MapBuilder()
.put("custom", new MapBuilder()
.put("artifactHandlers.useCustomArtifactHandlers", "false")
.put("buildExpiryConfig", new MapBuilder()
.put("duration", "1")
.put("period", "days")
.build())
.build())
.build());
ConcurrentBuilds concurrentBuilds = new ConcurrentBuilds()
.maximumNumberOfConcurrentBuilds(7);
Plan plan = new Plan(project, "My Plan One", "PLAN1")
.description("This is an example of a plan")
.enabled(true)
.stages(stage1)
.pluginConfigurations(concurrentBuilds, configurationForPlan);
Miscellaneous plugins configuration on a job level. Clover plugin is configured with
AllOtherPluginsConfiguration
.
AllOtherPluginsConfiguration configurationForJob = new AllOtherPluginsConfiguration()
.configuration(new MapBuilder()
.put("custom", new MapBuilder()
.put("clover", new MapBuilder()
.put("path", "results")
.put("license", "")
.put("integration", "custom")
.put("exists", "true")
.put("useLocalLicenseKey", "true")
.build())
.build())
.build());
Plan plan = new Plan(project, "My Plan Two", "PLAN2")
.description("This is an example of a plan")
.enabled(true)
.stages(new Stage("Stage 1")
.jobs(new Job("Job 1", "JOB")
.pluginConfigurations(configurationForJob)));
Miscellaneous plugins are used for various additional functionalities for plans and jobs like Build expiry and Clover code coverage. You can configure these plugins from the Miscellaneous tab in the web interface. Some miscellaneous plugins work only on the job level while other work only on the plan level. When you choose a plugin, make sure you’re configuring it on the right level.
In case a plugin doesn’t have a dedicated builder, you can use AllOtherPluginsConfiguration
to provide configuration for such plugins as a workaround.
Refer to plugin documentation to obtain a list of valid keys. Note that keys imported with AllOtherPluginsConfiguration
are not validated.
Deployment projects
Configuring a deployment project. Artifact Downloader Task will download all artifacts from a linked build plan, which will be next uploaded by the SCP Task.
Deployment deployment = new Deployment(new PlanIdentifier("TEST", "PLAN"), "My deployment project")
.releaseNaming(new ReleaseNaming("release-1.1")
.autoIncrement(true))
.environments(new Environment("QA")
.tasks(new ArtifactDownloaderTask()
.artifacts(new DownloadItem()
.allArtifacts(true)), new ScriptTask()
.inlineBody("echo hello"), new ScpTask()
.host("myserver")
.username("admin")
.authenticateWithPassword("admin")
.fromArtifact(new ArtifactItem()
.allArtifacts())
.toRemotePath("/remote-dir")));
A deployment project in Bamboo is a container for holding the software project you are deploying: releases that have been built and tested, and the environments to which releases are deployed. You can also defined how releases should be named when they are created by Bamboo.
To learn more about Bamboo deployment projects, see Bamboo documentation.
Specifying release name that is automatically incremented when release is created: the subsequent release names will be named “release-1.2”, “release-1.3” and so on.
ReleaseNaming releaseNaming = new ReleaseNaming("release-1.1")
.autoIncrement(true);
Specifying release name that contains some automatically incremented variables. The variable needs to be a global variable or plan variable of the associated plan.
ReleaseNaming releaseNaming = new ReleaseNaming("release-${bamboo.release_number}")
.variablesToAutoIncrement("release_number");
Configuring deployment permissions. Note that the permissions object has to be published to the Bamboo server.
DeploymentPermissions deploymentPermission = new DeploymentPermissions("My deployment project")
.permissions(new Permissions()
.userPermissions("myUserName", PermissionType.VIEW)
.userPermissions("myUserName", PermissionType.EDIT)
.loggedInUserPermissions(PermissionType.VIEW)
.groupPermissions("bamboo_users", PermissionType.EDIT));
Environments
Configuring a deployment environment.
Environment environment = new Environment("QA")
.tasks(new ArtifactDownloaderTask()
.artifacts(new DownloadItem()
.allArtifacts(true)), new ScriptTask()
.inlineBody("echo hello"))
.triggers(new ScheduledDeploymentTrigger()
.scheduleOnceDaily(LocalTime.MIDNIGHT))
.requirements(new Requirement("isLocalAgent"))
.notifications(new Notification()
.type(new DeploymentFinishedNotification())
.recipients(new UserRecipient("aUser")));
Configuring environment specific permissions. Note that the permissions object has to be published to the Bamboo server.
EnvironmentPermissions environmentPermission = new EnvironmentPermissions("My deployment project")
.environmentName("QA")
.permissions(new Permissions()
.loggedInUserPermissions(PermissionType.VIEW)
.groupPermissions("bamboo_users", PermissionType.EDIT)
.userPermissions("myUserName", PermissionType.VIEW)
.userPermissions("myUserName", PermissionType.EDIT)
.userPermissions("myUserName", PermissionType.BUILD));
An environment represents the servers or groups of servers where the software release has been deployed to, and the tasks that are needed for the deployment to work smoothly. You can also define when and to whom notifications should be send.
Deployment triggers
Triggering in Bamboo allows deployments to a specific environments to be started automatically. The following triggering methods can be used with deployment environments:
After successful plan trigger
Execute deployment when linked plan build complete
Environment environment = new Environment("QA")
.triggers(new AfterSuccessfulBuildPlanTrigger()
.triggerByBranch("qa_ready"));
After successful stage trigger
Execute deployment when linked plan’s stage build complete
Environment environment = new Environment("QA")
.triggers(new AfterSuccessfulStageTrigger("Integration tests")
.triggerByBranch("qa_ready"));
After successful deployment trigger
Execute deployment when other environment deployment complete
Deployment deployment = new Deployment(new PlanIdentifier("TEST", "TEST"), "My deployment project")
.releaseNaming(new ReleaseNaming("release-1.1")
.autoIncrement(true))
.environments(new Environment("Canaries")
.triggers(new AfterSuccessfulDeploymentTrigger("Staging")), new Environment("Staging"));
Scheduled trigger
Execute deployment by schedule
Environment environment = new Environment("QA")
.triggers(new ScheduledDeploymentTrigger()
.scheduleEvery(12, TimeUnit.HOURS)
.artifactBranch("qa_ready"));
Docker
Disabled Docker configuration. These are the default Docker settings for jobs and environments.
DockerConfiguration dockerConfiguration = new DockerConfiguration()
.enabled(false);
Enabled Docker configuration with minimum settings.
DockerConfiguration dockerConfiguration = new DockerConfiguration()
.image("postgres:latest");
How to set Docker configuration to a job or to an environment.
Job job = new Job("Default Job", "JOB1")
.dockerConfiguration(dockerConfiguration);
Environment environment = new Environment("Staging")
.dockerConfiguration(dockerConfiguration);
Builds and deployments are normally run on the Bamboo agent’s native operating system. However, both jobs and environments can be instrumented to be run in a Docker container, for better control over the available tool set and additional build isolation.
See the examples on how to set up basic Docker configuration, and how to append it to a job or to an environment.
Image
A simple enabled Docker configuration with specified Docker image.
DockerConfiguration dockerConfiguration = new DockerConfiguration()
.image("localhost:5000/my-image:${bamboo.my.image.version}");
To run a job or an environment in a Docker container, you’ll need to specify which Docker image to use.
You can choose the repository host, namespace and tag for the image, by following the standard Docker image format,
for example localhost:5000/namespace/image:tag
.
Bamboo variables are allowed in the Docker image configuration field.
Volumes
Docker configuration with the default data volumes and a few custom ones.
DockerConfiguration dockerConfiguration = new DockerConfiguration()
.image("ubuntu")
.volume("${bamboo.my.host.dir}", "/opt/${bamboo.my.container.dir}")
.volume("/bin", "~/bin")
.volume("/etc", "~/etc");
Docker configuration without the default data volumes.
DockerConfiguration dockerConfiguration = new DockerConfiguration()
.image("ubuntu")
.withoutDefaultVolumes();
You may choose which agent’s directories should be mounted in the Docker container under specific paths. This way you can define additional data volumes for the Docker container.
By default, Bamboo maps some of the agent’s directories to corresponding directories in the Docker container. You can disable this behaviour if it’s undesirable.
Bamboo variables are allowed in data volumes configuration fields.
Dependencies
Dependencies are configured with setting options on
Dependencies
andDependenciesConfiguration
objects.
Plan plan = new Plan(project, "My Plan One", "PLAN1")
.description("This is an example of a plan")
.enabled(true)
.stages(stage1)
.dependencies(new Dependencies()
.configuration(new DependenciesConfiguration()
.requireAllStagesPassing(true))
.childPlans(new PlanIdentifier("PROA", "PLAN2"), new PlanIdentifier("PROA", "PLAN3")));
While other options are set on
DependenciesConfiguration
object, automatic dependencies can be configured with a plugin method.
Plan plan = new Plan(project, "My Plan One", "PLAN1")
.description("This is an example of a plan")
.enabled(true)
.stages(stage1)
.pluginConfigurations(new AllOtherPluginsConfiguration()
.configuration(new MapBuilder()
.put("custom.dependency.automaticManagement.enabled", "true")
.build()));
Child plans are triggered after execution of a parent plan. You can configure child plans from the Dependencies tab in the web interface.
Note that Bamboo Specs override existing settings. Hence omitting dependencies section results in removing of all existing dependencies.
Automatic dependency management is controlled in the web interface from the Dependencies tab. However, in Bamboo Specs, this setting is configured using a plugin method (see examples). Automatic dependencies are omitted when exporting to Bamboo Specs. In case a plan already has an automatic dependency on another plan, an attempt to add the same dependency manually will be ignored.
Utilities
Publish plan to Bamboo using URL, login and password provided from a command line. In public static void main(String[] args):
String bambooUrl = args[0];
UserPasswordCredentials adminUser = new SimpleUserPasswordCredentials(args[1], args[2]);
BambooServer server = new BambooServer(bambooUrl, adminUser);
server.publish(createPlan());;
The Bamboo Specs library comes with several helper classes, which can ease task of deploying a spec to Bamboo.
BambooSpec - an annotation to mark classes which can publish a plan; used by the Bamboo Specs Runner plugin for Maven
BambooServer - publish a plan, a plan permission or a deployment project to Bamboo running on certain URL using a provided credentials
UserPasswordCredentials - an interface for providing credentials, you can implement it to provide custom source
FileUserPasswordCredentials - read login and password from ‘.credentials’ file from current working directory
SimpleUserPasswordCredentials - pass login and password directly