Description
Is it reproducible with SwiftPM command-line tools: swift build
, swift test
, swift package
etc?
- Confirmed reproduction steps with SwiftPM CLI. The description text must include reproduction steps with either of command-line SwiftPM commands,
swift build
,swift test
,swift package
etc.
Description
In the specification for the Swift Package Registry Service, the specification for the GET /{scope}/{name}
endpoint says:
A server MAY paginate results by responding with a Link header field that includes any of the following relations:
and provides these examples of a Link
header:
Link: <https://packages.example.com/mona/HashMap/5.0.3>; rel="latest-version",
<https://packages.example.com/mona/HashMap?page=1>; rel="first",
<https://packages.example.com/mona/HashMap?page=2>; rel="previous",
<https://packages.example.com/mona/HashMap?page=4>; rel="next",
<https://packages.example.com/mona/HashMap?page=10>; rel="last"
However, it does not appear that the SPM Package Registry client implementation supports pagination for the GET /{scope}/{name}
endpoint.
This is a burden on Swift Package Registry Service (SPRS) implementations. For example, if you were implementing an SPRS service which proxied the Github API, you would most likely use this Github API endpoint to implement the GET /{scope}/{name}
.
Take an example of implementing GET /{scope}/{name}
for swift-syntax.
- You get the request for
GET /swiftlang/swift-syntax
from SPM to your SPRS - You proxy this request to the Github API:
GET https://api.github.com/repos/swiftlang/swift-syntax/tags
- This response uses the default value of
per_page
which is 30, and responds with the first 30 tags. Here is theLink
header in that response:
Link: <https://api.github.com/repositories/143079594/tags?per_page=30&page=2>; rel="next", <https://api.github.com/repositories/143079594/tags?per_page=30&page=47>; rel="last"
This means there are 47 pages of tags for swift-syntax
. So since the SPM client does not support pagination, then you had to make 47 requests to the GIthub API to fetch all of the tags before you can produce a response for the SPM client.
You could always use a per_page
of 100 (which is the maximum), but that only reduces the number of requests you have to make to 14.
It would be much better if the SPRS could respond with its own Link
header to the GET /{scope}/{name}
response and the SPM client would respect that and make multiple GET /{scope}/{name}
calls in order to fetch all of the package releases (tags).
When you request GET https://api.github.com/repos/swiftlang/swift-syntax/tags
That endpoint has a maximum per_page
of 100meaning that for repositories with a LOT of tags (like swift-syntax), then your implementation would have to make
Expected behavior
I would expect the SPM Package Registry client to respect the Link
header with next
, last
attributes and make multiple requests to the GET /{scope}/{name}
endpoint in order to fetch all of the tags.
Actual behavior
The SPM Package Registry client makes ONE request to GET /{scope}/{name}
. If the expected tag is not in that first page of tags, then package resolution fails.
Steps to reproduce
- Clone https://github.com/hollyoops/swiftPM-registry-service
npm install
set GITHUB_ACCESS_TOKEN="Your github token" && npm start
swift package-registry set --global http://127.0.0.1:3001
- Create a
Package.swift
which depends onswiftlang.swift-syntax
with tag600.0.1
(the latest version) - Observe package resolution fail, since it says it can't find the release
600.0.1
Swift Package Manager version/commit hash
6.0.0-dev
Swift & OS version (output of swift --version ; uname -a
)
swift-driver version: 1.115.1 Apple Swift version 6.0.3 (swiftlang-6.0.3.1.10 clang-1600.0.30.1)
Target: arm64-apple-macosx15.0
Darwin ML-H71R34NL7K 24.2.0 Darwin Kernel Version 24.2.0: Fri Dec 6 19:02:41 PST 2024; root:xnu-11215.61.5~2/RELEASE_ARM64_T6030 arm64