Written by

Senior Applications Developer at InterSystems Corporation
InterSystems Official Dominic Chui · Jun 1

IPM Version 0.10.7 Release Notes

IPM version 0.10.7 was released on May 29th, 2026. As usual, you can check it out on the GitHub page or through the Community Registry.


Highlighted Features

Utility Scripts iriscli and ipm

IPM is now bundled with two convenience scripts that are runnable from a standard terminal. iriscli launches an interactive IRIS terminal and ipm runs IPM commands directly. These are automatically installed to both ~/.local/bin/ and ~/bin/, so they work inside and outside of containers (Unix/Linux only).

Examples:

  1. Entering the IRIS shell in the "iris" container:
    docker exec -it iris iriscli
  2. Listing installed IPM modules:
    ipm list


 

Structured Test Output Formats

The test and verify commands now offer different structured output formats for results: json, yaml, and toon. These new output formats will also show a summary block before the failing tests.

Use config set TestReportFormat <format> for a persistent default, or -f <format> to override it for a single run. If neither is set, the pre-existing output format will be used. The output can also be redirected to a file using the -output-file <path> flag, with the format inferred from the file extension (.json, .yaml, .toon, or .xml for JUnit). In addition, the -quiet flag has been modified to suppress the build and install noise. The most LLM-friendly output will be with test <module-name> -quiet -format toon. In contrast, the -verbose flag paired with a format option will show every test (passing or failing) in the output.

