How does SwiftPM query for package versions from GitHub?

A while back I asked a question about iterating over swift-syntax versions:

My goal was to be able to run an automated test across all version releases of swift-syntax currently supported by a package as an alternative to testing against each release "by hand".

@Matejkob responded with the swift-macro-compatibility-check repo. This ships with a script that runs swift package resolve swift-syntax across a hard-coded list of swift-syntax versions.

This got me thinking… how could an approach like this generalize across any dependency? It seems like I would need a way to fetch release versions at runtime:

When I actually try this code from shell:

curl --http1.1 \
-X GET \
-H "Accept: application/vnd.swift.registry.v1+json" \
https://github.com/swiftlang/swift-syntax

GitHub returns the HTML page of the repo… not the JSON dictionary of releases…

I did a little exploring inside the SPM repo:

Maybe that's a clue?

curl --http1.1 \
-X GET \
-H "Accept: application/vnd.github.v3+json" \
https://github.com/swiftlang/swift-syntax/releases

This returns nothing… just a 406 error.

Is there any more reliable advice for dynamically querying for a list of package releases from GitHub? Are there any more clues I should be looking for inside GitHubPackageMetadataProvider?

Is trying to query for this list of versions before going into swift package resolve not the right way to think about things? Is there another way I can creatively use swift package as a "front end" to query for that list on my behalf?

If there was some way for swift package to return that list to me… I could then iterate through that list and pass each value to swift package resolve… which should unblock an automated test.

Any more advice about this? I was thinking about building this in shell… but I'm open to Python or Swift if those would be easier. Thanks!

Something like this should work:

curl -L \
  -H "Accept: application/vnd.github+json" \
  -H "X-GitHub-Api-Version: 2022-11-28" \
  https://api.github.com/repos/swiftlang/swift-syntax/releases|jq -r '.[].name'|sort

Note though that SwiftPM does not actually operate on GH releases but on git tags. Not every git tag will necessarily have an associated GH release.

1 Like

Ahh… awesome! Thanks!

Hmm… could you please help me understand more what that means? Code like this:

Looks like it is querying for releases and then pulling the tags from that… as opposed to going the other way and trying to pull releases from tags. Was that what you meant?

This code is specific to the package collections feature, it does not reflect how SwiftPM accesses versions during regular package resolution.

1 Like