mibexsoftware / bamboo-plan-dsl-plugin

Configuration as code with a Groovy-based DSL or YAML for Atlassian Bamboo.
https://marketplace.atlassian.com/plugins/ch.mibex.bamboo.plandsl/
Other
40 stars 16 forks source link

Doc missing or example not working in bamboo-plan-dsl-example #24

Closed cattz closed 7 years ago

cattz commented 7 years ago

Duplicate of: https://github.com/mibexsoftware/bamboo-plan-dsl-example/issues/2

It may be I am doing something wrong (learning Groovy), but I can't get this example to work in my Bamboo instance:

  1. When running the Plan DSL sed task with this settings:

    • script location: File
    • source code checkout relative path to the DSL scripts: src/main/groovy/plans/HelloWorldPlan.groovy I get an error:
      Plan DSL: task failed: startup failed:file:/workspace/PROJ-PLAN-JOB1/src/main/groovy/plans/HelloWorldPlan.groovy: 3: unable to resolve class dsls.utilities.MyUtility @ line 3, column 1.   import dsls.utilities.MyUtility
  2. If I add the utility groovy file:

    src/main/groovy/plans/utilities/MyUtility.groovy
    src/main/groovy/plans/HelloWorldPlan.groovy

    I get the error:

    Plan DSL: task failed: MyUtility.groovy Not a valid DSL script
  3. I can't get the unit tests to pass if I use job requirements:

    
    project(key: "PKEY", name: "PrjName" {
       (...)
        stage(name: 'Prepare') {        
            job(key: 'PRE', name: 'Prepare') {
                requirements {
                    requirement(capabilityKey: 'os.linux', matchType: new Requirement.Exists()) {}
                }
            }
         }
        (...)
    }

It would be awesome to have the right way of running the example from Bamboo in its README

mrueegg commented 7 years ago

Hi,

Thanks for your feedback.

1) This is right. HelloWorldPlan.groovy needs utilities/MyUtility.groovy because it references it. With this example I wanted to show how to refactor common tasks into separate files and how to reference them.

2) The problem is the used file glob in the seed task. You probably used **/*.groovy, hence the plug-in used all Groovy files and interpreted them as DSL scripts. While this is correct for HelloWorldPlan.groovy, it isn't valid for utilities/MyUtility.groovy. We have an internal check that makes sure that only real DSL scripts (Groovy files that contain project { plan { etc.)) can be passed to the seed task. I guess that the seed task is successful if you only use *.groovy? Anyway, I have to document this better or think about removing this check.

3) I was able to run the provided unit test when including your job requirements section from above. What error did you get?

cattz commented 7 years ago
  1. I think refactoring common tasks into separate files is a very valuable technique, and having the full example repo working is an extremely good starting point.

  2. I didn't use a glob, but a single file reference: image

But I get this error:

08-Mar-2017 13:43:53    Plan DSL: start processing...
08-Mar-2017 13:43:53    Plan DSL: will now process script file from HelloWorldPlan.groovy
08-Mar-2017 13:43:53    Plan DSL: task failed: startup failed:file:/home/devsvc/bamboo-local-agents/145948704/TOOLING-BDE-JOB1/src/main/groovy/dsls/HelloWorldPlan.groovy: 3: unable to resolve class dsls.utilities.MyUtility @ line 3, column 1.   import dsls.utilities.MyUtility   ^1 error
  1. I can make the unit test pass, but I need to add this import:
    import ch.mibex.bamboo.plandsl.dsl.jobs.Requirement

    Otherwise I get the error:

    Error:(140, 71) Groovyc: unable to resolve class Requirement.Exists

    It's not such a big deal to add the import, but feels weird when no other import is needed. It is a bit in line with what my colleague raised in #15 about syntax inconsistency.

mrueegg commented 7 years ago

2) You're absolutely right, this is a bug. I have some ideas on how to remodel the example dsl repository according to this structure:

    .
    ├── dsls                         # DSL script files
    ├── src
    │   ├── main
    │   │   ├── groovy           # utility/support classes
    │   │       └── MyUtility.groovy
    │   │   └── resources
    │   │       └── idea.gdsl   # IntelliJ support
    │   └── test
    │       └── groovy             # Unit tests

This directory structure has the advantage that DSL files and utility files are not mixed anymore. Also, you have better IDE support when using the standard (Maven) directory layout for Groovy/utility classes.

What do you think?

  1. You're right, the import shouldn't be necessary. I'm not happy with the current syntax (see the discussion in #15), so I will try to change it for the next release to use enums instead of classes to allow
requirements {
  requirement(capabilityKey: 'os.linux', matchType: Requirement.Exists) {}
}
cattz commented 7 years ago
  1. I really like that layout a lot more. In my case (probably a common one) I'll be writing the utilities while other people will modify the DSLs. Having both parts separated is an advantage (we could even use separate repos and submodules). I guess it will also make easier to write the tests.

  2. I prefer that syntax, for sure , but mostly for me it's about the import. How would the other requirement rules (equal and matches) look? I'll add some comments to #15

cattz commented 7 years ago

I've created a PR in the example repo: https://github.com/mibexsoftware/bamboo-plan-dsl-example/pull/4

mrueegg commented 7 years ago

Thanks a lot for the PR!

Unfortunately, I cannot merge it right now because the current plug-in is not able to load classes from different folders (non-subfolders) than where the DSL's are located.

We will support a new field for configuring additional class paths in the seed task with the next release of the plug-in where you can e.g. enter "src/main/groovy". When this plug-in version is out, I can merge the pull request. Thanks for your understanding.

mrueegg commented 7 years ago

@cattz Please see the new example directory layout in https://github.com/mibexsoftware/bamboo-plan-dsl-example.

The syntax for the job requirements looks like this with the new release 1.6.0:

requirements {
    requirement(capabilityKey: 'system.builder.gradle.Gradle 2.2',
        matchType: equalsTo("2.2")) {
    }
    requirement(capabilityKey: 'system.builder.ant.Ant',
        matchType: exists()) {
    }
    equirement(capabilityKey: 'system.builder.mvn3.maven323',
        matchType: matches("[A-Z0-9]*")) {
    }
}

Looking forward to your feedback. Thanks again for reporting this!