Skip to content

Make the environment resolvable, and run the tests in CI - #25

Open
baggepinnen wants to merge 2 commits into
mainfrom
env/resolvable-deps
Open

Make the environment resolvable, and run the tests in CI#25
baggepinnen wants to merge 2 commits into
mainfrom
env/resolvable-deps

Conversation

@baggepinnen

Copy link
Copy Markdown
Collaborator

Makes both environments resolvable from a bare clone, and adds a CI workflow that runs the test suite.

Pkg.resolve has never worked here

acados_jll and tera_renderer_jll are dependencies of MPCComponents, which this package depends on, but they were listed here only under [extras]. A [sources] entry binds only for a package the active project itself depends on, so the resolver had no version to place for them:

ERROR: Unsatisfiable requirements detected for package acados_jll [49ddb18e]:
 acados_jll [49ddb18e] has no known versions!
 └─restricted to versions 0.6 by MPCComponents [aba2bcdf] — no versions left

That is why the manifests are checked in and why the last two dependency updates had to edit them in place rather than resolve.

LinearMPC was in the same position and failed less visibly. It is registered, so instead of erroring the resolver quietly took the release in place of the feat/disturbance-cross-term fork that MPCComponents needs for Sd. I hit exactly this while testing the fix: with only the two JLLs moved, a from-scratch resolve produced LinearMPC v0.10.0 with no repo-rev.

All three move to [deps] with compat bounds. Nothing here calls them; being a declared dependency is simply what makes the source bind.

MultibodyComponents no longer comes from a local checkout

The registered 0.2.4 resolves against this stack, so the ../MultibodyComponents path source is gone and the compat bound moves to 0.2.4. The README's claim that "the registered release does not resolve against these pins" was true when written and is not any more.

This is also what makes CI possible at all — a runner has no sibling checkout to point a path source at.

After both changes, Pkg.resolve() succeeds in the package and test environments from nothing but the registries and the remaining sources, and every fork binds as intended:

[b5590941] DiscreteComponents v0.4.0
[82e1c212] LinearMPC v0.10.0 `https://github.com/baggepinnen/LinearMPC.jl.git#feat/disturbance-cross-term`
[aba2bcdf] MPCComponents v0.1.0 `https://github.com/JuliaComputing/MPCComponents.jl#main`
[01883e52] MultibodyComponents v0.2.4
[49ddb18e] acados_jll v0.6.0+0 `https://github.com/baggepinnen/acados_jll.jl#main`
[73a839a6] tera_renderer_jll v0.2.1+0 `https://github.com/baggepinnen/tera_renderer_jll.jl#main`

Both manifests are re-resolved from scratch rather than edited. They stay checked in, so an instantiate still reproduces the exact stack the tests ran against.

CI

.github/workflows/CI.yml follows MPCComponents': Julia 1.12 on the self-hosted runner, JuliaComputing/set-up-private-juliahub-registries, then julia-buildpkg and julia-runtest, on pushes to main, tags, and pull requests, with the same concurrency group. JULIA_PKG_USE_CLI_GIT is set for the same reason it is set there: the unregistered packages are cloned over Git and need the credentials the registry step installs. No Documentation workflow, since this repository has no docs/.

GLMakie leaves the test dependencies. Its only use is inside an if false block that renders the multibody model; it is never loaded, and it cannot precompile without a display — it fails here with during initialization of module GLFW — so on a headless runner it would fail the test environment for a code path that never runs. Add it back locally to use that block. Say the word if you would rather keep it and let the runner deal with it.

Verification

julia --project=test test/runtests.jl against the fully re-resolved environment:

testset result
codegen 3108 passed
MPC program 217 passed
MPC multirate program 13 passed
MPC multirate model 7 passed

No failures. The workflow itself only proves out once it runs on this PR.

Also fixes a typo I introduced in #23: the simulation-only paragraph read "[sources] names branch / a branch build of LinearMPC".

🤖 Generated with Claude Code

https://claude.ai/code/session_01Sgq4SoUgK37T6grZRYE2FS

baggepinnen and others added 2 commits September 9, 2026 11:26
`Pkg.resolve` has never worked in this project. `acados_jll` and
`tera_renderer_jll` are dependencies of MPCComponents, which this package depends
on, but they were listed here only under `[extras]`, and a `[sources]` entry binds
only for a package the active project itself depends on. The resolver therefore
had no version to place for them and failed with

    ERROR: Unsatisfiable requirements detected for package acados_jll [49ddb18e]:
     acados_jll [49ddb18e] has no known versions!

LinearMPC was in the same position but failed less visibly: it is registered, so a
resolve quietly took the release in place of the fork carrying the disturbance
cross term, which MPCComponents needs. All three move to `[deps]`, with compat
bounds, even though nothing here calls them; that is what makes the sources bind.

MultibodyComponents no longer comes from a local checkout. The registered 0.2.4
resolves against this stack, so the `../MultibodyComponents` path source is gone
and neither environment needs anything beside the registries and the remaining
sources. That is also what makes CI possible: a runner has no sibling checkout.

The CI workflow follows MPCComponents': Julia 1.12 on the self-hosted runner,
the private-registry setup step, then buildpkg and runtest. `JULIA_PKG_USE_CLI_GIT`
is set for the same reason it is there -- the unregistered packages are cloned over
Git and need the credentials the registry step installs.

GLMakie leaves the test dependencies. Its only use is inside an `if false` block
that renders the multibody model, it is not otherwise loaded, and it cannot
precompile without a display, so on a headless runner it would fail the test
environment for a code path that never runs. Add it back locally to use that block.

Both manifests are re-resolved from scratch rather than edited. test/runtests.jl
against the result: 3108 codegen, 217 MPC program, 13 MPC multirate program, 7 MPC
multirate model, all passing, none failed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sgq4SoUgK37T6grZRYE2FS
The job queued indefinitely and never started. This repository is public, and
the organization's `Default` runner group has `allows_public_repositories:
false`, so a public repository cannot route to it at all. Public repositories
are served by a separate `public` runner group, and by deliberate design no
scale set in it advertises the bare `self-hosted` label -- that keeps those
runners off the radar of workflows that have not opted in -- so
`runs-on: self-hosted` matches nothing and the job waits forever rather than
failing.

The tiers that have to be named are `self-hosted-2vcpu-4gb-public`,
`self-hosted-4vcpu-8gb-public`, `self-hosted-8vcpu-16gb-public` and
`self-hosted-8vcpu-32gb-public`. This suite compiles the multibody models and
builds acados, so it takes the heavy-compute tier. JuliaComputing/Multibody.jl,
also public, targets the same one for the same reason.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sgq4SoUgK37T6grZRYE2FS
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.

1 participant