Skip to content

Swift Package Registry

Avrea runs a Swift package registry that acts as a caching proxy for public Swift packages hosted on GitHub. With the registry enabled, SwiftPM resolves version-pinned dependencies as checksummed archives served from colocated storage instead of running a full git clone per dependency against GitHub. Resolution gets faster and repeat builds stop depending on GitHub availability.

The registry is on by default. It changes how SwiftPM records resolved dependencies (see below); repositories that need to keep git-form Package.resolved pins can turn it off with the Swift Package Registry setting (organization and repository scope) in the console, or via the CLI:

Terminal window
avr settings set cache.swift-registry.enabled false

macOS runners are pre-configured automatically: the registry is set as the default in the SwiftPM configuration and Xcode resolves package dependencies through it. Your workflow needs no changes:

workflow.yml
jobs:
build:
runs-on: avrea-macos-latest
steps:
- uses: actions/checkout@v6
- run: swift build

Package identities map directly to GitHub repositories: the package at github.com/apple/swift-numerics has the registry identity apple.swift-numerics. The first time a version is requested, Avrea fetches the tagged source from GitHub, repacks it into a stable source archive, and caches it. Every later resolution of that version, from any of your jobs, is served from the cache with a checksum that never changes.

Anything the registry cannot serve falls back to git exactly as before: branch- and commit-pinned dependencies, private repositories, and packages that do not resolve by identity. A mixed dependency graph works without configuration.

When a dependency resolves through the registry, Package.resolved records a registry identity and archive checksum for it instead of a git URL and commit. The first run with the registry enabled rewrites those pins. If your workflow diffs or hash-keys Package.resolved, expect a one-time change, and keep the setting consistent across the repository's workflows so pins do not flip back and forth.

Commit Package.resolved and resolve with --force-resolved-versions in CI:

Terminal window
swift package resolve --force-resolved-versions

Like npm ci, this uses exactly the committed pins, skips version exploration, and fails loudly instead of silently re-resolving when the manifest and lockfile disagree. For Xcode projects, the equivalent is xcodebuild -disableAutomaticPackageResolution.

The effect is large on a fresh runner. Resolving vapor's 28-package dependency graph:

SetupResolve time
git, no lockfile23s
Registry, no lockfile11s
git, committed lockfile + --force-resolved-versions12s
Registry, committed lockfile + --force-resolved-versions4s
  • macOS runner with Xcode 26 or later: registry resolution relies on current SwiftPM and Xcode support. Runners with older Xcode versions keep resolving via git even with the setting enabled.
  • Public GitHub dependencies: private packages and non-GitHub hosts resolve via git as before.

The registry is configured automatically when the setting is on, and an existing SwiftPM registry configuration in your job is left untouched. To point at it explicitly:

Terminal window
swift package-registry set --global https://cache.avrea.com:8443/swift