Plan Creation Scripting


On this page

Summary

The Bamboo CLI can be used to create plans using a CLI script. Conversely, the exportPlan action can be used to easily get started with plan creation scripting. This is a major step forward for managing Bamboo build environments including the ability to put your plan scripts under source control. Similar support is available for deployment projects using exportDeploymentProject and exportEnvironment actions.

Do you have any of these problems?

  1. Plans not doing everything they are suppose to? It is hard to visualize a plan or compare plans.
  2. Cloning plans and having them diverge. 
  3. Keeping similar plans in sync. 
  4. Keeping multiple Bamboo instances consistent with plan definitions.

Internally, we have the same problem and the fix was to get plan creation scripts under source control where changes could be controlled and similar plans created from the same source. We maintain multiple Bamboo sites including multiple production build instances (restricted instances for releasing products) and developer build instances. Prior to this ability, the plans diverge. Release 4.3 contains the basics for creating build plans using the most common elements. Now we have hundreds of plans created this way! More capabilities will be added based on feedback, please open an issue with your specific requirements.

There are a number of Bamboo limitations that have been worked around as best as possible. It is hoped these can be improved with future Bamboo support. For instance, plan or job deletes take place in the background and replacement plans or jobs cannot be created until they are fully deleted. Scripting will wait for this to occur, but it can take a minute or so. This means recreate scenarios take longer than one would expect. Adding tasks can be difficult to get working. We have some examples (Examples for AddTask Action), but, some careful work is required to get new ones working correctly :(. The best approach is to use exportPlan of an existing plan that represents the main elements of the kind of plan you want to create. The export provides insight and a starting point for your new plan source. Start simple and gradually add improvements and simplifications to reduce redundancy. Using bamboo variables is strongly recommended to simplify plans, making maintenance easier, and essentially parameterizing your plan.

Note that on re-create of a plan, Bamboo will no longer discard previous build logs on Bamboo 6.9 or higher (see BAM-15957).

See the movePlans tip below - this is the most effective way of avoiding both of these limitations! Moving plans preserves the logs and makes the recreate of the plans very fast. With an archiving process and convention defined using movePlans, you can now safely make sure all your plans are updated from the latest source quickly while preserving history.

NEW for CLI 6.4 - Exporting existing plans

See Configuration as Code for more details.


Watch this page!

More documentation and examples will be published or referenced here in the future.

Features

  1. Support for standard build plan creation, replace, or update scenarios
    • createPlan
    • createPlan --replace - recommended approach that for an existing plan, under the covers, does a move, delete, and create scenario to create the plan in minimum time
    • createPlan --replace --options clear - (since CLI 8.2) modifies plan replacement by, under the covers, removing most plan constructs to enable subsequent scripting to create again from scratch useful when plan is referenced in other plans and as a way to preserve the log history.
    • createOrUpdatePlan - only creates a plan if it does not already exist and only modifies plan name and description - removed in CLI 9.0 as the other options now cover use cases better.
  2. Support for deployment projects and environments
  3. Same plan script can be used for update or create 
    • Enablers to ignore "already exists" errors for add constructs and "not found" errors for remove constructs
    • Enablers to easily remove previous constructs so they can be recreated if needed
    • Makes initial creation and debugging easier
  4. Variable replacements so scripts can be easily duplicated and re-used while minimizing text changes
  5. Scripts can be parameterized using find and replace logic
  6. exportPlan and exportDeploymentProject action can be used to create a CLI script - starting point for creating new plans
  7. Support for
    • Plans - including plan level:
      • Artifacts
      • Repositories
      • Triggers
      • Branches
      • Dependencies
      • Notifications
      • Variables
    • Stages
    • Jobs
    • Tasks - including final tasks
    • Deployment projects
    • Environments
  8. Non-plan actions can also be included in your plan creation script
    • addAgentAssignment or similar

  9. Condition portions of the plan depending on creation script parameters

Related Example Documentation

Example - Gradle

This builds the Groovy Bamboo app with Gradle and runs integration tests with Gint. The plan is parameterized by NUMBER which represents a Bamboo instance to test against. Normally, we add a Gradle task to the build to run the plan creation script easily.

#
# -a run -f bamboo.cli --findReplace "%NUMBER%:711"
#
-a createPlan            --plan "Bamboo-Groovy @NUMBER@ --replace --options addDefaultJob \
                             --repository bamboo-groovy

-a addLabels             --plan @plan@ --labels @NUMBER@
-a addVariables          --plan @plan@ --field number=@NUMBER@ \
                                       --field "buildArgs = clean build installApp -Pnumber=${bamboo.number}" \
                                       --field "itestArgs = -Pnumber=${bamboo.number} ""-Dargs=${bamboo.baseArgs}"" " \
                                       --field "baseArgs  = --continue --parallel -Dlevel=all -DincludeLevels=all"                                     
# Default stage and job - do a clean build of the jar and install the resulting app
-a addArtifact           --plan @plan@ --job @job@ --artifact jar    --location build/libs --copyPattern "*.jar" --shared
-a addTask               --plan @plan@ --job @job@ --taskKey GRADLEWRAPPER \
                                       --field "arguments=${bamboo.buildArgs}" \
                                       --field buildJdk=JDK

# Integration test - add a job for each gint tests so they run in parallel for faster build times
-a addStage              --plan @plan@ --stage "ITEST"
-a runFromList           --list "variable,task" \
                         -i "-a addJob      --plan @plan@ --stage @stage@ --job @entry@" \
                         -i "-a addArtifact --plan @plan@ --job @entry@ --artifact output_@entry@ --location build/output --copyPattern **/*" \
                         -i "-a addTask     --plan @plan@ --job @entry@ --taskKey GRADLEWRAPPER \
                                               --field ""arguments=itest-${bamboo.shortJobName} ${bamboo.itestArgs}"" \
                                               --field buildJdk=JDK \
                                               --field testChecked=true \
                            "

Example - Maven

#
# --action run --file create-plan.txt --findReplace "%PLAN%:EXAMPLE-P1:%PLAN_NAME%:,%PLAN_DESCRIPTION%:,%PROJECT_NAME%:,%STAGE_DESCRIPTION%:"
#
 
# Plan
-a createPlan            --plan %PLAN% --name "%PLAN_NAME%" --description "%PLAN_DESCRIPTION%" --projectName "%PROJECT_NAME%" --replace
-a addRepository         --plan @plan@ --name local --repositoryKey MERCURIAL --field1 repository.hg.repositoryUrl --value1 http://examplegear.com/cli --field2 repository.hg.authentication --value2 PASSWORD --field3 selectedWebRepositoryViewer --value3 bamboo.webrepositoryviewer.provided:noRepositoryViewer
-a addTrigger            --plan @plan@ --name "scheduled trigger" --type scheduled --schedule 20:00
-a addTrigger            --plan @plan@ --name "polling trigger" --repository @repository@ --type polling
-a removeVariables       --plan @plan@ --field1 @all
-a addVariables          --plan @plan@ --replace --field1 xxxx --value1 xxxx --field2 yyyy --value2 yyyy

# Stage and jobs
-a addStage              --plan @plan@ --stage "FIRST" --description "%STAGE_DESCRIPTION%"

-a addJob                --plan @plan@ --stage "@stage@" --job JOB1
-a addArtifact           --plan @plan@ --job @job@ --artifact jar --location target --copyPattern "**/*.jar" --shared
-a addArtifact           --plan @plan@ --job @job@ --artifact itest --location src/itest --copyPattern "**/*" --shared
-a addTask               --plan @plan@ --job @job@ --description "get source"    --taskKey CHECKOUT --field selectedRepository_0=defaultRepository --field checkoutDir_0=
-a addTask               --plan @plan@ --job @job@ --description "maven compile" --taskKey MAVEN2   --field "label=Maven 2" --field goal=compile --field buildJdk=JDK

# Stage and jobs
-a addStage              --plan @plan@ --stage "A"

-a addJob                --plan @plan@ --stage "@stage@" --job TEST1 --name "TEST1 job name" --description "TEST1 job description"
-a addArtifactDependency --plan @plan@ --job @job@ --artifact jar --location downloads

-a addJob                --plan @plan@ --stage "@stage@" --job "Test 2"
-a addArtifactDependency --plan @plan@ --job @job@ --artifact itest --location src/itest
-a addTask               --plan @plan@ --job @job@ --description "integration test" --taskKey GINT --field1 script --value1 src/itest/groovy/integration-test.gant --field label=Gant --field buildJdk=JDK --fields scriptLocation:FILE,levelAll:true,includeLevelsAll:true,clean:true,verbose:true,stopOnFail:false,testChecked:true,testDirectoryOption:standardTestDirectory,testResultsDirectory:**/*reports/*.xml

# Stage and jobs
-a addStage              --plan @plan@ --stage "B"

-a addJob                --plan @plan@ --stage "@stage@" --job TEST3 --name "selenium"
-a addArtifactDependency --plan @plan@ --job @job@ --artifact itest --location src/itest
-a addTask               --plan @plan@ --job @job@ --description "firefox" --taskKey GINT --field1 script --value1 src/itest/groovy/selenium-test.gant --field "arguments=-Dbrowser=firefox" --field label=Gant --field buildJdk=JDK --fields scriptLocation:FILE,levelAll:true,includeLevelsAll:true,clean:true,verbose:true,stopOnFail:false,testChecked:true,testDirectoryOption:standardTestDirectory,testResultsDirectory:**/*reports/*.xml 

Advanced Tips

Automate your automation!

Since the CLI scripts can be parameterized as indicated in the example, you can write some simple groovy, cli, or other scripts to drive the creation of sets of builds conforming to your standard process. For instance, we generate about 15 plans as soon as a new release of Confluence ships. You can take this a step further by creating a Bamboo plan that creates other plans! This plan will need to be parameterized. Run CLI Actions in Bamboo enables some of this meta-programming.

Archiving projects and plans

New for CLI 6.6 is the movePlans action. Easily archive projects or plans before replacing them with the latest plan definitions. The big advantage with this is saving all the plan logs for reference at least for a period of time. Later you can delete them all together with the deleteProject action.

Example we use for the CLI
--action movePlans --project CLI --toProject XX66CLI

How To's

Other Related Information