Higson CLI Maven Plugin

The Higson CLI Maven Plugin (higson-cli-maven-plugin) allows you to synchronize the business logic configuration stored in your project repository with a running Higson Studio instance directly from the command line or CI/CD pipeline. The plugin uses the Studio snapshot API to perform pull (download) and push (upload) operations.

This eliminates the need to use the Higson Studio GUI for environment migrations and enables version-controlled, automated deployments of business rules configuration.

Prerequisites:

  • Java 17
  • Maven 3.x
  • Running Higson Studio instance (4.2.x)

Quick Start#

Add the plugin to your pom.xml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<plugin>
    <groupId>io.higson</groupId>
    <artifactId>higson-cli-maven-plugin</artifactId>
    <version>4.2.0</version>
    <configuration>
        <higsonSnapshotDir>${basedir}/src/main/higson</higsonSnapshotDir>
        <higsonUrl>http://localhost:8282/higson</higsonUrl>
        <higsonToken>${higsonToken}</higsonToken>
    </configuration>
</plugin>

Pull the snapshot from Studio into your local directory:

mvn higson-cli:pull

Push local changes back to Studio:

mvn higson-cli:push

Authentication#

The plugin supports two mutually exclusive authentication methods.

Provide a pre-obtained Bearer token directly. No login request is made. Recommended for CI/CD pipelines and automated environments.

1
2
3
4
5
<configuration>
    <higsonUrl>http://localhost:8282/higson</higsonUrl>
    <higsonSnapshotDir>${basedir}/src/main/higson</higsonSnapshotDir>
    <higsonToken>${higsonToken}</higsonToken>
</configuration>

Pass the token at build time:

mvn higson-cli:pull -DhigsonToken=eyJhbGciOiJIUzI1NiJ9...

The token must have the SNAPSHOT_DOWNLOAD permission for pull operations and SNAPSHOT_UPLOAD for push operations. Studio Integration Tokens can be managed in Settings → Users.

Username and password#

The plugin will call the Studio login endpoint (/api/login) and obtain a Bearer token automatically. Suitable for development environments. Do not hardcode credentials in pom.xml — use Maven property references (${higsonPassword}) resolved from ~/.m2/settings.xml or CI/CD secret injection.

1
2
3
4
5
6
<configuration>
    <higsonUrl>http://localhost:8282/higson</higsonUrl>
    <higsonSnapshotDir>${basedir}/src/main/higson</higsonSnapshotDir>
    <higsonUser>${higsonUser}</higsonUser>
    <higsonPassword>${higsonPassword}</higsonPassword>
</configuration>

Pull#

The pull goal downloads a snapshot from Studio and writes the files into higsonSnapshotDir. After extraction, the plugin prints a per-file status to the console: new (file did not exist locally), modified (content changed), or skipped (file is unchanged). If higsonSnapshotDir does not exist, the plugin creates it automatically.

mvn higson-cli:pull

Full goal reference:

mvn io.higson:higson-cli-maven-plugin:pull

Pull options#

All pull options are optional. When omitted, their default values apply.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<pullOptions>
    <tags>true</tags>
    <domains>true</domains>
    <profileWithContext>true</profileWithContext>
    <sourceProfileCodes>
        <param>PROFILE_CODE</param>
    </sourceProfileCodes>
    <functions>
        <nameStartsWith>
            <param>myapp.</param>
        </nameStartsWith>
        <filterByTags>
            <param>production</param>
        </filterByTags>
        <onlyFromActiveSession>false</onlyFromActiveSession>
    </functions>
    <decisionTables>
        <nameStartsWith>
            <param>myapp.</param>
        </nameStartsWith>
        <filterByTags>
            <param>production</param>
        </filterByTags>
        <onlyFromActiveSession>false</onlyFromActiveSession>
    </decisionTables>
    <eol>CRLF</eol>
    <excludes>
        <exclude>config.json</exclude>
        <exclude>@tags/@basic/TEMP.tag</exclude>
    </excludes>
</pullOptions>

Top-level pull options#

