🔥 엔드포인트

3122자
34분

서버는 다음 엔드포인트에 응답해야 합니다:

링크HTTP 메서드경로설명
[1]GET/{scope}/{name}패키지 릴리스 목록
[2]GET/{scope}/{name}/{version}패키지 릴리스 메타데이터 가져오기
[3]GET/{scope}/{name}/{version}/Package.swift{?swift-version}패키지 릴리스 매니페스트 가져오기
[4]GET/{scope}/{name}/{version}.zip패키지 릴리스 소스 아카이브 다운로드
[5]GET/identifiers{?url}URL에 등록된 패키지 식별자 조회
[6]PUT/{scope}/{name}/{version}패키지 릴리스 생성

서버는 명시된 각 엔드포인트에 대한 HEAD 요청에도 응답해야 합니다.

클라이언트는 서버의 허용된 통신 옵션을 확인하기 위해 별표(*)를 사용하여 OPTIONS 요청을 보낼 수 있습니다. 서버는 Link 헤더로 응답할 수 있는데, 이 헤더에는 service-doc 관계 유형의 이 문서에 대한 링크 항목과 service-desc 관계 유형의 OpenAPI 명세에 대한 링크 항목이 포함됩니다.


1. 패키지 릴리스 목록

클라이언트는 /{scope}/{name} 경로에 GET 요청을 보내 특정 패키지의 사용 가능한 릴리스 목록을 가져올 수 있습니다. 클라이언트는 Accept 헤더를 application/vnd.swift.registry.v1+json 값으로 설정해야 하며, 요청된 URL에 .json 확장명을 추가할 수 있습니다.

GET /mona/LinkedList HTTP/1.1
Host: packages.example.com
Accept: application/vnd.swift.registry.v1+json
text

요청된 위치에서 패키지를 찾을 경우 서버는 상태 코드 200 (OK)와 Content-Type 헤더 application/json으로 응답해야 합니다. 그렇지 않으면 서버는 상태 코드 404 (Not Found)로 응답해야 합니다.

서버는 요청된 패키지의 릴리스가 포함된 JSON 문서로 응답해야 합니다.

HTTP/1.1 200 OK
Content-Type: application/json
Content-Version: 1
Content-Length: 508
Link: <https://github.com/mona/LinkedList>; rel="canonical",
      <ssh://git@github.com:mona/LinkedList.git>; rel="alternate",
      <https://packages.example.com/mona/LinkedList/1.1.1>; rel="latest-version",
      <https://github.com/sponsors/mona>; rel="payment"

{
    "releases": {
        "1.1.1": {
            "url": "<https://packages.example.com/mona/LinkedList/1.1.1>"
        },
        "1.1.0": {
            "url": "<https://packages.example.com/mona/LinkedList/1.1.0>",
            "problem": {
                "status": 410,
                "title": "Gone",
                "detail": "this release was removed from the registry"
            }
        },
        "1.0.0": {
            "url": "<https://packages.example.com/mona/LinkedList/1.0.0>"
        }
    }
}
text

응답 본문에는 반드시 최상위 releases 키 아래 중첩된 JSON 객체가 포함되어야 하며, 이 객체의 키는 릴리스 버전이고 값은 다음 필드가 포함된 객체입니다:

타입설명필수 여부
url문자열릴리스 리소스의 위치선택사항
problem객체"문제 세부사항" 객체선택사항

서버는 url 키를 사용하여 릴리스의 URL을 지정할 수 있습니다. 클라이언트는 url 키 값이 제공된 경우 그 값을 사용해 릴리스를 찾아야 합니다. 그렇지 않은 경우, 클라이언트는 원본 호스트에서 URI 템플릿 /{scope}/{name}/{version}을 확장하여 릴리스를 찾아야 합니다.

서버는 problem 키와 연결된 모든 릴리스를 패키지 해석 목적으로 사용할 수 없는 것으로 간주해야 합니다.

서버는 존재하는 경우 latest-version 관계를 가진 Link 헤더 필드를 사용하여 최신 우선순위의 공개된 패키지 릴리스에 대한 링크로 응답해야 합니다.

서버는 가장 높은 우선순위 버전부터 시작하여 우선순위 순서대로 릴리스를 나열해야 합니다. 그러나 클라이언트는 응답에서 특정 버전 순서를 가정해서는 안 됩니다.

