Skip to content

Fix Julia 1.10 support and add downgrade CI#8

Merged
ChrisRackauckas merged 4 commits into
SciML:mainfrom
ChrisRackauckas-Claude:fix-julia110-and-add-downgrade
Jun 7, 2026
Merged

Fix Julia 1.10 support and add downgrade CI#8
ChrisRackauckas merged 4 commits into
SciML:mainfrom
ChrisRackauckas-Claude:fix-julia110-and-add-downgrade

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Contributor

Summary

This PR restores Julia 1.10 (LTS) support and adds a downgrade-compatibility CI workflow for the three workspace submodules.

1. Julia 1.10 code fix (DiscreteMeasures)

DiscreteMeasures.jl/src/DiscreteMeasures.jl used the two-argument form allequal(length, x), which only exists on Julia >= 1.11. On Julia 1.10 (the SciML-required LTS) this throws a MethodError, so the package cannot even load/construct a DiscreteMeasure. Replaced with allequal(length.(x)), which is semantically identical (all support points share the same length) and works on 1.10.

Verified on the 1.10 binary: the two-arg form MethodErrors; allequal(length.(x)) returns the same result (true for equal-length / scalar vectors, false otherwise).

2. CanonicalMoments compat floor fix

IntervalArithmetic: "0.16 - 0.20, =0.20.9" -> "0.18 - 0.20, =0.20.9". IntervalArithmetic 0.16-0.17 require RecipesBase <= 0.7 (and pull ConstructionBase down), which is unsatisfiable together with this package's Symbolics floor. 0.18 is the lowest IntervalArithmetic that resolves and passes the suite. The disjoint =0.20.9 range is preserved; no allowed version sits below the verified floor.

DiscreteMeasures and OUQBase floors were already healthy on 1.10 (no compat change needed).

3. Downgrade CI

Added .github/workflows/Downgrade.yml: a matrix over [CanonicalMoments.jl, DiscreteMeasures.jl, OUQBase.jl] calling SciML/.github/.github/workflows/downgrade.yml@v1 with julia-version: "1.10", project: ${{ matrix.project }}, projects: ${{ matrix.project }}, secrets: inherit. Mirrors the existing Tests.yml matrix shape.

Depends on SciML/.github#67 (adds the project input to the reusable downgrade.yml so it can build/test a workspace submodule) + a v1 retag. Until that merges and v1 is retagged, the project: input is ignored by the pinned @v1 reusable workflow.

Local verification (Julia 1.10, isolated depot, compat pinned to floors)

All three submodules pass the downgrade suite at their compat floors on Julia 1.10:

DiscreteMeasures (IntervalArithmetic 0.16.0):
Test Summary:          | Pass  Total
DiscreteMeasure        |    8      8
ProductDiscreteMeasure |   15     15
Expectation            |    3      3
Measure Restrictions   |   19     19
     Testing DiscreteMeasures tests passed

CanonicalMoments (IntervalArithmetic 0.18.0, Symbolics 6.29.2, Reexport 1.2.2):
Test Summary:               | Pass  Total
Orthogonal Polynomial Roots |   11     11
Moment Sequence             |  260    260
     Testing CanonicalMoments tests passed

OUQBase (ModelingToolkit 9.69.0, SciMLBase 2.89.1, Symbolics 6.39.1, JuMP 1.23.6,
         DomainSets 0.7.15, Polynomials 4.0.13, OrderedCollections 1.7.0,
         NaNMath 1.1.3, Reexport 1.2.2):
     Testing Running tests...
Optimization stopped after 101 steps
Best candidate found: [0.376915, 0.851782]
Fitness: 0.198058667
     Testing OUQBase tests passed

Ignore until reviewed by @ChrisRackauckas.

🤖 Generated with Claude Code

ChrisRackauckas and others added 3 commits June 6, 2026 04:53
DiscreteMeasures: replace two-arg `allequal(length, x)` (Julia >= 1.11 only)
with `allequal(length.(x))`, which is semantically identical and works on
Julia 1.10. The two-arg form MethodErrors on 1.10, breaking the LTS.

CanonicalMoments: raise the IntervalArithmetic compat floor 0.16 -> 0.18.
IntervalArithmetic 0.16-0.17 require RecipesBase <= 0.7 / pull ConstructionBase
down, which is unsatisfiable with this package's Symbolics floor; 0.18 is the
lowest version that resolves and passes. Kept the disjoint =0.20.9 range.

