Skip to content

Refresh dependency graph and modernize toolchain - #125

Open
JustinDSN wants to merge 1 commit into
spotify:mainfrom
JustinDSN:chore/refresh-dependency-graph
Open

JustinDSN wants to merge 1 commit into
spotify:mainfrom
JustinDSN:chore/refresh-dependency-graph

Conversation

@JustinDSN

Copy link
Copy Markdown

What

Unblocks XCMetrics' dependency graph and moves CI and Docker onto a toolchain that can build it.

Fixes #121.

The problem

swift package update on main today doesn't no-op — it fails to resolve, and swift test fails to compile. Both trace to one line:

.package(url: ".../swift-tools-support-core.git", exact: "0.2.7"),

TSC 0.2.7 requires swift-system <1.2.0. swift-nio >= 2.70 requires swift-system >= 1.2.0, and vapor >= 4.100 requires swift-nio >= 2.65. So that single exact: pin has held every Vapor- and NIO-adjacent package frozen at its 2022 version, and multipart-kit 4.5.1's vendored OrderedCollections no longer compiles on current Swift — which is #121.

TSC 0.8.0 declares dependencies: [], having dropped swift-system entirely. Relaxing the pin to from: "0.8.0" is sufficient to free the graph.

Changes

File Change
Package.swift swift-tools-support-core exact: "0.2.7"from: "0.8.0"
Package.resolved Regenerated via swift package update — ~50 packages move
Double+Utils.swift powFoundation.pow; swift-numerics 1.1.1 adds a conflicting Double.pow
ci.yaml macOS-13/Xcode 14.2 → macos-26/Xcode 26.5; swift:5.7swift:6.3; checkout v1 → v4
Dockerfile swift:5.7-focalswift:6.3-noble; drop removed --enable-test-discovery
.dockerignore New — see below

Notable version moves:

swift-tools-support-core  0.2.7   -> 0.8.0     vapor         4.65.2  -> 4.122.1
swift-nio                 2.43.1  -> 2.102.0   swift-crypto  1.1.0   -> 3.15.1
postgres-nio              1.11.0  -> 1.33.1    multipart-kit 4.5.1   -> 4.7.1

multipart-kit 4.5.1 → 4.7.1 is what actually fixes the test-target compile.

Why the toolchain bump is required, not optional

The refreshed graph's manifests need Swift 6.2 at minimum — swift-collections 1.6.0 declares swift-tools-version:6.2, and vapor 4.122.1, swift-nio 2.102.0 and postgres-nio 1.33.1 declare 6.0/6.1. Swift 5.7 cannot parse them. Xcode 26.5 and swift:6.3 keep the "match the linux swift version to the xcode swift version" convention established in #86.

Why .dockerignore

There isn't one today, so COPY . . ships the host's .build directory into the Linux image context — 1.9 GB of macOS artifacts on a typical dev machine. Without it the Docker build is impractical to run locally.

Test plan

  • swift build -c release — passes.
  • TZ=UTC swift test77/77 pass. On main the test target does not compile at all.
  • docker build .passes on swift:6.3-noble (linux/arm64). Resulting image boots and serves its command list; XCMetricsBackend product builds in ~95s inside the container.
  • Running swift test in a non-UTC timezone shows 4 failures in StatisticsControllerTests. That's a pre-existing bug unrelated to this PR: the test compares Date().xcm_truncateTime() (local) against UTC values returned by the controller, so it's off by a day at any negative offset. GitHub runners are UTC, so CI is unaffected. Happy to fix it in a follow-up if you'd like.

Relationship to #124 / #123

Independent — this can land in either order. XCLogParser appears at 0.2.49 in Package.resolved here because the existing from: "0.2.38" floor already permits it; #124 raises the declared floor to match. If #124 lands first this rebases to a one-line conflict; if this lands first, #124 reduces to the Package.swift line alone.

🤖 Generated with Claude Code

XCMetrics cannot be built or tested on current Swift toolchains. `swift test`
fails to compile inside multipart-kit 4.5.1's vendored OrderedCollections
(spotify#121), and `swift package update` does not merely no-op — it fails to
resolve at all.

The cause is a single constraint. `swift-tools-support-core` is pinned
`exact: "0.2.7"`, which requires swift-system <1.2.0, while swift-nio >= 2.70
requires swift-system >= 1.2.0 and vapor >= 4.100 requires swift-nio >= 2.65.
TSC 0.8.0 dropped its swift-system dependency entirely, so relaxing that one
pin unblocks the whole graph.

- Package.swift: swift-tools-support-core `exact: "0.2.7"` -> `from: "0.8.0"`.
- Package.resolved: regenerated. ~50 packages move, notably vapor
  4.65.2 -> 4.122.1, swift-nio 2.43.1 -> 2.102.0, swift-crypto 1.1.0 -> 3.15.1,
  postgres-nio 1.11.0 -> 1.33.1, and multipart-kit 4.5.1 -> 4.7.1 (which is
  what fixes the test-target compile). XCLogParser moves 0.2.38 -> 0.2.49 on
  its own, since the existing `from: "0.2.38"` floor already permits it.
- Double+Utils.swift: qualify `pow` as `Foundation.pow`. swift-numerics 1.1.1
  introduces a `Double.pow` static member that makes the unqualified call
  ambiguous.
- ci.yaml / Dockerfile: the refreshed graph needs Swift 6.2 at minimum
  (swift-collections 1.6.0 declares swift-tools-version:6.2). CI moves from
  macOS-13 / Xcode 14.2 to macos-26 / Xcode 26.5, and the Linux container and
  Docker images from swift:5.7-focal to swift:6.3-noble — keeping the "match
  the linux swift version to the xcode swift version" convention from spotify#86.
  actions/checkout v1 -> v4, since v1's Node runtime no longer runs on
  current runners.
- .dockerignore: added. Without it `COPY . .` ships the host's .build
  directory (1.9 GB of macOS artifacts) into the Linux image context.

Fixes spotify#121.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

Not able to build locally with XCode16.3

1 participant