Parameter Type Default Description
tags boolean true Include tags in the downloaded snapshot.
domains boolean true Include domain configuration in the downloaded snapshot.
profileWithContext boolean true Include profile context data.
sourceProfileCodes list of strings empty Limit the export to the listed profile codes. When empty, all profiles are included.
eol string none Line ending conversion applied to all text files after download. Available values: LF, CR, CRLF. When not set, files are copied as-is.
excludes list of glob patterns empty Files matching any of the patterns are not written to higsonSnapshotDir.

Functions filtering#

Parameter Type Default Description
nameStartsWith list of strings empty Include only functions whose names start with any of the provided prefixes. When empty, all functions are included.
filterByTags list of strings empty Include only functions that have at least one of the listed tags assigned. When empty, tag filtering is not applied.
onlyFromActiveSession boolean false When true, includes only functions that have been modified in the currently active session.

Decision tables filtering#

Parameter Type Default Description
nameStartsWith list of strings empty Include only decision tables whose names start with any of the provided prefixes. When empty, all decision tables are included.
filterByTags list of strings empty Include only decision tables that have at least one of the listed tags assigned. When empty, tag filtering is not applied.
onlyFromActiveSession boolean false When true, includes only decision tables that have been modified in the currently active session.

Line ending conversion (EOL)#

By default, no line ending conversion is applied (files are copied as-is from the Studio response).

If you work on Windows with git config core.autocrlf=true, every pulled file may appear as modified because of line ending differences. Setting <eol>CRLF</eol> normalises all pulled text files to Windows line endings before writing them to disk, preventing false diffs.

Value Line ending Platform
LF \n Unix / Linux / macOS
CR \r Classic macOS
CRLF \r\n Windows

File exclusions#

Use excludes to prevent specific files from being overwritten on pull. Each entry is a glob pattern evaluated against the relative path of the file inside the snapshot.

1
2
3
4
5
<excludes>
    <exclude>config.json</exclude>
    <exclude>@profiles/MOTO/profile.json</exclude>
    <exclude>@tags/@basic/AGRO.tag</exclude>
</excludes>

Push#

The push goal zips the contents of higsonSnapshotDir and uploads it to Studio via the snapshot import endpoint. Imported changes land in a new session — a set of pending changes that must be explicitly published before they affect the live environment. See Sessions for how to review and publish sessions in Studio. higsonSnapshotDir must exist and must not be empty.

mvn higson-cli:push

Publish the session immediately after a successful import:

mvn higson-cli:push -DautoCommit=true

Full goal reference:

mvn io.higson:higson-cli-maven-plugin:push
mvn io.higson:higson-cli-maven-plugin:push -DautoCommit=true

autoCommit#

Parameter Type Default Description
autoCommit boolean false When true, the imported snapshot is automatically published without requiring manual session approval in Studio.

Push options#

The pushOptions block controls how Studio handles elements during import. All parameters are optional and default to false.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<pushOptions>
    <decisionTableConfig>
        <removeNotIncludedInSnapshot>false</removeNotIncludedInSnapshot>
        <forceDelete>false</forceDelete>
        <searchWithinMatrix>false</searchWithinMatrix>
    </decisionTableConfig>
    <functionConfig>
        <removeNotIncludedInSnapshot>false</removeNotIncludedInSnapshot>
        <forceDelete>false</forceDelete>
        <searchWithinMatrix>false</searchWithinMatrix>
    </functionConfig>
    <domainConfig>
        <removeNotIncludedInSnapshot>false</removeNotIncludedInSnapshot>
    </domainConfig>
</pushOptions>

These options mirror the Remove not in snapshot, Force Delete, and Search Within Parameter Matrix options available in the Studio snapshot upload UI. Refer to the Snapshot article for a detailed explanation of each behaviour.

Decision table configuration#

Parameter Type Default Description
removeNotIncludedInSnapshot boolean false Delete decision tables present in Studio but absent from the snapshot. Deletion respects the same name/tag filters that were used during export.
forceDelete boolean false Force delete decision tables even when they are referenced by other elements. May cause errors in dependent elements.
searchWithinMatrix boolean false When checking for references before deletion, also search inside decision table matrices (not only domain elements and IN-level value sources).

Function configuration#

