Skip to content

Setting Goals

This page assumes you have created some goals. It shows how to:

  • group goals
  • set dependencies between goals
  • choose which goals to execute on each push
  • prevent the SDM from setting goals on a push

Grouping goals

You can group goals into sets. Start creating a goal set with the goals method; give it a name. Add goals to the set with the plan method.

    const BaseGoals = goals("checks")

The plan method accepts one or more goals. The code below is equivalent to the code above:

    const BaseGoals = goals("checks")
        .plan(codeInspection, autofix);


By default, all goals execute in parallel. If some goals should wait for others to succeed, you can give them preconditions as you add them to a plan. To do this, call the after method immediately after plan.

The following example constructs a goal set called “build” with three goals: autofix, codeInspection, and mavenBuild. The mavenBuild goal will execute only after autofix completes successfully.

    const BuildGoals = goals("build")
        .plan(autofix, codeInspection)

Note that the after method affects only the goals in the last call to plan. Here, the mavenBuild goal gets a precondition that the autofix goal must complete successfully.

The goals listed in after can be part of this goal set, but they don’t have to be. They could be in another goal set that is also added to the push. If the goal in after is not attached to a particular push at all, then the precondition is ignored. See the next section for how to attach goal sets to a push.

Set goals on push with “push rules”

Finally, you can tell the SDM which goals to run on each push. Here, we set the BaseGoals (inspection and autofix) on every push. Then if this is a Maven project (identified by having a pom.xml), we do the build as well.


The rules are evaluated in order. The resulting goals are combined and de-duplicated to determine the goals that will be set on the push.

The rules themselves are written in a simple internal DSL that aims to be human readable.

The onAnyPush() function will return true on all pushes.

The whenPushSatisfies function is used to combine other rules. For example, we could limit building to Java projects, rather than all Maven projects, as follows:

whenPushSatisfies(IsMaven, IsJava).setGoals(BuildGoals),

The DSL includes support for logical operations. For example, this will build all Maven projects except Kotlin projects:

whenPushSatisfies(IsMaven, not(IsKotlin)).setGoals(BuildGoals),


Each argument to sdm.withPushRules is a PushRule, contributing goals on a commit if a condition is met. That condition is a PushTest.


Push tests are functions that look at the content of a push and decide whether this goal applies.

See: Documentation on Push Tests

Here’s a quick example of a push test:

export const IsMaven: PredicatePushTest = predicatePushTest(
    "Is Maven",
    p => p.hasFile("pom.xml"));

To establish a PushTest for whether a project uses Maven as a build tool, this code calls a constructor function predicatePushTest with a name for the PushTest and a function from a Project to a Promise<Boolean>.

The example spring-sdm uses this PushTest to create a PushRule, which sets build goals only on Maven projects:


Stop setting goals

Sometimes we want to stop setting goals after a particular rule evaluates to true.

For example, we can modify the earlier example to do nothing at all if the project has a leaveMeAlone file in the root directory:

    whenPushSatisfies(async pu => pu.project.hasFile("leaveMeAlone")).setGoals(goals("none").andLock()),

The andLock method on the Goals class causes further goal evaluation to be ignored.