서버는 패키지의 소스 저장소 위치를 지정하는 canonical 관계 유형의 Link 항목을 포함할 수 있습니다.

서버는 다른 소스 저장소 위치에 대해 alternate 관계 유형의 Link 항목을 하나 이상 포함할 수 있습니다.

서버는 다음 관계 중 하나를 포함하는 Link 헤더 필드를 사용하여 결과를 페이지네이션할 수 있습니다:

이름설명
next결과의 바로 다음 페이지
last결과의 마지막 페이지
first결과의 첫 페이지
prev결과의 바로 이전 페이지

예를 들어, 페이지네이션된 결과의 세 번째 페이지에 대한 응답의 Link 헤더 필드는 다음과 같습니다:

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"
text

서버는 패지지 매니저 후원을 위한 payment 관계와 같은 추가 Link 항목으로 응답할 수 있습니다.

2. 패키지 릴리스 정보 가져오기

클라이언트는 /{scope}/{name}/{version} 경로에 GET 요청을 보내 릴리스 정보를 가져올 수 있습니다. 클라이언트는 Accept 헤더 값을 application/vnd.swift.registry.v1+json으로 설정해야 하며, 요청된 URL에 .json 확장명을 추가할 수 있습니다.

GET /mona/LinkedList/1.1.1 HTTP/1.1
Host: packages.example.com
Accept: application/vnd.swift.registry.v1+json
text

요청된 위치에서 릴리스를 찾을 경우 서버는 상태 코드 200 (OK)와 Content-Type 헤더 application/json으로 응답해야 합니다. 그렇지 않으면 서버는 상태 코드 404 (Not Found)로 응답해야 합니다.

HTTP/1.1 200 OK
Content-Version: 1
Content-Type: application/json
Content-Length: 720
Link: <https://packages.example.com/mona/LinkedList/1.1.1>; rel="latest-version",
      <https://packages.example.com/mona/LinkedList/1.0.0>; rel="predecessor-version"
{
  "id": "mona.LinkedList",
  "version": "1.1.1",
  "resources": [
    {
      "name": "source-archive",
      "type": "application/zip",
      "checksum": "a2ac54cf25fbc1ad0028f03f0aa4b96833b83bb05a14e510892bb27dea4dc812",
      "signing": {
        "signatureBase64Encoded": "l1TdTeIuGdNsO1FQ0ptD64F5nSSOsQ5WzhM6/7KsHRuLHfTsggnyIWr0DxMcBj5F40zfplwntXAgS0ynlqvlFw==",
        "signatureFormat": "cms-1.0.0"
      }
    }
  ],
  "metadata": { ... },
  "publishedAt": "2023-02-16T04:00:00.000Z"
}
text

응답 본문에는 다음 필드가 포함된 JSON 객체가 있어야 합니다:

타입설명필수 여부
id문자열네임스페이스가 지정된 패키지 식별자
version문자열패키지 릴리스 버전
resources배열릴리스에 사용 가능한 리소스
metadata객체릴리스에 대한 추가 정보
publishedAt문자열레지스트리에 기록된 대로 패키지 릴리스가 게시된 ISO 8601 형식의 날짜/시간 문자열. metadata의 관련 originalPublicationTime 참조

서버는 다음 항목이 포함된 Link 헤더로 응답해야 합니다:

관계설명
latest-version패키지의 최신 우선순위 공개 릴리스
successor-version존재하는 경우 우선순위로 정렬된 패키지의 다음 공개 릴리스
predecessor-version존재하는 경우 우선순위로 정렬된 패키지의 이전 공개 릴리스

latest-version 관계의 링크는 요청된 릴리스에 해당할 수 있습니다.

2.1. 패키지 릴리스 리소스

resources 배열의 각 요소는 다음 키가 있는 JSON 객체입니다:

타입설명
name문자열리소스 이름
type문자열리소스의 콘텐츠 타입
checksum문자열리소스에 대한 SHA256 다이제스트의 16진수 표현
signing객체서명에 대한 정보. 리소스가 서명된 경우에만 필요

signing JSON 객체에는 다음 키가 포함됩니다:

타입설명
signatureBase64Encoded문자열base64로 인코딩된 리소스 서명
signatureFormat문자열서명 형식 (예: cms-1.0.0)

리소스 객체는 다음과 같은 nametype 값의 조합 중 하나를 가져야 합니다:

이름콘텐츠 타입설명
source-archiveapplication/zip패키지 소스의 아카이브

릴리스는 주어진 nametype 값의 조합을 가진 리소스 객체를 둘 이상 가질 수 없습니다.

2.2. 패키지 릴리스 메타데이터 표준

부록 B"패키지 릴리스 생성" 요청의 일부로 제출되는 패키지 릴리스 메타데이터에 대한 JSON 스키마를 정의합니다. 서버는 스키마를 확장하여 추가 메타데이터를 허용 및/또는 채울 수 있습니다. "패키지 릴리스 정보 가져오기" API 응답의 metadata 키에는 사용자가 제공한 메타데이터와 서버가 채운 메타데이터가 모두 포함됩니다.

3. 패키지 릴리스 매니페스트 가져오기

클라이언트는 /{scope}/{name}/{version}/Package.swift 경로에 GET 요청을 보내 릴리스의 패키지 매니페스트를 가져올 수 있습니다. 클라이언트는 Accept 헤더 값을 application/vnd.swift.registry.v1+swift로 설정해야 합니다.

GET /mona/LinkedList/1.1.1/Package.swift HTTP/1.1
Host: packages.example.com
Accept: application/vnd.swift.registry.v1+swift
text

요청된 위치에서 릴리스를 찾을 경우 서버는 상태 코드 200 (OK)와 Content-Type 헤더 text/x-swift로 응답해야 합니다. 그렇지 않으면 서버는 상태 코드 404 (Not Found)로 응답해야 합니다.

HTTP/1.1 200 OK
Cache-Control: public, immutable
Content-Type: text/x-swift
Content-Disposition: attachment; filename="Package.swift"
Content-Length: 361
Content-Version: 1
Link: <http://packages.example.com/mona/LinkedList/1.1.1/Package.swift?swift-version=4>; rel="alternate"; filename="Package@swift-4.swift"; swift-tools-version="4.0",
      <http://packages.example.com/mona/LinkedList/1.1.1/Package.swift?swift-version=4.2>; rel="alternate"; filename="Package@swift-4.2.swift"; swift-tools-version="4.0"

// swift-tools-version:5.0
import PackageDescription

let package = Package(
    name: "LinkedList",
    products: [
        .library(name: "LinkedList", targets: ["LinkedList"])
    ],
    targets: [
        .target(name: "LinkedList"),
        .testTarget(name: "LinkedListTests", dependencies: ["LinkedList"]),
    ],
    swiftLanguageVersions: [.v4, .v5]
)
text

서버는 매니페스트 크기를 바이트 단위로 설정한 Content-Length 헤더로 응답해야 합니다.

서버는 "Package.swift"와 같이 매니페스트 파일 이름과 동일한 filename 매개변수가 있는 attachment로 설정된 Content-Disposition 헤더로 응답해야 합니다.

서버는 응답 콘텐츠(즉, 매니페스트)가 다른 API 버전에서 변경되지 않아야 하므로 Content-Version 헤더를 생략할 수 있습니다.

클라이언트와 서버는 RFC 7234에 설명된 대로 캐싱을 지원하는 것이 좋습니다.

서버는 릴리스의 소스 아카이브에 있는 각 버전별 패키지 매니페스트 파일에 대해 다음 정규식 패턴과 일치하는 파일 이름을 가진 Link 헤더 필드를 포함해야 합니다:

APackage@swift-(d+)(?:.(d+))?(?:.(d+))?.swiftz
text

각 링크 값은 alternate 관계 유형을 가져야 하며, filename 속성은 버전별 패키지 매니페스트 파일 이름(예: Package@swift-4.swift)으로 설정되어야 하고, swift-tools-version 속성은 패키지 매니페스트 파일에 지정된 Swift 도구 버전(예: // swift-tools-version:4.0으로 시작하는 매니페스트의 경우 4.0)으로 설정되어야 합니다.

3.1. swift-version 쿼리 매개변수

클라이언트는 특정 버전의 Swift에 대한 매니페스트를 요청하기 위해 swift-version 쿼리 매개변수를 지정할 수 있습니다.

GET /mona/LinkedList/1.1.1/Package.swift?swift-version=4.2 HTTP/1.1
Host: packages.example.com
Accept: application/vnd.swift.registry.v1+swift
text

패키지에 Package@swift-{swift-version}.swift라는 이름의 파일이 포함되어 있으면 서버는 상태 코드 200 (OK)와 응답 본문의 해당 파일 내용으로 응답해야 합니다.

HTTP/1.1 200 OK
Cache-Control: public, immutable
Content-Type: text/x-swift
Content-Disposition: attachment; filename="Package@swift-4.2.swift"
Content-Length: 361
Content-Version: 1

// swift-tools-version:4.2
import PackageDescription

let package = Package(
    name: "LinkedList",
    products: [
        .library(name: "LinkedList", targets: ["LinkedList"])
    ],
    targets: [
        .target(name: "LinkedList"),
        .testTarget(name: "LinkedListTests", dependencies: ["LinkedList"]),
    ],
    swiftLanguageVersions: [.v3, .v4]
)
text

그렇지 않으면 서버는 상태 코드 303 (See Other)로 응답하고 정규화되지 않은 Package.swift 리소스로 리디렉션해야 합니다.

HTTP/1.1 303 See Other
Content-Version: 1
Location: <https://packages.example.com/mona/LinkedList/1.1.1/Package.swift>
text

4. 소스 아카이브 다운로드

클라이언트는 /{scope}/{name}/{version}.zip 경로에 GET 요청을 보내 릴리스의 소스 아카이브를 가져올 수 있습니다. 클라이언트는 Accept 헤더 값을 application/vnd.swift.registry.v1+zip으로 설정해야 하며, 반드시 요청된 경로에 .zip 확장명을 추가해야 합니다.

GET /mona/LinkedList/1.1.1.zip HTTP/1.1
Host: packages.example.com
Accept: application/vnd.swift.registry.v1+zip
text

요청된 위치에서 릴리스를 찾을 경우 서버는 상태 코드 200 (OK)와 Content-Type 헤더 application/zip으로 응답해야 합니다. 그렇지 않으면 서버는 상태 코드 404 (Not Found)로 응답해야 합니다.

HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: public, immutable
Content-Type: application/zip
Content-Disposition: attachment; filename="LinkedList-1.1.1.zip"
Content-Length: 2048
Content-Version: 1
Digest: sha-256=oqxUzyX7wa0AKPA/CqS5aDO4O7BaFOUQiSuyfepNyBI=
Link: <https://mirror-japanwest.example.com/mona-LinkedList-1.1.1.zip>; rel=duplicate; geo=jp; pri=10; type="application/zip"
X-Swift-Package-Signature-Format: cms-1.0.0
X-Swift-Package-Signature: l1TdTeIuGdNsO1FQ0ptD64F5nSSOsQ5WzhM6/7KsHRuLHfTsggnyIWr0DxMcBj5F40zfplwntXAgS0ynlqvlFw==
text

서버는 아카이브 크기를 바이트 단위로 설정한 Content-Length 헤더로 응답해야 합니다. 클라이언트는 예상 콘텐츠 길이를 초과하는 응답의 모든 요청을 종료해야 합니다.

서버는 소스 아카이브의 암호화 다이제스트가 포함된 Digest 헤더로 응답할 수 있습니다.

서버는 패키지 이름, 하이픈(-), 버전 번호 및 파일 확장명(예: "LinkedList-1.1.1.zip")이 같은 filename 매개변수가 있는 attachment로 설정된 Content-Disposition 헤더로 응답해야 합니다.

서버는 응답 콘텐츠(즉, 소스 아카이브)가 다른 API 버전에서 변경되지 않아야 하므로 Content-Version 헤더를 생략할 수 있습니다.

클라이언트와 서버는 RFC 7233에 설명된 대로 범위 요청을, RFC 7234에 설명된 대로 캐싱을 지원하는 것이 좋습니다.

릴리스가 서명된 경우 서버는 응답에 X-Swift-Package-Signature-FormatX-Swift-Package-Signature 헤더를 포함해야 합니다.

4.1. 무결성 검증

클라이언트는 4.2.1에 설명된 대로 GET /{scope}/{name}/{version} 응답의 관련 source-archive 리소스에 대한 checksum 값을 사용하여 다운로드한 소스 아카이브의 무결성을 검증해야 합니다.

클라이언트는 소스 아카이브 응답의 Digest 헤더에 제공된 값을 사용하여 무결성을 검증해야 합니다 (명령어 shasum -b -a 256 LinkedList-1.1.1.zip | cut -f1 | xxd -r -p | base64 사용).

4.2. 다운로드 위치

서버는 RFC 6249에 설명된 대로 duplicate 관계를 가진 Link 헤더 필드를 사용하여 미러나 여러 다운로드 위치를 지정할 수 있습니다. 클라이언트는 이 정보를 사용하여 다운로드에 선호하는 전략을 결정할 수 있습니다.

서버는 클라이언트를 다른 호스트에서 소스 아카이브를 다운로드하도록 리디렉션하기 위해 상태 코드 303 (See Other)로 응답할 수 있습니다. 클라이언트는 안전하지 않은 연결로 다운그레이드하는 리디렉션은 따라서는 안 됩니다. 클라이언트는 리디렉션 루프를 방지하기 위해 리디렉션 횟수를 제한해야 합니다.

예를 들어, 서버는 서명된 URL을 사용하여 클라이언트를 CDN에서 다운로드하도록 리디렉션합니다:

HTTP/1.1 303 See Other
Location: <https://example.cdn.com/LinkedList-1.1.1.zip?key=XXXXXXXXXXXXXXXXX>
text
GET /LinkedList-1.1.1.zip?key=XXXXXXXXXXXXXXXXX HTTP/1.1
Host: example.cdn.com
Accept: application/vnd.swift.registry.v1+zip
text
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: public, immutableContent-Type: application/zip
Content-Disposition: attachment; filename="LinkedList-1.1.1.zip"
Content-Length: 2048
Content-Version: 1
Digest: sha-256=a2ac54cf25fbc1ad0028f03f0aa4b96833b83bb05a14e510892bb27dea4dc812
text

4.3. 서명 검증

클라이언트는 서명 형식과 구성에 따라 서명된 아카이브의 서명을 검증해야 합니다. 서명 정보는 4.2.1에 설명된 대로 GET /{scope}/{name}/{version} 응답의 관련 source-archive 리소스에서도 찾을 수 있습니다.

5. URL에 등록된 패키지 식별자 조회

클라이언트는 /identifiers?url={url} 경로에 GET 요청을 보내 특정 URL과 연결된 패키지 식별자를 가져올 수 있습니다. 클라이언트는 Accept 헤더 값을 application/vnd.swift.registry.v1+json으로 설정해야 합니다.

GET /identifiers?url=https://github.com/mona/LinkedList HTTP/1.1
Host: packages.example.com
Accept: application/vnd.swift.registry.v1
text

클라이언트는 반드시 url 쿼리 매개변수에 대한 URL을 제공해야 합니다. url 매개변수가 지정되지 않은 경우 서버는 상태 코드 400 (Bad Request)로 응답해야 합니다.

지정된 URL과 연결된 하나 이상의 패키지 식별자가 있는 경우 서버는 상태 코드 200 (OK) 및 Content-Type 헤더 application/json으로 응답해야 합니다. 그렇지 않으면 서버는 상태 코드 404 (Not Found)로 응답해야 합니다.

서버는 지정된 URL에 대한 패키지 식별자가 포함된 JSON 문서로 응답해야 합니다.

HTTP/1.1 200 OK
Content-Type: application/json
Content-Version: 1

{
    "identifiers": [
      "mona.LinkedList"
    ]
}
text

응답 본문에는 최상위 identifiers 키 아래 중첩된 패키지 식별자 문자열의 배열이 포함되어야 합니다.

클라이언트와 서버가 RFC 7234에 설명된 대로 캐싱을 지원하는 것이 좋습니다.

5.1 URL에서 패키지 식별자 매핑

패키지 릴리스 메타데이터 JSON 객체의 일부로 repositoryURLs 배열을 사용하여 패키지 식별자와 연결된 URL을 지정할 수 있습니다. 이것은 서버가 이 API에 대한 URL에서 패키지 식별자 매핑을 얻을 수 있는 한 가지 방법입니다.

서버는 패키지 작성자가 이러한 매핑을 지정하기 위해 다른 메커니즘을 선택할 수 있습니다.

서버는 해당 저장소에 대한 패키지 작성자의 소유권 주장을 검증해야 합니다.

6. 패키지 릴리스 생성

클라이언트는 /{scope}/{name}/{version} 경로에 PUT 요청을 보내 패키지의 새 릴리스를 게시할 수 있습니다. 클라이언트는 다음 섹션이 포함된 멀티파트 폼 데이터로 인코딩된 본문을 제공해야 합니다:

Content-Type설명필수 여부
source-archiveapplication/zip패키지의 소스 아카이브필수
source-archive-signatureapplication/octet-stream소스 아카이브 서명선택사항
metadataapplication/json릴리스에 대한 추가 정보선택사항
metadata-signatureapplication/octet-stream메타데이터 서명선택사항

클라이언트는 Content-Type 헤더 값을 multipart/form-data로 설정해야 합니다. boundary는 임의의 문자열일 수 있습니다.

클라이언트는 Content-Transfer-Encoding 헤더에 유효한 값(예: binary)을 사용할 수 있습니다.

클라이언트는 Content-Length 헤더에 바이트 단위로 본문의 총 크기를 설정해야 합니다.

클라이언트는 Accept 헤더 값을 application/vnd.swift.registry.v1+json으로 설정해야 합니다.

소스 아카이브가 서명된 경우 클라이언트는 X-Swift-Package-Signature-Format 헤더에 서명 형식을 설정해야 합니다.

PUT /mona/LinkedList/1.1.1 HTTP/1.1
Host: packages.example.com
Accept: application/vnd.swift.registry.v1+json
Content-Type: multipart/form-data;boundary="boundary"
Content-Length: 336
Expect: 100-continue
X-Swift-Package-Signature-Format: cms-1.0.0

--boundary
Content-Disposition: form-data; name="source-archive"
Content-Type: application/zip
Content-Length: 32
Content-Transfer-Encoding: base64

gHUFBgAAAAAAAAAAAAAAAAAAAAAAAA==

--boundary
Content-Disposition: form-data; name="source-archive-signature"
Content-Type: application/octet-stream
Content-Length: 88
Content-Transfer-Encoding: base64

l1TdTeIuGdNsO1FQ0ptD64F5nSSOsQ5WzhM6/7KsHRuLHfTsggnyIWr0DxMcBj5F40zfplwntXAgS0ynlqvlFw==

--boundary
Content-Disposition: form-data; name="metadata"
Content-Type: application/json
Content-Transfer-Encoding: quoted-printable
Content-Length: 3

{ "repositoryURLs": [] }

--boundary
Content-Disposition: form-data; name="metadata-signature"
Content-Type: application/octet-stream
Content-Length: 88
Content-Transfer-Encoding: base64

M6TdTeIuGdNsO1FQ0ptD64F5nSSOsQ5WzhM6/7KsHRuLHfTsggnyIWr0DxMcBj5F40zfplwntXAgS0ynlqvlFw==
text

서버는 클라이언트에게 패키지 릴리스를 생성하는 모든 요청에 대해 인증을 수행하도록 요구해야 합니다. 다중 요소 인증 사용을 권장합니다.

클라이언트는 릴리스를 어떤 순서로든 게시할 수 있습니다. 예를 들어 패키지에 기존 1.0.02.0.0 릴리스가 있는 경우 클라이언트는 새 1.0.1 또는 1.1.0 릴리스를 게시할 수 있습니다.

릴리스가 게시되면 소스 아카이브를 포함하여 해당 릴리스와 연결된 리소스는 변경되어서는 안 됩니다.

지정된 버전의 패키지에 대해 릴리스가 이미 존재하는 경우 서버는 상태 코드 409 (Conflict)로 응답해야 합니다.

HTTP/1.1 409 Conflict
Content-Version: 1
Content-Type: application/problem+json
Content-Language: en

{
   "detail": "a release with version 1.0.0 already exists"
}
text

새 소유자에게 범위가 이전된 후 패키지의 새 릴리스를 게시하기 위해 서버가 정책을 제정하는 것이 좋습니다. 예를 들어, 기존 패키지의 다음 릴리스는 새 주 버전으로 게시되거나 이전 후 45일이 지난 후에만 게시됩니다.

클라이언트가 Expect 헤더를 제공하는 경우 서버는 상태 코드 100 (Continue)로 응답하기 전에 요청이 성공할 수 있는지 확인해야 합니다. 예상을 지원하지 않는 서버는 상태 코드 417 (Expectation Failed)로 응답해야 합니다. 응답하여 클라이언트는 Expect 헤더를 제거하고 요청을 다시 시도할 수 있습니다.

HTTP/1.1 417 (Expectation Failed)
Content-Version: 1
Content-Type: application/problem+json
Content-Language: en

{
   "detail": "expectations aren't supported"
}
text

이 엔드포인트에 대한 지원은 선택사항입니다. 서버는 상태 코드 405 (Method Not Allowed)로 응답하여 게시가 지원되지 않음을 나타내야 합니다.

HTTP/1.1 405 (Method Not Allowed)
Content-Version: 1
Content-Type: application/problem+json
Content-Language: en

{
   "detail": "publishing isn't supported"
}
text

서버는 동기식 또는 비동기식으로 응답할 수 있습니다. 자세한 내용은 4.6.4를 참조하세요.

6.1. 소스 아카이브

클라이언트는 릴리스의 소스 아카이브가 포함된 source-archive라는 멀티파트 섹션을 포함해야 합니다. 클라이언트는 Content-Type 헤더 값을 application/zip으로, Content-Length 헤더에 바이트 단위의 Zip 아카이브 크기를 설정해야 합니다.

--boundary
Content-Disposition: form-data; name="source-archive"
Content-Type: application/zip
Content-Length: 32
Content-Transfer-Encoding: base64

gHUFBgAAAAAAAAAAAAAAAAAAAAAAAA==
text

클라이언트는 릴리스에 대한 소스 아카이브를 만들기 위해 swift package archive-source 도구를 사용해야 합니다.

서버는 패키지를 분석하여 실행 가능성을 평가하고, 보안 테스트를 수행하거나, 소프트웨어 품질을 평가할 수 있습니다. 서버는 어떤 이유로든 상태 코드 422 (Unprocessable Entity)로 응답하여 패키지 릴리스 게시를 거부할 수 있습니다.

HTTP/1.1 422 Unprocessable Entity
Content-Version: 1
Content-Type: application/problem+json
Content-Language: en

{
   "detail": "package doesn't contain a valid manifest (Package.swift) file"
}
text

서버는 클라이언트의 후속 요청에 대한 응답으로 제공되는 체크섬을 계산하기 위해 swift package compute-checksum 도구를 사용해야 합니다 (소스 아카이브 다운로드 참조).

6.2. 패키지 릴리스 메타데이터

클라이언트는 릴리스에 대한 추가 정보가 포함된 metadata라는 멀티파트 섹션을 포함할 수 있습니다. 클라이언트는 Content-Type 헤더 값을 application/json으로, Content-Length 헤더에 바이트 단위의 JSON 문서 크기를 설정해야 합니다. 패키지 릴리스 메타데이터는 4.2.2에서 설명한 대로 JSON 스키마를 기반으로 해야 합니다.

--boundary
Content-Disposition: form-data; name="metadata"
Content-Type: application/json
Content-Length: 226
Content-Transfer-Encoding: quoted-printable

{
  "description": "One thing links to another.",
  "repositoryURLs": ["<https://github.com/mona/LinkedList>"],
  "licenseURL": "<https://www.apache.org/licenses/LICENSE-2.0>",
  "author": {
      "name": "Mona Lisa Octocat"
  }
}
text

서버는 릴리스에 대한 추가 메타데이터를 허용 및/또는 채울 수 있습니다.

서버는 JSON 스키마의 속성과 정의한 추가 메타데이터를 필수로 지정할 수 있습니다.

클라이언트가 유효하지 않은 JSON 문서를 제공하면 서버는 상태 코드 422 (Unprocessable Entity) 또는 413 (Payload Too Large)로 응답해야 하며, 응답 본문에 유효성 검사 오류 세부 정보를 전달할 수 있습니다.

HTTP/1.1 422 Unprocessable Entity
Content-Version: 1
Content-Type: application/problem+json
Content-Language: en

{
   "detail": "invalid JSON provided for release metadata"
}
text

6.3. 동기식 및 비동기식 게시

서버는 새 패키지 릴리스를 게시하는 요청에 대해 동기식 또는 비동기식으로 응답할 수 있습니다.

클라이언트는 respond-async 토큰과 선택적 wait 기본 설정이 포함된 Prefer 헤더 필드를 사용하여 비동기 처리에 대한 선호도를 나타낼 수 있습니다 (RFC 7240 참조).

PUT /mona/LinkedList/1.1.1 HTTP/1.1
Host: packages.example.com
Accept: application/vnd.swift.registry.v1
Prefer: respond-async, wait=300
text

6.3.1. 동기식 게시

처리가 동기식으로 수행되는 경우 서버는 패키지 릴리스가 게시되었음을 나타내기 위해 상태 코드 201 (Created)로 응답해야 합니다. 이 응답에는 새 릴리스에 대한 URL이 포함된 Location 헤더도 포함되어야 합니다.

HTTP/1.1 201 Created
Content-Version: 1
Location: <https://packages.example.com/github.com/mona/LinkedList/1.1.1>
text

클라이언트는 각 요청에 대한 시기적절한 응답을 보장하기 위해 시간 제한을 설정할 수 있습니다.

6.3.2. 비동기식 게시

처리가 비동기식으로 수행되는 경우 서버는 요청이 처리 중임을 알리기 위해 상태 코드 202 (Accepted)로 응답해야 합니다. 이 응답에는 클라이언트가 진행 상황 업데이트를 폴링할 수 있는 URL이 포함된 Location 헤더가 반드시 포함되어야 하며, 처리가 완료될 것으로 예상되는 시간이 포함된 Retry-After 헤더가 포함되어야 합니다. 서버는 선택한 URI에 상태 리소스 엔드포인트를 배치할 수 있습니다. 그러나 순차적이지 않은 무작위로 생성된 식별자의 사용을 권장합니다.

HTTP/1.1 202 Accepted
Content-Version: 1
Location: <https://packages.example.com/submissions/90D8CC77-A576-47AE-A531-D6402C4E33BC>
Retry-After: 120
text

클라이언트는 게시 요청에 대한 응답으로 서버가 제공한 위치에 GET 요청을 보내 해당 프로세스의 현재 상태를 볼 수 있습니다.

GET /submissions/90D8CC77-A576-47AE-A531-D6402C4E33BC HTTP/1.1
Host: packages.example.com
Accept: application/vnd.swift.registry.v1
text

비동기 게시 요청이 여전히 처리 중인 경우 서버는 상태 코드 202 (Accepted)와 처리가 완료될 것으로 예상되는 시간이 포함된 Retry-After 헤더로 응답해야 합니다. 서버는 응답 본문에 추가 세부 정보를 포함할 수 있습니다.

HTTP/1.1 202 Accepted
Content-Version: 1
Content-Type: application/json
Retry-After: 120

{
  "status": "Processing (2/3 steps complete)",
  "steps": {
    {"name": "Validate metadata", "status": "complete"},
    {"name": "Verify package manifest", "status": "complete"},
    {"name": "Scan for vulnerabilities", "status": "pending"}
  }
}
text

비동기 게시 요청이 성공적으로 처리를 완료한 경우 서버는 상태 코드 301 (Moved Permanently)과 패키지 릴리스에 대한 URL이 포함된 Location 헤더로 응답해야 합니다.

HTTP/1.1 301 Moved Permanently
Content-Version: 1
Location: <https://packages.example.com/mona/LinkedList/1.1.1>
text

비동기 게시 요청이 실패한 경우 서버는 적절한 클라이언트 오류 상태 코드(4xx)로 응답해야 합니다.

HTTP/1.1 400 Bad Request
Content-Version: 1
Content-Type: application/problem+json
Content-Language: en
Location: <https://packages.example.com/submissions/90D8CC77-A576-47AE-A531-D6402C4E33BC>

{
   "detail": "invalid package"
}
text

클라이언트는 게시 요청에 대한 응답으로 서버가 제공한 위치에 DELETE 요청을 보내 해당 프로세스를 취소할 수 있습니다.

새 패키지 릴리스를 게시하는 요청이 실패하는 경우 서버는 즉시 응답을 보낼 때와 동일한 방식으로 상태를 폴링하는 클라이언트에 응답할 때 해당 실패를 전달해야 합니다.

패키지 릴리스를 게시하는 요청을 비동기식으로 처리 중인 서버에 클라이언트가 해당 릴리스를 게시하는 요청을 하는 경우 서버는 상태 코드 409 (Conflict)로 응답해야 합니다.

HTTP/1.1 409 Conflict
Content-Version: 1
Content-Type: application/problem+json
Content-Language: en
Location: <https://packages.example.com/submissions/90D8CC77-A576-47AE-A531-D6402C4E33BC>

{
   "detail": "already processing a request to publish this package version"
}
text

클라이언트가 해당 릴리스를 게시하는 요청에 대한 실패한 처리를 완료한 서버에 패키지 릴리스를 게시하는 요청을 하는 경우 서버는 해당 릴리스를 다시 게시하려고 시도해야 합니다. 서버는 상태 코드 409 (Conflict)로 응답하여 패키지 릴리스를 게시하는 후속 요청을 수행하는 것을 거부할 수 있습니다.