Examples:

  1. No specified format results in the pre-existing style for failing tests, but adds the test result summary block.

    zpm:USER>test-output-format test -only
    
    [USER|test-output-format]       Test START
    Building dependency graph...Done.
    Use the following URL to view the result:
    http://172.19.0.3:52773/csp/sys/%25UnitTest.Portal.Indices.cls?Index=100&$NAMESPACE=USER
    Some tests FAILED in suites:
      ,(root)
    
    Test Results:
    
    Test Run #100 (USER) .799303s 2026-04-24 17:20:12
    Methods: 18 total, 6 passed, 12 failed
    Assertions: 22 total, 20 passed, 2 failed
    
    FAILED (root):Test.Output.Format.AfterAllReturn: OnAfterAllTests:  ERROR #5001: deliberate OnAfterAllTests return-error
    FAILED (root):Test.Output.Format.AfterAllThrow: OnAfterAllTests:  ERROR #5001: deliberate OnAfterAllTests throw
    FAILED (root):TestMethodBodyPasses: OnAfterOneTest:  ERROR #5001: deliberate OnAfterOneTest return-error for TestMethodBodyPasses
    FAILED (root):TestMethodBodyPasses: OnAfterOneTest:  ERROR #5001: deliberate OnAfterOneTest throw for TestMethodBodyPasses
    FAILED (root):Test.Output.Format.BeforeAllReturn: OnBeforeAllTests:  ERROR #5001: deliberate OnBeforeAllTests return-error
    FAILED (root):Test.Output.Format.BeforeAllThrow: OnBeforeAllTests:  ERROR #5001: deliberate OnBeforeAllTests throw
    FAILED (root):TestFirstMethod: OnBeforeOneTest:  ERROR #5001: deliberate OnBeforeOneTest return-error for TestFirstMethod
    FAILED (root):TestSecondMethod: OnBeforeOneTest:  ERROR #5001: deliberate OnBeforeOneTest return-error for TestSecondMethod
    FAILED (root):TestFirstMethod: OnBeforeOneTest:  ERROR #5001: deliberate OnBeforeOneTest throw for TestFirstMethod
    FAILED (root):TestSecondMethod: OnBeforeOneTest:  ERROR #5001: deliberate OnBeforeOneTest throw for TestSecondMethod
    FAILED (root):TestFailingAssertions: AssertTrue - deliberate failure: zero is not true
    FAILED (root):TestFailingAssertions: AssertEquals - deliberate mismatch
    FAILED (root):TestThrowsFromBody: TestThrowsFromBody:  ERROR #5001: deliberate throw from test body
    [test-output-format]    Test FAILURE
    ERROR! 13 failure(s).
  2. Specifying a test format results in both the test result summary block and the failing tests in the specified format.

    zpm:USER>test-output-format test -only -f toon
    
    [USER|test-output-format]       Test START
    Building dependency graph...Done.
    Use the following URL to view the result:
    http://172.19.0.3:52773/csp/sys/%25UnitTest.Portal.Indices.cls?Index=101&$NAMESPACE=USER
    Some tests FAILED in suites:
      ,(root)
    
    Test Results:
    
    summary:
      id: 101  namespace: USER  duration: .834048s  testDateTime: 2026-04-24 17:20:33
      methods[18]: 6 passed, 12 failed
      assertions[22]: 20 passed, 2 failed
    
    failures[13]{suiteName,testcaseName,methodName,status,assertAction,assertCounter,assertDescription,assertLocation}:
      (root),Test.Output.Format.AfterAllReturn,Test.Output.Format.AfterAllReturn,failed,OnBeforeAllTests,0,"OnAfterAllTests:  ERROR #5001: deliberate OnAfterAllTests return-error",""
      (root),Test.Output.Format.AfterAllThrow,Test.Output.Format.AfterAllThrow,failed,OnBeforeAllTests,0,"OnAfterAllTests:  ERROR #5001: deliberate OnAfterAllTests throw",""
      (root),Test.Output.Format.AfterOneReturn,TestMethodBodyPasses,failed,error,0,"OnAfterOneTest:  ERROR #5001: deliberate OnAfterOneTest return-error for TestMethodBodyPasses",""
      (root),Test.Output.Format.AfterOneThrow,TestMethodBodyPasses,failed,error,0,"OnAfterOneTest:  ERROR #5001: deliberate OnAfterOneTest throw for TestMethodBodyPasses",""
      (root),Test.Output.Format.BeforeAllReturn,Test.Output.Format.BeforeAllReturn,failed,OnBeforeAllTests,0,"OnBeforeAllTests:  ERROR #5001: deliberate OnBeforeAllTests return-error",""
      (root),Test.Output.Format.BeforeAllThrow,Test.Output.Format.BeforeAllThrow,failed,OnBeforeAllTests,0,"OnBeforeAllTests:  ERROR #5001: deliberate OnBeforeAllTests throw",""
      (root),Test.Output.Format.BeforeOneReturn,TestFirstMethod,failed,error,0,"OnBeforeOneTest:  ERROR #5001: deliberate OnBeforeOneTest return-error for TestFirstMethod",""
      (root),Test.Output.Format.BeforeOneReturn,TestSecondMethod,failed,error,0,"OnBeforeOneTest:  ERROR #5001: deliberate OnBeforeOneTest return-error for TestSecondMethod",""
      (root),Test.Output.Format.BeforeOneThrow,TestFirstMethod,failed,error,0,"OnBeforeOneTest:  ERROR #5001: deliberate OnBeforeOneTest throw for TestFirstMethod",""
      (root),Test.Output.Format.BeforeOneThrow,TestSecondMethod,failed,error,0,"OnBeforeOneTest:  ERROR #5001: deliberate OnBeforeOneTest throw for TestSecondMethod",""
      (root),Test.Output.Format.MethodAssertFailure,TestFailingAssertions,failed,AssertTrue,2,"deliberate failure: zero is not true","TestFailingAssertions+2^Test.Output.Format.MethodAssertFailure.cls"
      (root),Test.Output.Format.MethodAssertFailure,TestFailingAssertions,failed,AssertEquals,3,"deliberate mismatch","TestFailingAssertions+3^Test.Output.Format.MethodAssertFailure.cls"
      (root),Test.Output.Format.MethodThrowFailure,TestThrowsFromBody,failed,error,0,"TestThrowsFromBody:  ERROR #5001: deliberate throw from test body",""
    
    [test-output-format]    Test FAILURE
    ERROR! 13 failure(s).

 

Configurable Custom Root for load and install

v0.10.4 introduced a standard unpacking directory $System.Util.DataDirectory()/ipm/<packagename>/<version>/ for modules installed using the install command. Now, modules installed from a tarball using the load command will also unpack in the same directory. Directory loads are unaffected and load in-place.

In addition, this module root can now be user-configured using config set ModuleRoot /custom/path/. If /custom/path/ does not exist, the directory chain will be automatically created.

 

Packaging Tests with Modules

Tests can now be packaged with a module by using the -include-tests flag with either the package or publish commands or adding <IncludeTests>1</IncludeTests> in module.xml as an element of <Module>.

 

Sorted list/list-installed Command Output

The list/list-installed command can now be sorted by name, date, or version, either in ascending or descending order, defaulting to name ascending. Note that IPM itself will always appear at the top of the list regardless of sort option.

Examples:

Sort by version:
list -sort -version

Sort by name descending:
list -sort -n-d


Important Bug Fixes

Configuring ORAS repositories for certain OCI registries

Fixed an issue where it was impossible to properly authenticate an IPM ORAS repository for some OCI registries like GitHub Container Registry (GHCR). ORAS repositories in IPM also now show an "Authenticated?" status in the repo -list summary.

To configure a GHCR repo, use this command:
repo -o -n github -url ghcr.io -namespace <gh-username> -username <gh-username> -password <gh-personal-access-token>
Optionally, use -password-stdin instead of -password for security.

 

The info display for namespaces with mapped IPM

Previously, the welcome display (also shown by info) would not show the IPM version when IPM was mapped into a namespace. It now shows both the version and the namespace it is mapped from.


 

IPM self-uninstallation

IPM now gracefully uninstalls itself without throwing errors.

 

Smarter dependency resolution during update

When updating a module (using the load, install or update command), IPM will no longer erroneously use the currently installed versions as limitations for dependency resolution, but will instead consider the post-update versions. This fixes an issue where diamond dependencies could not be updated without uninstalling completely and reinstalling.

Example of diamond dependency topology, where all modules are being updated from 1.0.0 to 2.0.0 simultaneously:

     parent
     /    \
    a      b
     \    /
      base

Full Changelog

Added

  • #408: Modules can now list dependencies without specifying version; will be assumed to be "*"
  • #945: When loading from a tarball, the load command now unpacks into the configured module root (defaults to $System.Util.DataDirectory()/ipm/) under <packagename>/<version>/ instead of a temporary directory, matching the behavior of the install command. Directory loads are unaffected and continue to load in-place.
  • #992: Implement automatic history purge logic
  • #973: Enables CORS and JWT configuration for WebApplications in module.xml
  • #1110: Add iriscli and ipm container utility scripts that are auto-installed to ~/.local/bin/ and ~/bin/ so they work both inside and outside of containers (Unix/Linux only)
  • #1013: Implement recursive placeholder resolution in Default parameters
  • #971: Adds structured test output formats (JSON, YAML, Toon). Use -f <format> for a one-shot override or config set TestReportFormat <format> for a persistent default. Without either, legacy output is shown. Also adds -output-file for writing results to a file (including JUnit XML via .xml extension) and improves -quiet to suppress build noise.
  • #1029: Add support for user-configurable ModuleRoot for IPM module installation
  • #1053: Add file system permissions check before install/load.
  • #870: When running tests for just a single suite or class, will only load and compile the relevant classes instead of all the tests
  • #843: Optionally include tests when packaging using either the -include-tests flag or <IncludeTests>1</IncludeTests> in module.xml
  • #1079: Add semantic sorting and shortcuts to list-installed
  • #1152: Adds information about scoped dependencies in the output array of BuildDependencyGraph()

Fixed

  • #1175: Fix issue parsing version for packages with both deployed and non-deployed versions
  • #964: Fix poor error handling on some install failures due to incorrect error message variable in embedded SQL
  • #1130: Fix issue with ORAS repositories pointing to some OCI registries that require authentication (e.g. ghcr.io) not accepting credentials properly. repo -list now shows an Authenticated? status for ORAS repos with credentials configured.
  • #1001: The unmap and enable commands will now only activate CPF merge once after all namespaces have been configured instead of after every namespace
  • #1052: In a namespace with mapped IPM, the info command works again and the intro message displays the IPM version and where it's mapped from
  • #1102: %IPM.Storage.QualifiedModuleInfo:%New() will now copy over version properties when passed in a resolvedReference
  • #1112: Packaging a module with a globals resource now respects SourcesRoot, placing the exported file at the correct path in the tarball
  • #1057: Fix IPM not cleaning up after itself on self-uninstall
  • #1122: Packaging should recognize resources in dependency modules set to deploy
  • #1119: The update command should check version requirements using post-update values instead of what's currently installed
  • #1097: The Test resource processor now supports nested tests
  • #1116: Fix behavior inconsistencies between install and uninstall for package name casing.
  • #1114: Fix issue with SystemRequirements being confused by multiple namespaces with different version of IPM installed
  • #1128: Fixed an issue where an update can fail if a resource is moved from one module to another
  • #430: Updating shared transitive dependencies with lock-step version requirements now works instead of erroring out
  • #1179: IPM will no longer erroneously complain about Python 3.13+ on compatible versions of IRIS. The lower bound check (3.10+) remains, but the upper bound is left to the user. There is a compatibility matrix in the README.

Security

  • urllib3 Python wheel updated to 2.7.0
  • requests Python wheel updated to 2.33.0
  • #1138: Warn when using -password instead of -password-stdin.