Parameter Type Default Description
removeNotIncludedInSnapshot boolean false Delete functions present in Studio but absent from the snapshot. Deletion respects the same name/tag filters that were used during export.
forceDelete boolean false Force delete functions even when they are referenced by other elements. May cause errors in dependent elements.
searchWithinMatrix boolean false When checking for references before deletion, also search inside decision table matrices.

Domain configuration#

Parameter Type Default Description
removeNotIncludedInSnapshot boolean false Delete domain elements present in Studio but absent from the snapshot.

Import result#

After a successful push, the plugin prints an import summary to the console grouped by element type (Decision Tables, Functions, Domain, Profiles, Tags, Tests, Test Packages). A detailed log is also written to the log file (see Log files).

The build fails if Studio reports any import error. A build with warnings completes successfully.


Log files#

The plugin writes operation logs to disk after each pull or push. logFilePath sets the base path; the plugin automatically appends an operation suffix before writing:

  • Pull: higson-cli-pull.log
  • Push: higson-cli-push.log

The default base is ${basedir}/higson-cli, which results in ${basedir}/higson-cli-pull.log and ${basedir}/higson-cli-push.log.

To use a custom base path, set logFilePath in the plugin configuration:

1
2
<!-- Results in logs/higson-pull.log and logs/higson-push.log -->
<logFilePath>${basedir}/logs/higson.log</logFilePath>

Or override at build time:

mvn higson-cli:push -DlogFilePath=/path/to/custom/higson.log

The pull log contains the full export request parameters and a per-file change summary (new, modified, skipped). The push log contains per-element-type import statistics and the status (imported, skipped, error, warning, deleted) for every individual element.


Full configuration reference#

The example below includes all available parameters with their default values.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<plugin>
    <groupId>io.higson</groupId>
    <artifactId>higson-cli-maven-plugin</artifactId>
    <version>4.2.0</version>
    <configuration>

        <!-- Required -->
        <higsonUrl>http://localhost:8282/higson</higsonUrl>
        <higsonSnapshotDir>${basedir}/src/main/higson</higsonSnapshotDir>

        <!-- Authentication: token (recommended) -->
        <higsonToken>${higsonToken}</higsonToken>

        <!-- Authentication: username and password (alternative) -->
        <!-- <higsonUser>${higsonUser}</higsonUser> -->
        <!-- <higsonPassword>${higsonPassword}</higsonPassword> -->

        <!-- Optional: base path for log files (default: ${basedir}/higson-cli) -->
        <!-- Resulting files: higson-cli-pull.log, higson-cli-push.log -->
        <logFilePath>${basedir}/higson-cli.log</logFilePath>

        <!-- Optional: auto-publish session after successful push (default: false) -->
        <autoCommit>false</autoCommit>

        <pullOptions>
            <tags>true</tags>
            <domains>true</domains>
            <profileWithContext>true</profileWithContext>
            <sourceProfileCodes>
                <param>PROFILE_CODE</param>
            </sourceProfileCodes>
            <functions>
                <nameStartsWith>
                    <param>myapp.</param>
                </nameStartsWith>
                <filterByTags>
                </filterByTags>
                <onlyFromActiveSession>false</onlyFromActiveSession>
            </functions>
            <decisionTables>
                <nameStartsWith>
                    <param>myapp.</param>
                </nameStartsWith>
                <filterByTags>
                </filterByTags>
                <onlyFromActiveSession>false</onlyFromActiveSession>
            </decisionTables>
            <!-- Optional: LF | CR | CRLF. Default: no conversion -->
            <eol>CRLF</eol>
            <excludes>
                <exclude>config.json</exclude>
            </excludes>
        </pullOptions>

        <pushOptions>
            <decisionTableConfig>
                <removeNotIncludedInSnapshot>false</removeNotIncludedInSnapshot>
                <forceDelete>false</forceDelete>
                <searchWithinMatrix>false</searchWithinMatrix>
            </decisionTableConfig>
            <functionConfig>
                <removeNotIncludedInSnapshot>false</removeNotIncludedInSnapshot>
                <forceDelete>false</forceDelete>
                <searchWithinMatrix>false</searchWithinMatrix>
            </functionConfig>
            <domainConfig>
                <removeNotIncludedInSnapshot>false</removeNotIncludedInSnapshot>
            </domainConfig>
        </pushOptions>

    </configuration>
</plugin>