From 9c84ff468d585b0a5718c19a23e9f5b5022b2cff Mon Sep 17 00:00:00 2001 From: Jesse Dowell Date: Tue, 15 Sep 2026 14:25:11 -0600 Subject: [PATCH] feat: embed mirthsync 3.7.0 and expose selective deployment (0.0.5) The plugin embeds the mirthsync CLI as a Maven dependency and calls its mainFunc in-process; 0.0.4 still bundled 3.5.1. Bump the dependency to 3.7.0 in the server and client modules (its dependency list is identical to 3.5.1, so the hand-maintained runtime whitelist still covers the closure) and the plugin to 0.0.5 in all four POMs. Engine compatibility (4.5.2, 4.6.0) is unchanged. Settings panel gains "Deploy only changed channels" (--deploy-changed) and "Also deploy new channels" (--deploy-new), mirrored through preset defaults, the preset serialization key list, snapshot/restore, and properties load/save. "Only changed" clears the other two deploy boxes (mirthsync runs every deploy flag it is given and warns); "new" is enabled only with "changed" and is cleared when it is not. Smoke-tested on OIE 4.6.0: POST /api/mirthsync/execute reports 3.7.0 and the same push --deploy-changed sequence deploys exactly the edited channel; /help lists both flags. --- README.md | 5 +- client/pom.xml | 4 +- .../client/panel/MainSettingsPanel.java | 65 +++++++++++++++++++ pom.xml | 2 +- server/pom.xml | 4 +- shared/pom.xml | 2 +- 6 files changed, 74 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 1debfa4..27b07e1 100644 --- a/README.md +++ b/README.md @@ -36,10 +36,10 @@ External runtime libraries (including mirthsync) are copied to `mirthsync-plugin - **Java 17** (Temurin/Adoptium recommended) - **Maven 3.9+** - **Git** -- Access to a Mirth Connect 4.5.x environment +- Access to a Mirth Connect or Open Integration Engine 4.5.2 or 4.6.0 environment (the exact versions listed in `mirth.plugin.compatible_versions` in `pom.xml`) - Optional: custom signing certificate/keystore (default self-signed cert lives in `certificate/keystore.jks`; password is `storepass` and alias `selfsigned`) -The plugin depends on [`com.saga-it:mirthsync`](https://clojars.org/com.saga-it/mirthsync), which is published on [Clojars](https://clojars.org) and resolved automatically during the Maven build. +The plugin depends on [`com.saga-it:mirthsync`](https://clojars.org/com.saga-it/mirthsync), which is published on [Clojars](https://clojars.org) and resolved automatically during the Maven build. The embedded CLI version is pinned in `server/pom.xml` and `client/pom.xml` (currently **3.7.0**); bump both together, and publish that mirthsync release to Clojars first. --- @@ -94,6 +94,7 @@ From **Settings → MirthSync** inside the Administrator UI: - **Flags & Toggles** - Includes mirthsync options like `--force`, `--include-configuration-map`, `--git-init`, `--delete-orphaned`, etc. + - Deploy after push: “Deploy channels after push” (`--deploy`), “Deploy all together” (`--deploy-all`), “Deploy only changed channels” (`--deploy-changed`, mirthsync 3.7.0+) and, with it, “Also deploy new channels” (`--deploy-new`). - “Allow interactive prompts” is currently disabled with a tooltip (“Currently unsupported”). - **Git Metadata & Commands** diff --git a/client/pom.xml b/client/pom.xml index a07058e..f0c9755 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -24,7 +24,7 @@ com.saga-it mirthsync-plugin - 0.0.4 + 0.0.5 client @@ -51,7 +51,7 @@ com.saga-it mirthsync - 3.5.1 + 3.7.0 diff --git a/client/src/main/java/com/saga_it/mirthsync_plugin/client/panel/MainSettingsPanel.java b/client/src/main/java/com/saga_it/mirthsync_plugin/client/panel/MainSettingsPanel.java index 62da436..129f9bb 100644 --- a/client/src/main/java/com/saga_it/mirthsync_plugin/client/panel/MainSettingsPanel.java +++ b/client/src/main/java/com/saga_it/mirthsync_plugin/client/panel/MainSettingsPanel.java @@ -37,6 +37,7 @@ import javax.swing.text.StyledDocument; import javax.swing.text.JTextComponent; import java.awt.*; +import java.awt.event.ItemEvent; import java.io.File; import java.io.PrintWriter; import java.io.StringWriter; @@ -81,6 +82,8 @@ public class MainSettingsPanel extends AbstractSettingsPanel { private MirthCheckBox skipDisabledCheckbox; private MirthCheckBox deployCheckbox; private MirthCheckBox deployAllCheckbox; + private MirthCheckBox deployChangedCheckbox; + private MirthCheckBox deployNewCheckbox; private MirthCheckBox interactiveCheckbox; private MirthCheckBox autoCommitCheckbox; private MirthCheckBox gitInitCheckbox; @@ -119,6 +122,8 @@ public class MainSettingsPanel extends AbstractSettingsPanel { Keys.SKIP_DISABLED, Keys.DEPLOY, Keys.DEPLOY_ALL, + Keys.DEPLOY_CHANGED, + Keys.DEPLOY_NEW, Keys.INTERACTIVE, Keys.AUTO_COMMIT, Keys.GIT_INIT, @@ -300,6 +305,10 @@ private JPanel buildOptionsPanel() { skipDisabledCheckbox = createCheckBox("Skip disabled channels"); deployCheckbox = createCheckBox("Deploy channels after push"); deployAllCheckbox = createCheckBox("Deploy all together"); + deployChangedCheckbox = createCheckBox("Deploy only changed channels"); + deployChangedCheckbox.setToolTipText("After the push, deploy only channels the server reports as changed (--deploy-changed). Clears the other deploy options."); + deployNewCheckbox = createCheckBox("Also deploy new channels"); + deployNewCheckbox.setToolTipText("With \"Deploy only changed channels\": also deploy pushed channels that are not currently deployed (--deploy-new)."); interactiveCheckbox = createCheckBox("Allow interactive prompts"); autoCommitCheckbox = createCheckBox("Auto commit after operations"); gitInitCheckbox = createCheckBox("Initialise git repository if missing"); @@ -309,6 +318,30 @@ private JPanel buildOptionsPanel() { registerCheckboxListener(skipDisabledCheckbox); registerCheckboxListener(deployCheckbox); registerCheckboxListener(deployAllCheckbox); + registerCheckboxListener(deployChangedCheckbox); + registerCheckboxListener(deployNewCheckbox); + // "Only changed" cannot be honoured alongside the other two deploy + // modes (mirthsync runs both and warns), so ticking one side clears + // the other. ItemListeners also fire on programmatic setSelected, so + // preset restore and properties load stay consistent without extra calls. + deployChangedCheckbox.addItemListener(e -> { + if (e.getStateChange() == ItemEvent.SELECTED) { + deployCheckbox.setSelected(false); + deployAllCheckbox.setSelected(false); + } + syncDeployNewEnabled(); + }); + deployCheckbox.addItemListener(e -> { + if (e.getStateChange() == ItemEvent.SELECTED) { + deployChangedCheckbox.setSelected(false); + } + }); + deployAllCheckbox.addItemListener(e -> { + if (e.getStateChange() == ItemEvent.SELECTED) { + deployChangedCheckbox.setSelected(false); + } + }); + syncDeployNewEnabled(); registerCheckboxListener(interactiveCheckbox); registerCheckboxListener(autoCommitCheckbox); registerCheckboxListener(gitInitCheckbox); @@ -330,6 +363,9 @@ private JPanel buildOptionsPanel() { panel.add(deployAllCheckbox, "growx"); panel.add(interactivePanel, "growx, wrap"); + panel.add(deployChangedCheckbox, "growx"); + panel.add(deployNewCheckbox, "growx, wrap"); + panel.add(autoCommitCheckbox, "growx"); panel.add(gitInitCheckbox, "growx, wrap"); @@ -594,6 +630,19 @@ private void initDefaultPresets() { defaultPresets.put("Git: diff --cached (client)", gitDiffStagedClient); } + /** + * --deploy-new only means something with --deploy-changed (mirthsync warns + * and ignores it otherwise). Clearing it when disabled keeps what is + * persisted equal to what the panel shows. + */ + private void syncDeployNewEnabled() { + boolean enabled = deployChangedCheckbox.isSelected(); + deployNewCheckbox.setEnabled(enabled); + if (!enabled) { + deployNewCheckbox.setSelected(false); + } + } + private Map createEmptyPreset() { Map preset = new LinkedHashMap<>(); preset.put(Keys.SERVER_URL, ""); @@ -609,6 +658,8 @@ private Map createEmptyPreset() { preset.put(Keys.SKIP_DISABLED, Boolean.FALSE.toString()); preset.put(Keys.DEPLOY, Boolean.FALSE.toString()); preset.put(Keys.DEPLOY_ALL, Boolean.FALSE.toString()); + preset.put(Keys.DEPLOY_CHANGED, Boolean.FALSE.toString()); + preset.put(Keys.DEPLOY_NEW, Boolean.FALSE.toString()); preset.put(Keys.INTERACTIVE, Boolean.FALSE.toString()); preset.put(Keys.AUTO_COMMIT, Boolean.FALSE.toString()); preset.put(Keys.GIT_INIT, Boolean.FALSE.toString()); @@ -893,6 +944,8 @@ private Map snapshotCurrentSettings() { snapshot.put(Keys.SKIP_DISABLED, Boolean.toString(skipDisabledCheckbox.isSelected())); snapshot.put(Keys.DEPLOY, Boolean.toString(deployCheckbox.isSelected())); snapshot.put(Keys.DEPLOY_ALL, Boolean.toString(deployAllCheckbox.isSelected())); + snapshot.put(Keys.DEPLOY_CHANGED, Boolean.toString(deployChangedCheckbox.isSelected())); + snapshot.put(Keys.DEPLOY_NEW, Boolean.toString(deployNewCheckbox.isSelected())); snapshot.put(Keys.INTERACTIVE, Boolean.toString(interactiveCheckbox.isSelected())); snapshot.put(Keys.AUTO_COMMIT, Boolean.toString(autoCommitCheckbox.isSelected())); snapshot.put(Keys.GIT_INIT, Boolean.toString(gitInitCheckbox.isSelected())); @@ -952,6 +1005,9 @@ private void applyPresetValues(Map preset) { skipDisabledCheckbox.setSelected(Boolean.parseBoolean(preset.getOrDefault(Keys.SKIP_DISABLED, "false"))); deployCheckbox.setSelected(Boolean.parseBoolean(preset.getOrDefault(Keys.DEPLOY, "false"))); deployAllCheckbox.setSelected(Boolean.parseBoolean(preset.getOrDefault(Keys.DEPLOY_ALL, "false"))); + deployChangedCheckbox.setSelected(Boolean.parseBoolean(preset.getOrDefault(Keys.DEPLOY_CHANGED, "false"))); + deployNewCheckbox.setSelected(Boolean.parseBoolean(preset.getOrDefault(Keys.DEPLOY_NEW, "false"))); + syncDeployNewEnabled(); interactiveCheckbox.setSelected(Boolean.parseBoolean(preset.getOrDefault(Keys.INTERACTIVE, "false"))); autoCommitCheckbox.setSelected(Boolean.parseBoolean(preset.getOrDefault(Keys.AUTO_COMMIT, "false"))); gitInitCheckbox.setSelected(Boolean.parseBoolean(preset.getOrDefault(Keys.GIT_INIT, "false"))); @@ -1291,6 +1347,8 @@ private List buildExecutionArguments() { addFlag(args, skipDisabledCheckbox.isSelected(), "--skip-disabled"); addFlag(args, deployCheckbox.isSelected(), "--deploy"); addFlag(args, deployAllCheckbox.isSelected(), "--deploy-all"); + addFlag(args, deployChangedCheckbox.isSelected(), "--deploy-changed"); + addFlag(args, deployChangedCheckbox.isSelected() && deployNewCheckbox.isSelected(), "--deploy-new"); addFlag(args, interactiveCheckbox.isSelected(), "--interactive"); addOption(args, "--commit-message", textOrNull(commitMessageField)); addOption(args, "--git-author", textOrNull(gitAuthorField)); @@ -1796,6 +1854,8 @@ private static final class Keys { static final String SKIP_DISABLED = "skipDisabled"; static final String DEPLOY = "deploy"; static final String DEPLOY_ALL = "deployAll"; + static final String DEPLOY_CHANGED = "deployChanged"; + static final String DEPLOY_NEW = "deployNew"; static final String INTERACTIVE = "interactive"; static final String AUTO_COMMIT = "autoCommit"; static final String GIT_INIT = "gitInit"; @@ -2082,6 +2142,9 @@ public void doRefresh() { skipDisabledCheckbox.setSelected(Boolean.parseBoolean(properties.getProperty(Keys.SKIP_DISABLED, "false"))); deployCheckbox.setSelected(Boolean.parseBoolean(properties.getProperty(Keys.DEPLOY, "false"))); deployAllCheckbox.setSelected(Boolean.parseBoolean(properties.getProperty(Keys.DEPLOY_ALL, "false"))); + deployChangedCheckbox.setSelected(Boolean.parseBoolean(properties.getProperty(Keys.DEPLOY_CHANGED, "false"))); + deployNewCheckbox.setSelected(Boolean.parseBoolean(properties.getProperty(Keys.DEPLOY_NEW, "false"))); + syncDeployNewEnabled(); interactiveCheckbox.setSelected(Boolean.parseBoolean(properties.getProperty(Keys.INTERACTIVE, "false"))); autoCommitCheckbox.setSelected(Boolean.parseBoolean(properties.getProperty(Keys.AUTO_COMMIT, "false"))); gitInitCheckbox.setSelected(Boolean.parseBoolean(properties.getProperty(Keys.GIT_INIT, "false"))); @@ -2133,6 +2196,8 @@ private Properties buildProperties() { properties.setProperty(Keys.SKIP_DISABLED, Boolean.toString(skipDisabledCheckbox.isSelected())); properties.setProperty(Keys.DEPLOY, Boolean.toString(deployCheckbox.isSelected())); properties.setProperty(Keys.DEPLOY_ALL, Boolean.toString(deployAllCheckbox.isSelected())); + properties.setProperty(Keys.DEPLOY_CHANGED, Boolean.toString(deployChangedCheckbox.isSelected())); + properties.setProperty(Keys.DEPLOY_NEW, Boolean.toString(deployNewCheckbox.isSelected())); properties.setProperty(Keys.INTERACTIVE, Boolean.toString(interactiveCheckbox.isSelected())); properties.setProperty(Keys.AUTO_COMMIT, Boolean.toString(autoCommitCheckbox.isSelected())); properties.setProperty(Keys.GIT_INIT, Boolean.toString(gitInitCheckbox.isSelected())); diff --git a/pom.xml b/pom.xml index 76ed24b..84889fc 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,7 @@ com.saga-it mirthsync-plugin - 0.0.4 + 0.0.5 pom https://saga-it.com/products/mirthsync-plugin diff --git a/server/pom.xml b/server/pom.xml index 5f4a796..6ad7954 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -24,7 +24,7 @@ com.saga-it mirthsync-plugin - 0.0.4 + 0.0.5 server @@ -232,7 +232,7 @@ com.saga-it mirthsync - 3.5.1 + 3.7.0 diff --git a/shared/pom.xml b/shared/pom.xml index a9bd16e..d4ef351 100644 --- a/shared/pom.xml +++ b/shared/pom.xml @@ -24,7 +24,7 @@ com.saga-it mirthsync-plugin - 0.0.4 + 0.0.5