Add .github/workflows/Downgrade.yml: matrix over the 3 workspace submodules
(CanonicalMoments.jl, DiscreteMeasures.jl, OUQBase.jl) calling the reusable
SciML downgrade workflow at julia-version 1.10, mirroring Tests.yml.

Downgrade suite run locally at the compat floors on Julia 1.10:
- DiscreteMeasures (IntervalArithmetic 0.16.0): PASS
- CanonicalMoments (IntervalArithmetic 0.18.0, Symbolics 6.29.2): PASS
- OUQBase (ModelingToolkit 9.69.0, SciMLBase 2.89.1, Symbolics 6.39.1,
  JuMP 1.23.6, DomainSets 0.7.15, Polynomials 4.0.13): PASS

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The strict (allow-reresolve: false) downgrade cannot reconcile this
package's floored core deps against the latest-floating transitive SciML
stack. allow-reresolve: true lets Pkg resolve a consistent set while
still enforcing the floor [compat] pins set by julia-downgrade-compat.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The downgrade CI resolves each workspace submodule in isolation via
julia-downgrade-compat, which cannot resolve sibling submodule deps
(DiscreteMeasures, CanonicalMoments) since they are unregistered
path deps -> "unknown package UUID". Declare them via [sources] so the
action removes them for resolution and re-adds them to the manifest as
path deps (the same mechanism SciML tests.yml@v1 relies on).

Submodule floor bumps (verified resolvable + test-passing at floors on
Julia 1.10, deps-mode, allow_reresolve=true):

CanonicalMoments:
- add [sources] DiscreteMeasures = ../DiscreteMeasures.jl
- Polynomials: (none) -> "4"  (0.5.0 lacked AbstractPolynomial export)
- RecurrenceRelationships: (none) -> "0.2"
- add julia/LinearAlgebra/Statistics/DiscreteMeasures floors

OUQBase:
- add [sources] CanonicalMoments + DiscreteMeasures path deps
- SciMLBase: 2.89.1 -> 2.153  (2.89.1 held Optimization to 3.25.1, too
  old for the test stack's OptimizationBBO -> UndefVarError deduce_retcode;
  2.153 lets OptimizationBBO/OptimizationBase/Optimization resolve
  consistently, matching the passing latest-CI set)

Downgrade suite run locally at these floors: PASS
- CanonicalMoments: Orthogonal Polynomial Roots 11/11, Moment Sequence 260/260
- OUQBase: FloodProblem solve pipeline completes (was failing on deduce_retcode)

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ChrisRackauckas-Claude

Copy link
Copy Markdown
Contributor Author

Downgrade CI fix for CanonicalMoments + OUQBase

Root cause (both failures, identical): julia-downgrade-compat resolves each workspace submodule in isolation, and the submodules declared their sibling submodules as plain [deps] with no way to locate them. Since DiscreteMeasures/CanonicalMoments are unregistered local path deps, the action's standalone resolver failed with:

