Uploaded image for project: 'Bamboo Data Center'
  1. Bamboo Data Center
  2. BAM-20155

Implement functionality to define Tasks at Plan level, as well as at Job level

XMLWordPrintable

    • 0
    • 1
    • Our product teams collect and evaluate feedback from a number of different sources. To learn more about how we use customer feedback in the planning process, check out our new feature policy.

      Currently, Bamboo UI only allows defining tasks at a Job level (there's no 'Tasks' tab in 'Plan Configuration' view, the only place it's available - is within a Job view). What this results in - is that all tasks must be defined for each job, even if same exact task is defined for another job. This may not be an issue for plans with just one job, or with jobs containing entirely different sets of tasks. But... for plans that include similar jobs (jobs containing same tasks) - this results in unnecessary duplication of task definitions.

       

      Consider a plan containing 3 jobs: arm32-rev1-buildarm32-rev2-buildx64-generic-build. Each job contains an identical set of tasks (5 tasks in our case) - dedicated to platform/flavor specific builds. Each job includes a 'Source Code Checkout' task, a 'Setup' task, a build ('Run Docker Container') task, and some other tasks (3 sets of virtually identical tasks).

      Here's an example of Plan specs extracted for this plan:

      import com.atlassian.bamboo.specs.api.BambooSpec;
      import com.atlassian.bamboo.specs.api.builders.AtlassianModule;
      import com.atlassian.bamboo.specs.api.builders.BambooKey;
      import com.atlassian.bamboo.specs.api.builders.BambooOid;
      import com.atlassian.bamboo.specs.api.builders.Variable;
      import com.atlassian.bamboo.specs.api.builders.notification.AnyNotificationRecipient;
      import com.atlassian.bamboo.specs.api.builders.notification.Notification;
      import com.atlassian.bamboo.specs.api.builders.permission.PermissionType;
      import com.atlassian.bamboo.specs.api.builders.permission.Permissions;
      import com.atlassian.bamboo.specs.api.builders.permission.PlanPermissions;
      import com.atlassian.bamboo.specs.api.builders.plan.Job;
      import com.atlassian.bamboo.specs.api.builders.plan.Plan;
      import com.atlassian.bamboo.specs.api.builders.plan.PlanIdentifier;
      import com.atlassian.bamboo.specs.api.builders.plan.Stage;
      import com.atlassian.bamboo.specs.api.builders.plan.artifact.Artifact;
      import com.atlassian.bamboo.specs.api.builders.plan.branches.BranchCleanup;
      import com.atlassian.bamboo.specs.api.builders.plan.branches.PlanBranchManagement;
      import com.atlassian.bamboo.specs.api.builders.plan.configuration.AllOtherPluginsConfiguration;
      import com.atlassian.bamboo.specs.api.builders.plan.configuration.ConcurrentBuilds;
      import com.atlassian.bamboo.specs.api.builders.project.Project;
      import com.atlassian.bamboo.specs.api.builders.repository.VcsRepositoryIdentifier;
      import com.atlassian.bamboo.specs.api.builders.requirement.Requirement;
      import com.atlassian.bamboo.specs.api.builders.task.AnyTask;
      import com.atlassian.bamboo.specs.builders.notification.PlanCompletedNotification;
      import com.atlassian.bamboo.specs.builders.notification.PlanFailedNotification;
      import com.atlassian.bamboo.specs.builders.notification.ResponsibilityChangedNotification;
      import com.atlassian.bamboo.specs.builders.notification.ResponsibleRecipient;
      import com.atlassian.bamboo.specs.builders.task.CheckoutItem;
      import com.atlassian.bamboo.specs.builders.task.ScriptTask;
      import com.atlassian.bamboo.specs.builders.task.VcsCheckoutTask;
      import com.atlassian.bamboo.specs.builders.trigger.BitbucketServerTrigger;
      import com.atlassian.bamboo.specs.model.task.ScriptTaskProperties;
      import com.atlassian.bamboo.specs.util.BambooServer;
      import com.atlassian.bamboo.specs.util.MapBuilder;
      
      
      @BambooSpec
      public class PlanSpec {
          
          public Plan plan() {
              final Plan plan = new Plan(new Project()
                      .oid(new BambooOid("lrq0xrb9llac"))
                      .key(new BambooKey("CAT"))
                      .name("CatOne"),
                  "Platform Test",
                  new BambooKey("PLATR1TEST"))
                  .oid(new BambooOid("lrgbq5y1sf1f"))
                  .description("Rev 1 and Rev 2 Builds")
                  .pluginConfigurations(new ConcurrentBuilds()
                          .useSystemWideDefault(false),
                      new AllOtherPluginsConfiguration()
                          .configuration(new MapBuilder()
                                  .put("custom", new MapBuilder()
                                      .put("artifactHandlers.useCustomArtifactHandlers", "false")
                                      .put("buildExpiryConfig.enabled", "false")
                                      .build())
                                  .build()))
                  .stages(new Stage("Build")
                          .description("Build Platform Variants")
                          .jobs(new Job("x64-generic-build",
                                  new BambooKey("X64GEN"))
                                  .pluginConfigurations(new AllOtherPluginsConfiguration()
                                          .configuration(new MapBuilder()
                                                  .put("custom", new MapBuilder()
                                                      .put("auto", new MapBuilder()
                                                          .put("regex", "")
                                                          .put("label", "")
                                                          .build())
                                                      .put("buildHangingConfig", new MapBuilder()
                                                          .put("minutesBetweenLogs", "60")
                                                          .put("minutesQueueTimeout", "5")
                                                          .put("multiplier", "2.5")
                                                          .put("enabled", "true")
                                                          .build())
                                                      .put("ncover.path", "")
                                                      .put("clover", new MapBuilder()
                                                          .put("path", "")
                                                          .put("license", "")
                                                          .put("useLocalLicenseKey", "true")
                                                          .build())
                                                      .build())
                                                  .build()))
                                  .artifacts(new Artifact()
                                          .name("X64-Generic Versions")
                                          .copyPattern("*_versions.properties")
                                          .location("build/catone-platform")
                                          .shared(true))
                                  .tasks(new VcsCheckoutTask()
                                          .description("Checkout Default Repository")
                                          .checkoutItems(new CheckoutItem().defaultRepository()
                                                  .path("src/platform"),
                                              new CheckoutItem()
                                                  .repository(new VcsRepositoryIdentifier()
                                                          .name("build_scripts"))
                                                  .path("src/build_scripts"))
                                          .cleanCheckout(true),
                                      new ScriptTask()
                                          .description("Setup Working Dir")
                                          .location(ScriptTaskProperties.Location.FILE)
                                          .fileFromPath("${bamboo.working.directory}/src/build_scripts/setup.sh"),
                                      new ScriptTask()
                                          .description("Add Remote Origin")
                                          .location(ScriptTaskProperties.Location.FILE)
                                          .fileFromPath("${bamboo.working.directory}/src/build_scripts/add_origin.sh"),
                                      new ScriptTask()
                                          .description("Run docker container")
                                          .enabled(false)
                                          .location(ScriptTaskProperties.Location.FILE)
                                          .fileFromPath("${bamboo.working.directory}/src/build_scripts/catone/platform/run_docker.sh")
                                          .argument("x64 generic"),
                                      new AnyTask(new AtlassianModule("com.illucit.bamboo-variables-extractor-plugin:variable-updater"))
                                          .description("Platform Version")
                                          .enabled(false)
                                          .configuration(new MapBuilder()
                                                  .put("variable", "platformVersionArm32Rev1")
                                                  .put("filename", "build/catone-platform/catone-platform_versions.properties")
                                                  .put("expression", "catonePlatformArm32Rev1=([a-zA-Z0-9.]+)")
                                                  .put("failIfMissing", "true")
                                                  .put("defaultValue", "")
                                                  .build()))
                                  .requirements(new Requirement("buildrootCapable")
                                          .matchValue("true")
                                          .matchType(Requirement.MatchType.EQUALS))
                                  .cleanWorkingDirectory(true),
                              new Job("arm32-rev1-build",
                                  new BambooKey("JOB1"))
                                  .description("Arm32 Rev 1 Build")
                                  .pluginConfigurations(new AllOtherPluginsConfiguration()
                                          .configuration(new MapBuilder()
                                                  .put("custom", new MapBuilder()
                                                      .put("auto", new MapBuilder()
                                                          .put("regex", "")
                                                          .put("label", "")
                                                          .build())
                                                      .put("buildHangingConfig", new MapBuilder()
                                                          .put("minutesBetweenLogs", "60")
                                                          .put("minutesQueueTimeout", "5")
                                                          .put("multiplier", "2.5")
                                                          .put("enabled", "true")
                                                          .build())
                                                      .put("ncover.path", "")
                                                      .put("clover", new MapBuilder()
                                                          .put("path", "")
                                                          .put("license", "")
                                                          .put("useLocalLicenseKey", "true")
                                                          .build())
                                                      .build())
                                                  .build()))
                                  .artifacts(new Artifact()
                                          .name("Arm32-Rev1 Versions")
                                          .copyPattern("*_versions.properties")
                                          .location("build/catone-platform")
                                          .shared(true))
                                  .tasks(new VcsCheckoutTask()
                                          .description("Checkout Default Repository")
                                          .checkoutItems(new CheckoutItem().defaultRepository()
                                                  .path("src/platform"),
                                              new CheckoutItem()
                                                  .repository(new VcsRepositoryIdentifier()
                                                          .name("build_scripts"))
                                                  .path("src/build_scripts"))
                                          .cleanCheckout(true),
                                      new ScriptTask()
                                          .description("Setup Working Dir")
                                          .location(ScriptTaskProperties.Location.FILE)
                                          .fileFromPath("${bamboo.working.directory}/src/build_scripts/setup.sh"),
                                      new ScriptTask()
                                          .description("Add Remote Origin")
                                          .location(ScriptTaskProperties.Location.FILE)
                                          .fileFromPath("${bamboo.working.directory}/src/build_scripts/add_origin.sh"),
                                      new ScriptTask()
                                          .description("Run docker container")
                                          .location(ScriptTaskProperties.Location.FILE)
                                          .fileFromPath("${bamboo.working.directory}/src/build_scripts/catone/platform/run_docker.sh")
                                          .argument("arm32 rev1"),
                                      new AnyTask(new AtlassianModule("com.illucit.bamboo-variables-extractor-plugin:variable-updater"))
                                          .description("Platform Version")
                                          .configuration(new MapBuilder()
                                                  .put("variable", "platformVersionArm32Rev1")
                                                  .put("filename", "build/catone-platform/catone-platform_versions.properties")
                                                  .put("expression", "catonePlatformArm32Rev1=([a-zA-Z0-9.]+)")
                                                  .put("failIfMissing", "true")
                                                  .put("defaultValue", "")
                                                  .build()))
                                  .requirements(new Requirement("buildrootCapable")
                                          .matchValue("true")
                                          .matchType(Requirement.MatchType.EQUALS))
                                  .cleanWorkingDirectory(true),
                              new Job("arm32-rev2-build",
                                  new BambooKey("REV2"))
                                  .description("Arm32 Rev 2 Build")
                                  .pluginConfigurations(new AllOtherPluginsConfiguration()
                                          .configuration(new MapBuilder()
                                                  .put("custom", new MapBuilder()
                                                      .put("auto", new MapBuilder()
                                                          .put("regex", "")
                                                          .put("label", "")
                                                          .build())
                                                      .put("buildHangingConfig", new MapBuilder()
                                                          .put("minutesBetweenLogs", "60")
                                                          .put("minutesQueueTimeout", "5")
                                                          .put("multiplier", "2.5")
                                                          .put("enabled", "true")
                                                          .build())
                                                      .put("ncover.path", "")
                                                      .put("clover", new MapBuilder()
                                                          .put("path", "")
                                                          .put("license", "")
                                                          .put("useLocalLicenseKey", "true")
                                                          .build())
                                                      .build())
                                                  .build()))
                                  .artifacts(new Artifact()
                                          .name("Arm32-Rev2 Versions")
                                          .copyPattern("*_versions.properties")
                                          .location("build/catone-platform")
                                          .shared(true))
                                  .tasks(new VcsCheckoutTask()
                                          .description("Checkout Default Repository")
                                          .checkoutItems(new CheckoutItem().defaultRepository()
                                                  .path("src/platform"),
                                              new CheckoutItem()
                                                  .repository(new VcsRepositoryIdentifier()
                                                          .name("build_scripts"))
                                                  .path("src/build_scripts"))
                                          .cleanCheckout(true),
                                      new ScriptTask()
                                          .description("Setup Working Dir")
                                          .location(ScriptTaskProperties.Location.FILE)
                                          .fileFromPath("${bamboo.working.directory}/src/build_scripts/setup.sh"),
                                      new ScriptTask()
                                          .description("Add Remote Origin")
                                          .location(ScriptTaskProperties.Location.FILE)
                                          .fileFromPath("${bamboo.working.directory}/src/build_scripts/add_origin.sh"),
                                      new ScriptTask()
                                          .description("Run docker container")
                                          .enabled(false)
                                          .location(ScriptTaskProperties.Location.FILE)
                                          .fileFromPath("${bamboo.working.directory}/src/build_scripts/catone/platform/run_docker.sh")
                                          .argument("arm32 rev2"),
                                      new AnyTask(new AtlassianModule("com.illucit.bamboo-variables-extractor-plugin:variable-updater"))
                                          .description("Platform Version")
                                          .enabled(false)
                                          .configuration(new MapBuilder()
                                                  .put("variable", "platformVersionArm32Rev1")
                                                  .put("filename", "build/catone-platform/catone-platform_versions.properties")
                                                  .put("expression", "catonePlatformArm32Rev1=([a-zA-Z0-9.]+)")
                                                  .put("failIfMissing", "true")
                                                  .put("defaultValue", "")
                                                  .build()))
                                  .requirements(new Requirement("buildrootCapable")
                                          .matchValue("true")
                                          .matchType(Requirement.MatchType.EQUALS))
                                  .cleanWorkingDirectory(true)))
                  .linkedRepositories("catone-platform",
                      "catone-br2_external",
                      "build_scripts")
                  
                  .triggers(new BitbucketServerTrigger()
                          .description("repository commit trigger"))
                  .variables(new Variable("project_artifactoryURL",
                          "${bamboo.artifactoryURL}/api/build/promote/catone-platform"))
                  .planBranchManagement(new PlanBranchManagement()
                          .delete(new BranchCleanup()
                              .whenRemovedFromRepositoryAfterDays(7)
                              .whenInactiveInRepositoryAfterDays(30))
                          .notificationForCommitters())
                  .notifications(new Notification()
                          .type(new ResponsibilityChangedNotification())
                          .recipients(new ResponsibleRecipient()),
                      new Notification()
                          .type(new PlanCompletedNotification())
                          .recipients(new AnyNotificationRecipient(new AtlassianModule("com.atlassian.bamboo.plugins.bamboo-slack:recipient.slack"))
                                  .recipientString("${bamboo.slackBambooBotURL}")),
                      new Notification()
                          .type(new PlanFailedNotification())
                          .recipients(new ResponsibleRecipient()))
                  .forceStopHungBuilds();
              return plan;
          }
          
          public PlanPermissions planPermission() {
              final PlanPermissions planPermission = new PlanPermissions(new PlanIdentifier("CAT", "PLATR1TEST"))
                  .permissions(new Permissions()
                          .loggedInUserPermissions(PermissionType.VIEW, PermissionType.BUILD));
              return planPermission;
          }
          
          public static void main(String... argv) {
              //By default credentials are read from the '.credentials' file.
              BambooServer bambooServer = new BambooServer("https://bamboo.is.idexx.com");
              final PlanSpec planSpec = new PlanSpec();
              
              final Plan plan = planSpec.plan();
              bambooServer.publish(plan);
              
              final PlanPermissions planPermission = planSpec.planPermission();
              bambooServer.publish(planPermission);
          }
      }
      

      Notice (virtually) identical set of tasks defined for each job (3 sets of those)...

      In case like this (and I am sure in many others) - it makes much better sense to define tasks outside of a Job (at a Plan Configuration level), and simply allow listing them (including) in job's Tasks configuration tab (as well as allow defining some job-specific attributes - like enabled/disabled, script arguments, etc.).

      Having ability to define Tasks at Plan Configuration level, and simply include them in individual job's 'Tasks' configuration tab - would eliminate the need to define same tasks multiple times (which also reduces inconsistency and potential for errors across multiple jobs); would allow jobs to "pick-and-choose" which tasks they need to use (as well as set job-specific attributes like enabling/disabling the task, passing job-specific script arguments, etc.), as well as allow additional tasks to be defined at job level (which are not available to other jobs).

       

      Here's an example of same plan's Java specs refactored to demonstrate this case:

          public Plan plan() {
          	// Define tasks
          	VcsCheckoutTask checkoutTask = new VcsCheckoutTask()
      	        .description("Checkout Default Repository")
      	        .enabled(true)
      	        .checkoutItems(new CheckoutItem().defaultRepository()
      	                .path("src/platform"),
      	            new CheckoutItem()
      	                .repository(new VcsRepositoryIdentifier()
      	                        .name("build_scripts"))
      	                .path("src/build_scripts"))
      	        .cleanCheckout(true);
          	
          	ScriptTask setupTask = new ScriptTask()
      	        .description("Setup Working Dir")
      	        .fileFromPath("${bamboo.working.directory}/src/build_scripts/setup.sh");
          	
          	ScriptTask addOriginTask = new ScriptTask()
                  .description("Add Remote Origin")
                  .fileFromPath("${bamboo.working.directory}/src/build_scripts/add_origin.sh");
          	
          	ScriptTask runDockerTask = new ScriptTask()
                  .description("Run docker container")
                  .fileFromPath("${bamboo.working.directory}/src/build_scripts/catone/platform/run_docker.sh");
          	
          	AnyTask varUpdaterTask = new AnyTask(new AtlassianModule("com.illucit.bamboo-variables-extractor-plugin:variable-updater"))
                  .description("Platform Version")
                  .configuration(new MapBuilder()
      	            .put("variable", "platformVersionArm32Rev1")
      	            .put("filename", "build/catone-platform/catone-platform_versions.properties")
      	            .put("expression", "catonePlatformArm32Rev1=([a-zA-Z0-9.]+)")
      	            .put("failIfMissing", "true")
      	            .put("defaultValue", "")
      	            .build());
          	
              final Plan plan = new Plan(new Project()
                      .key(new BambooKey("CAT"))
                      .name("CatOne"),
                  "Platform Test",
                  new BambooKey("PLATR1TEST"))
                  .description("Rev 1 and Rev 2 Builds")
                  .enabled(true)
                  .pluginConfigurations(new ConcurrentBuilds()
                          .useSystemWideDefault(false),
                      new AllOtherPluginsConfiguration()
                          .configuration(new MapBuilder()
                                  .put("custom", new MapBuilder()
                                      .put("artifactHandlers.useCustomArtifactHandlers", "false")
                                      .put("buildExpiryConfig.enabled", "false")
                                      .build())
                                  .build()))
                  .stages(new Stage("Build")
                          .description("Build Platform Variants")
                          .jobs(new Job("arm32-rev1-build",
                                  new BambooKey("JOB1"))
                                  .description("Arm32 Rev 1 Build")
                                  .pluginConfigurations(new AllOtherPluginsConfiguration()
                                          .configuration(new MapBuilder()
                                                  .put("custom", new MapBuilder()
                                                      .put("auto", new MapBuilder()
                                                          .put("regex", "")
                                                          .put("label", "")
                                                          .build())
                                                      .put("buildHangingConfig", new MapBuilder()
                                                          .put("minutesBetweenLogs", "60")
                                                          .put("minutesQueueTimeout", "5")
                                                          .put("multiplier", "2.5")
                                                          .put("enabled", "true")
                                                          .build())
                                                      .put("ncover.path", "")
                                                      .put("clover", new MapBuilder()
                                                          .put("path", "")
                                                          .put("license", "")
                                                          .put("useLocalLicenseKey", "true")
                                                          .build())
                                                      .build())
                                                  .build()))
                                  .artifacts(new Artifact()
                                          .name("Arm32-Rev1 Versions")
                                          .copyPattern("*_versions.properties")
                                          .location("build/catone-platform")
                                          .shared(true))
                                  .tasks(checkoutTask.enabled(true), 
                                  		setupTask.enabled(true),
                                  		addOriginTask.enabled(true),
                                  		runDockerTask.enabled(true).argument("arm32 rev1"),
                                  		varUpdaterTask.enabled(true))
                                  .requirements(new Requirement("buildrootCapable")
                                          .matchValue("true")
                                          .matchType(Requirement.MatchType.EQUALS))
                                  .cleanWorkingDirectory(true)
                                  .dockerConfiguration(new DockerConfiguration()
                                          .enabled(false)),
                              new Job("arm32-rev2-build",
                                  new BambooKey("REV2"))
                                  .description("Arm32 Rev 2 Build")
                                  .pluginConfigurations(new AllOtherPluginsConfiguration()
                                          .configuration(new MapBuilder()
                                                  .put("custom", new MapBuilder()
                                                      .put("auto", new MapBuilder()
                                                          .put("regex", "")
                                                          .put("label", "")
                                                          .build())
                                                      .put("buildHangingConfig", new MapBuilder()
                                                          .put("minutesBetweenLogs", "60")
                                                          .put("minutesQueueTimeout", "5")
                                                          .put("multiplier", "2.5")
                                                          .put("enabled", "true")
                                                          .build())
                                                      .put("ncover.path", "")
                                                      .put("clover", new MapBuilder()
                                                          .put("path", "")
                                                          .put("license", "")
                                                          .put("useLocalLicenseKey", "true")
                                                          .build())
                                                      .build())
                                                  .build()))
                                  .artifacts(new Artifact()
                                          .name("Arm32-Rev2 Versions")
                                          .copyPattern("*_versions.properties")
                                          .location("build/catone-platform")
                                          .shared(true))
                                  .tasks(checkoutTask.enabled(true), 
                                  		setupTask.enabled(true),
                                  		addOriginTask.enabled(true),
                                  		runDockerTask.enabled(false).argument("arm32 rev2"),
                                  		varUpdaterTask.enabled(false))
                                  .requirements(new Requirement("buildrootCapable")
                                          .matchValue("true")
                                          .matchType(Requirement.MatchType.EQUALS))
                                  .cleanWorkingDirectory(true)
                                  .dockerConfiguration(new DockerConfiguration()
                                          .enabled(false)),
                              new Job("x64-generic-build",
                                  new BambooKey("X64GEN"))
                                  .pluginConfigurations(new AllOtherPluginsConfiguration()
                                          .configuration(new MapBuilder()
                                                  .put("custom", new MapBuilder()
                                                      .put("auto", new MapBuilder()
                                                          .put("regex", "")
                                                          .put("label", "")
                                                          .build())
                                                      .put("buildHangingConfig", new MapBuilder()
                                                          .put("minutesBetweenLogs", "60")
                                                          .put("minutesQueueTimeout", "5")
                                                          .put("multiplier", "2.5")
                                                          .put("enabled", "true")
                                                          .build())
                                                      .put("ncover.path", "")
                                                      .put("clover", new MapBuilder()
                                                          .put("path", "")
                                                          .put("license", "")
                                                          .put("useLocalLicenseKey", "true")
                                                          .build())
                                                      .build())
                                                  .build()))
                                  .artifacts(new Artifact()
                                          .name("X64-Generic Versions")
                                          .copyPattern("*_versions.properties")
                                          .location("build/catone-platform")
                                          .shared(true))
                                  .tasks(checkoutTask.enabled(true), 
                                  		setupTask.enabled(true),
                                  		addOriginTask.enabled(true),
                                  		runDockerTask.enabled(false).argument("x64 generic"),
                                  		varUpdaterTask.enabled(false))
                                  .requirements(new Requirement("buildrootCapable")
                                          .matchValue("true")
                                          .matchType(Requirement.MatchType.EQUALS))
                                  .cleanWorkingDirectory(true)))
                  .linkedRepositories("catone-platform", "catone-br2_external", "build_scripts")
                  
                  .triggers(new BitbucketServerTrigger()
                          .description("repository commit trigger"))
                  .variables(new Variable("project_artifactoryURL",
                          "${bamboo.artifactoryURL}/api/build/promote/catone-platform"))
      
      
                  .planBranchManagement(new PlanBranchManagement()
                          .delete(new BranchCleanup()
                              .whenRemovedFromRepositoryAfterDays(7)
                              .whenInactiveInRepositoryAfterDays(30))
                          .notificationForCommitters())
                  .noDependencies()
      //            .dependencies(new Dependencies()
      //                    .configuration(new DependenciesConfiguration()
      //                            .requireAllStagesPassing(true))
      //                    .childPlans(new PlanIdentifier("CAT", "AP")))
                  .notifications(new Notification()
                          .type(new ResponsibilityChangedNotification())
                          .recipients(new ResponsibleRecipient()),
                      new Notification()
                          .type(new PlanCompletedNotification())
                          .recipients(new AnyNotificationRecipient(new AtlassianModule("com.atlassian.bamboo.plugins.bamboo-slack:recipient.slack"))
                                  .recipientString("${bamboo.slackBambooBotURL}")),
                      new Notification()
                          .type(new PlanFailedNotification())
                          .recipients(new ResponsibleRecipient()));
              return plan;
          }
          
          public PlanPermissions planPermission() {
              final PlanPermissions planPermission = new PlanPermissions(new PlanIdentifier("CAT", "PLATR1TEST"))
                  .permissions(new Permissions()
                          .loggedInUserPermissions(PermissionType.BUILD, PermissionType.VIEW));
              return planPermission;
          }
          
          public static void main(String... argv) {
              //By default credentials are read from the '.credentials' file.
              BambooServer bambooServer = new BambooServer("https://bamboo.is.idexx.com");
              final Build_PlanSpec planSpec = new Build_PlanSpec();
              
              final Plan plan = planSpec.plan();
              bambooServer.publish(plan);
              
              final PlanPermissions planPermission = planSpec.planPermission();
              bambooServer.publish(planPermission);
          }
      
      

      Notice how tasks are defined outside of any job (at the top of the class, before Plan object is created) - and task objects simply used (listed) in the .tasks() calls within each job. Example:

      .tasks(checkoutTask.enabled(true), 
            setupTask.enabled(true),
            addOriginTask.enabled(true),
            runDockerTask.enabled(true).argument("arm32 rev1"),
            varUpdaterTask.enabled(true))
      

      See how much it improves overall quality of the code, how much smaller the code becomes, and how much sense it makes (from development prospective)?

       

      So... this suggestion - is for Bamboo development team to implement UI functionality that allows all this:

       

      1. Implement 'Tasks' tab in the Plan Configuration view
      2. Updates to Job's 'Tasks' tab to allow:
        • adding task(s) defined for the Plan
        • setting task-specific parameters (possibly overriding those defined at Plan level)
        • enable/disable a task
        • add new task(s) - using existing implementation (these job-level tasks will not be available/visible to other jobs)
      3. Update Java Specs extraction code to generate code appropriately (similarly to my example above)

       

       

              Unassigned Unassigned
              f4ed9518026d Valeriy Pogrebitskiy
              Votes:
              2 Vote for this issue
              Watchers:
              4 Start watching this issue

                Created:
                Updated:
                Resolved: