This is a reference implementation of Swift Package Registry Service, proposed in SE-0292 and SE-0321.
Features not implemented (and their corresponding section in the specification):
- Authentication (3.2)
- Rate limiting (3.4)
- Error response JSON is represented by
PackageRegistryModels.ProblemDetails
. (3.3) - Server responses, with the exception of
OPTIONS
requests and204
and redirects (3xx
) statuses, includeContent-Type
andContent-Version
headers. (3.5) - Package scope and name are validated using SwiftPM's
PackageModel.PackageIdentity.Scope
(3.6.1) andPackageModel.PackageIdentity.Name
(3.6.2). Case-insensitivity is done through lowercasing strings before comparison. - All
GET
endpoints supportHEAD
requests. (4) - All API paths support
OPTIONS
requests. (4)
curl http://localhost:9229/mona/LinkedList -i
.json
extension in the request URL is supported:
curl http://localhost:9229/mona/LinkedList.json -i
- The server returns HTTP status
404
if the given package has not published any releases. In other words, this API never returns an empty list. - A deleted release will have
problem.status
set to410
. - The
Link
HTTP header includes URLs to:- The latest published release. Specifically, the package release with the most recent
created_at
timestamp in the database. - The source repository URL if it is provided for the most recent release.
- The latest published release. Specifically, the package release with the most recent
- Pagination using the
Link
header is not supported. This implementation always returns all releases in the response.
curl http://localhost:9229/mona/LinkedList/0.0.1 -i
.json
extension in the request URL is supported:
curl http://localhost:9229/mona/LinkedList/0.0.1.json -i
- The server returns HTTP status
410
if the requested package release has been deleted. - The
Link
HTTP header includes URLs to:- The latest published release (specifically, the package release with the most recent
created_at
timestamp in the database) - The next release in logical sequence, if any.
- The previous release in logical sequence, if any.
- The latest published release (specifically, the package release with the most recent
Manifests are extracted from source archive as part of package release publication.
curl http://localhost:9229/mona/LinkedList/0.0.1/Package.swift -i
- The server returns HTTP status
410
if the associated package release has been deleted. - The server sets the
Cache-Control
,Content-Type
,Content-Disposition
,Content-Length
, etc. HTTP headers. Link
header is set only whenswift-version
query parameter is not provided.- If the manifest for
swift-version
is not found, the server responds with HTTP status303
and redirects to the unqualifiedPackage.swift
(i.e., withoutswift-version
).
# -L instructs cURL to follow redirects
curl http://localhost:9229/mona/LinkedList/0.0.1/Package.swift?swift-version=4.2 -iL
curl http://localhost:9229/mona/LinkedList/0.0.1.zip
- The
.zip
extension is required. - The server returns HTTP status
410
if the package release has been deleted. - The server sets the
Accept-Ranges
,Cache-Control
,Content-Type
,Content-Disposition
,Content-Length
,Digest
etc. HTTP headers. - Since this implementation does not support mirrors or alternative download locations, the
Link
header is not set. - Client should use the
Digest
response header to verify the download, but to verify the integrity of the downloaded source archive, usechecksum
value of the associatedsource-archive
resource in theGET /{scope}/{name}/{version}
response.
curl http://localhost:9229/identifiers?url=https://github.com/mona/LinkedList -i
- The server returns
404
if no package identifiers are found forurl
. In other words, this API never returns an empty list.
This API is in proposal stage: SE-0321, API specification update
- Package
scope
andname
are validated according to section 3.6 of the specification. - The source archive being published should be generated using the
package archive-source
command. PackageRegistryModels.PackageReleaseMetadata
is the only metadata model supported by this server implementation.- Refer to the API specification or
PackageRegistryClient
's source code for the request body format. Note the\r
s and the terminating boundary line (i.e.,--boundary--\r\n
). Themetadata
part is required. Send{}
if there is no metadata. - The
PackageRegistryTool
module provides a CLI tool for interacting with a package registry. - The server executes
swift package compute-checksum
to compute the checksum. Manifest(s) are extracted and saved to the database as part of publication. - The server does not take special actions on the
Expect: 100-continue
HTTP header. In other words, the server never returns HTTP status417
even if it doesn't supportExpect
. - For simplicity, only synchronous publication is supported (i.e., the server returns status
201
on successful publication). ThePrefer
HTTP header, if present in the request, is ignored. - A published package release cannot be modified.
- If the package release already exists, the server returns HTTP status
409
.
This endpoint is not defined in the API specification.
curl http://localhost:9229/mona/LinkedList/0.0.1 -XDELETE -i
.zip
extension in the request URL is supported:
curl http://localhost:9229/mona/LinkedList/0.0.1.zip -XDELETE -i
- The server does soft delete. Only the package release's
status
gets updated; no data is actually removed from the database. - The server returns HTTP status
204
upon successful deletion. If the release does not exist, status404
is returned. If the release has already been removed, status410
is returned. - Once deleted, the server does not allow the same package version to be published again.
- Requests to retrieve source archives, manifests, and metadata for a deleted package release would result in HTTP status
410
.
There are primarily three tables in the Postgres database, all populated via the "create package release" API.
Package release information and metadata (e.g., repository_url
, commit_hash
) provided by the publisher:
Column | Value Type | Description |
---|---|---|
scope |
text | Package scope |
name |
text | Package name |
version |
text | Package release version |
repository_url |
text | URL of the package's source repository. Optional. |
commit_hash |
text | Commit hash associated with the release. Optional. |
status |
text | One of: published , deleted |
created_at |
timestamp | Timestamp at which the release was created |
updated_at |
timestamp | Timestamp at which the release was last updated |
Except status
and updated_at
, data in this table do not change.
Package release resources such as source archives:
Column | Value Type | Description |
---|---|---|
scope |
text | Package scope |
name |
text | Package name |
version |
text | Package release version |
checksum |
text | Checksum of the resource computed using the swift package compute-checksum tool |
type |
text | Resource type. Only source-archive is supported. |
bytes |
blob | Resource bytes |
Data in this table cannot be modified via the APIs.
Package release manifest(s) (e.g., Package.swift
):
Column | Value Type | Description |
---|---|---|
scope |
text | Package scope |
name |
text | Package name |
version |
text | Package release version |
swift_version |
text | Swift version in case of version-specific manifest |
filename |
text | Name of the manifest file |
swift_tools_version |
text | Tools version as specified in the manifest |
bytes |
blob | Manifest bytes |
Data in this table cannot be modified via the APIs.
Local deployment requires docker.
To bring up a local instance of package registry service:
docker-compose -f deployment/local/docker-compose.yml up
The server by default runs on http://localhost:9229.
This implementation of package registry service uses Postgres database. To connect to Postgres, install psql
by running
brew install postgresql
. Then:
psql -h localhost -p 5432 -U postgres
Password is postgres
.
To connect to a Postgres database:
psql -h localhost -p 5432 -U postgres -d <DATABASE_NAME>
OR
postgres-# \c <DATABASE_NAME>
docker-compose -f docker/docker-compose.yml -f docker/docker-compose.2004.55.yml run test-registry