[ Info: Running resolver on CanonicalMoments.jl with --min=@deps
ERROR: LoadError: unknown package UUID: 7766d772-2108-41ee-a4bd-11c51440a39b   # DiscreteMeasures

DiscreteMeasures passes because it has no sibling deps.

Fix: declare sibling submodules via [sources] path entries. The downgrade action (and SciML/.github tests.yml@v1) explicitly handle [sources] path deps — they are removed for registry resolution and re-added to the manifest as path deps. This is the canonical workspace mechanism; the latest-CI (Julia 1.12) tests are unaffected.

Once resolution worked, two genuine floor bugs surfaced and were fixed (lowest working bounds):

CanonicalMoments (deps had no compat at all → floated to ancient versions):

  • Polynomials: none → "4" (resolved 0.5.0 lacked the AbstractPolynomial export the package uses → UndefVarError: AbstractPolynomial not defined)
  • RecurrenceRelationships: none → "0.2"
  • added julia="1.10", LinearAlgebra, Statistics, DiscreteMeasures floors

OUQBase:

  • SciMLBase: 2.89.12.153. The 2.89.1 floor held Optimization down to 3.25.1, but the test stack floated OptimizationBBO to a version calling deduce_retcode that the old Optimization lacked → UndefVarError: deduce_retcode not defined during the FloodProblem solve. Raising the SciMLBase floor lets OptimizationBBO/OptimizationBase/Optimization resolve consistently (matches the passing latest set).

Local downgrade suite (Julia 1.10, deps-mode, allow_reresolve=true): PASS

  • CanonicalMoments — Orthogonal Polynomial Roots 11/11, Moment Sequence 260/260 (Polynomials 4.0.0, RecurrenceRelationships 0.2.0)
  • OUQBase — FloodProblem solve pipeline completes (SciMLBase 2.153.0, OptimizationBBO 0.4.5, OptimizationBase 4.2.0); previously errored on deduce_retcode
  • DiscreteMeasures — already green, unchanged

Downgrade.yml already sets allow-reresolve: true for all three matrix entries (single matrix-templated with: block), so no workflow change was needed there.

Ignore until reviewed by @ChrisRackauckas.

🤖 Generated with Claude Code

Flip the Downgrade.yml caller from allow-reresolve: true to the strict
SciML default (false). With false, julia-downgrade-compat resolves each
workspace submodule's [deps] to their floors with transitive deps at
LATEST, and Pkg.test must instantiate that exact set with NO
reconciliation -- the rigorous downgrade that forces the declared [deps]
floors to be genuinely compatible with the latest transitive ecosystem.

Verified locally on Julia 1.10 (deps-mode, Pkg.test(allow_reresolve=false))
per matrix submodule -- ALL PASS at the existing floors, no floor raises
needed beyond those already in this PR:
- DiscreteMeasures.jl: 45/45 (DiscreteMeasure 8, ProductDiscreteMeasure 15,
  Expectation 3, Measure Restrictions 19)
- CanonicalMoments.jl: Orthogonal Polynomial Roots 11/11, Moment Sequence 260/260
- OUQBase.jl: FloodProblem OptimizationBBO solve pipeline completes
  (best candidate [0.344441, 0.831005], fitness 0.1927), tests passed

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ChrisRackauckas-Claude

Copy link
Copy Markdown
Contributor Author

Switched downgrade to strict allow-reresolve: false

Per @ChrisRackauckas, the Downgrade.yml caller now uses the strict SciML default allow-reresolve: false instead of true. This is the rigorous downgrade: julia-downgrade-compat@v2 (mode deps) resolves each workspace submodule's [deps] to their floors with transitive deps pinned to LATEST, and Pkg.test must instantiate that exact set with no reconciliation.

Local verification (Julia 1.10, deps-mode, Pkg.test(; allow_reresolve=false), per matrix submodule)

Reproduced the exact CI steps locally (ran the action's downgrade.jl resolver against each submodule, then strict test). All three PASS at the existing floors — no additional floor raises were needed beyond those already in this PR.

Submodule Result
DiscreteMeasures.jl PASS — 45/45 (DiscreteMeasure 8, ProductDiscreteMeasure 15, Expectation 3, Measure Restrictions 19)
CanonicalMoments.jl PASS — Orthogonal Polynomial Roots 11/11, Moment Sequence 260/260
OUQBase.jl PASS — FloodProblem OptimizationBBO solve pipeline completes (best candidate [0.344441, 0.831005], fitness 0.1927)

The floors added earlier in this PR (CanonicalMoments: Polynomials = "4", RecurrenceRelationships = "0.2", sibling [sources]; OUQBase: SciMLBase = "2.153", sibling [sources]) are exactly the floors that make the strict floor-direct / latest-transitive set resolve and test-pass, so flipping to false is clean.

Only .github/workflows/Downgrade.yml changed in this commit (allow-reresolve: truefalse).

Ignore until reviewed by @ChrisRackauckas.

🤖 Generated with Claude Code

@ChrisRackauckas ChrisRackauckas marked this pull request as ready for review June 7, 2026 05:47
@ChrisRackauckas ChrisRackauckas merged commit da36182 into SciML:main Jun 7, 2026
8 of 9 checks passed
@ChrisRackauckas-Claude

Copy link
Copy Markdown
Contributor Author

Follow-up: the lib/ monorepo restructure + centralized sublibrary CI uniformization (which was scoped as an extension of this PR) is in #10, since this PR was already merged. All fixes from this PR (Julia 1.10, [sources], verified [compat] floors) are in main and preserved by #10.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants