What are the best practices for using incompatible downstream packages in package development?

When developing a package, you may want to use its downstream packages for testing and documentation.
However, its downstream packages may not officially support the development version because the development version has not yet been released. This means that you may not be able to install them, even though they are potentially compatible.
Special handling seems to be done for the test project of a package under development, but no other projects can deviate from the constraints of [compat].

Consider a specific example.

Colors.jl v0.13.0-dev
ImageCore.jl v0.10.2 with [compat] Colors = "0.12"
WebP.jl v0.1.2 with [compat] ImageCore = "0.10"

Julia’s excellent package management system prevents accidental use of WebP.jl incompatible with the development version of Colors.jl.

How do we use it intentionally?

2 Likes

The following is my tentative measure. There should be better ways. Also, the best practices should be documented.

using Pkg
dependents = ["ImageCore"] # direct
idependents = ["WebP"] # indirect
devdir = get(ENV, "JULIA_PKG_DEVDIR", nothing) # backup
workdir = joinpath(@__DIR__, "work") # working directory
ENV["JULIA_PKG_DEVDIR"] = workdir
Pkg.activate(workdir)
Pkg.develop(dependents, preserve=PRESERVE_DIRECT)
ENV["JULIA_PKG_DEVDIR"] = devdir # restore
for dep in dependents
    Pkg.activate(joinpath(workdir, dep))
    Pkg.compat("Colors", "< 1")
end
Pkg.activate(@__DIR__) # this project
pkgspecs = [PackageSpec(path=joinpath(workdir, dep)) for dep in dependents]
Pkg.develop(pkgspecs, preserve=PRESERVE_DIRECT)
Pkg.add(idependents)

Another approach is to disguise the package version.
That has already been done.

I am fine with running this in a sandbox like CI, but I am not comfortable with running this locally.

Yet another approach would be to serialize the (intermediate) output of the development version and deserialize it in the project with the stable version.
This idea is not versatile, but I believe it is valuable in specific use cases.
cf. Support for cross-environment (de-)serialization of records and offline analysis · Issue #385 · timholy/SnoopCompile.jl · GitHub