Skip to content

Standardise toolchains with .tool-versions and verify builds in CI #143

Description

@adamnfish-gu

The example skeleton projects all use their own approach to setting up their language toolchains. Many use brew, which will only work on a Mac, but there are other approaches including assuming the tools are already available.

Additionally, lots of the projects are very out of date, and will no longer build. Ideally we'd know about this automatically ahead of time.

This issue tracks the work to fix that.

See also: #142

Approach

  • Each project declares its toolchain in a .tool-versions file, pinned to the major version (e.g. java 21, sbt 1).
  • script/setup runs the project's own dependency-fetch command, which populates their caches and ensures the language build tools defined in .tool-versions are available.
  • script/test runs a trivial passing testuite in the example skeleton project, which ensures the project builds and runs. These test scripts are now consistent so this can be run from CI.
  • The root README recommends mise for reading those files, but any version manager that understands .tool-versions would work.
  • CI discovers projects by looking for a .tool-versions file. CI also includes a step that fails the build if a project declares a toolchain without also providing the standard script/setup and script/test scripts.

PRs

The platform PR sets up CI and the documentation, all the language specific PRs build on top of it. Projects are independent of each other, but within a project fix must merge before adopt. Where languages include multiple PRs (a fix PR separate to an adopt PR), these have been "stacked" in GitHub.

Platform — the CI workflow and README updates:

Per projectfix makes the project builds and the tests pass ,adopt adds .tool-versions and updates script/setup:

Notes

  • java, rust and swift have no fix PR: their tests already pass on main.
  • typescript-node's fix PR is large even though there are only a few changes. This is because of the Yarn zero-install cache regeneration, which is unavoidable because the committed lockfile is stale.
  • The clojure project was nested one directory deeper than every other skeleton. Its adopt PR unnests it, so that the CI discovery works.

The expected end state (with every project change included) is on integration/verify. That branch is pushed so we can see the whole change at once if that's useful, it shouldn't be merged.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions