패키지는 시맨틱 버전 지정(SemVer)을 준수해야 합니다. 시맨틱 버전 지정은 패키지 작성자가 기존 버전 대비 특정 버전에 포함된 변경 사항 유형에 관한 정보를 자동화 툴이 사용할 수 있는 포맷으로 제공하도록 하는 버전 전략입니다.
시맨틱 버전 지정은 버전을 MAJOR.MINOR.PATCH로 표시합니다. 여기에서 MAJOR는 한 번 이상의 중대한 변경, MINOR는 한 번 이상 이전 버전과 호환되는 방식으로 API 변경, PATCH는 API 변경 없는 버그 수정을 의미합니다.
패키지 개발을 시작하면 버전 번호를 0.1.0부터 시작합니다. MAJOR 버전 번호 0은 초기 개발 단계의 패키지에 사용됩니다. 초기 개발 단계에서는 패키지 API가 기존 버전과 호환되지 않는 방식으로 자주 변경되므로 패키지가 충분히 안정적이고 정식으로 제작에 사용 가능할 때까지 MAJOR 버전 번호를 0으로 유지하십시오.
공식적으로 프로덕션 환경에서 패키지를 사용할 준비가 되면 MAJOR 버전을 1로 상향하고 후속 변경에 다음 가이드라인을 준수하십시오.
| 값 증분: | 해당 조건: | 예: |
|---|---|---|
| MAJOR | 하나 이상의 중대한 변경 사항이 있으며 두 패키지 버전은 서로 대체할 수 없습니다. 중대한 변경 사항은 다음과 같습니다. • 컴파일 또는 런타임 오류가 발생할 수 있는 방식으로 API 표면(API의 노출된 부분) 또는 기능 변경 • 에셋 제거 또는 에셋의 GUID 변경 등 API가 아닌 기능 제거 • 어셈블리 및 에셋 제거 또는 이름 변경(컴파일러가 어셈블리와 에셋을 찾지 못할 수 있기 때문) 참고: 메이저 버전을 상향할 때 항상 PATCH 및 MINOR 값을 0으로 재설정하십시오. |
1.2.3 버전과 2.0.0 버전은 호환 가능하지 않으며 안전하게 서로 교체하여 사용할 수 없습니다. |
|
MINOR (MAJOR 값과 동일) |
높은 MINOR 버전에는 이전 버전과 호환되는 방식으로 기능이 추가됩니다. 이전 버전과 호환되는(또는 중대하지 않은) API 변경 사항은 다음과 같습니다. • 컴파일 또는 런타임 오류의 위험 없이 API 표면 또는 기능 변경 • API가 아닌 기능 추가 • 어셈블리 및 에셋 추가(새 항목에는 기존 레퍼런스가 없기 때문) 참고: 마이너 버전을 상향할 때는 항상 PATCH 버전을 0으로 재설정하십시오. |
1.3.0 버전은 이전 버전과 호환되므로 1.2.0에 대한 종속성을 1.3.0으로 충족할 수 있습니다. 1.2.0으로는 1.3.0에 대한 종속성을 충족할 수 없습니다. |
|
PATCH (MAJOR.MINOR 값과 동일) |
높은 PATCH 버전에는 API의 변경 없이 이전 버전과 호환되는 방식으로 버그 수정이 추가됩니다. 다음과 같은 경우 API가 변경되지 않습니다. • API 표면이 동일하고 기능은 변경되지 않은 경우 • 변경 사항으로 인해 공개 API가 변경되지 않은 경우 |
1.3.0 버전과 1.3.1 버전은 둘 다 동일한 API를 가지고 있으므로 교체하여 사용할 수 있습니다. 단, 1.3.1에는 1.3.0에는 없는 버그 수정이 포함되어 있습니다. |
이러한 버전 지정 방식을 따르면 패키지 관리자가 충돌을 자동으로 해결(가능한 경우)하거나 패키지를 이전 버전과 호환되는 신규 버전으로 업그레이드할 수 있습니다.
다음 섹션에서는 이러한 규칙이 다양한 패키지 요소에 미치는 영향을 확인하는 데 도움이 되는 여러 사례를 소개합니다.
이러한 사례 외에도 일반적으로 MINOR 또는 PATCH 버전 상향만 필요한 일부 변경 사항에 영향을 줄 수 있는 또 다른 요소는 Auto Referenced 프로퍼티의 활성화 여부입니다.
어셈블리 정의에 설정할 수 있는 프로퍼티 중 하나는 Unity가 컴파일 중에 파일을 자동으로 참조하는지 여부를 제어하는 Auto Referenced 프로퍼티입니다. 이 프로퍼티를 활성화하면 일반적으로 MINOR 또는 PATCH 버전 상향만 필요한 일부 변경 사항이 중대한 변경 사항이 됩니다.
자동 참조를 비활성화하고 새 어셈블리를 사용할 수 있도록 변경하는 경우 API에 이전 버전과 호환되는 변경 사항이 적용됩니다. 이전 버전과 호환되는 API 변경(예: 플랫폼 추가, Unity Test References 비활성화, 새로운 .asmdef 추가, 정의 제약 제거)에는 MINOR 버전 상향만 필요합니다.
그러나 자동 참조를 활성화하면 새로 추가된 어셈블리가 다른 여러 어셈블리의 레퍼런스에 암시적으로 추가됩니다. 이러한 경우 다른 어셈블리에서 컴파일 오류가 발생할 수 있으므로 MAJOR 버전 상향이 필요합니다.
또 다른 일반적인 사례는 패키지 종속성에 대한 버전을 추가하거나 변경할 때 발생합니다. 대부분의 경우 패키지 종속성 변경에는 PATCH 버전 상향만 필요합니다. 그러나 새 패키지 버전에는 Auto Referenced 프로퍼티가 활성화된 어셈블리가 포함될 수 있습니다. 이는 중대한 변경 사항이므로 MAJOR 버전 상향이 필요합니다.
이러한 문제를 피하려면 타사 DLL 파일은 항상 관련이 없는 패키지에 넣으십시오(예: Newtonsoft.Json.dll을 SaveGameManager 패키지에 포함).
프로젝트는 에셋 데이터베이스에 표시되는 모든 에셋을 참조할 수 있습니다. 에셋 데이터베이스는 .meta 파일에 정의된 GUID를 사용하여 이러한 에셋을 고유하게 추적합니다.
이러한 변경 사항 중 하나를 공개 API에 도입하면 중대한 변경 사항이므로 새로운 MAJOR 릴리스가 필요합니다.
| 시나리오: | 중대한 변경 사항인 이유: |
|---|---|
| 에셋 데이터베이스에 표시되는 에셋 제거 | 에셋을 제거하면 사용자 프로젝트 또는 기타 패키지의 레퍼런스가 끊어질 수 있습니다. |
| 에셋의 GUID 변경 | 에셋 GUID를 변경하면 에셋 데이터베이스는 원본 에셋을 제거한 후 새(동일한) 에셋을 추가하는 것으로 인식합니다. 그러면 원본 GUID가 더 이상 에셋을 가리키지 않으므로 에셋 데이터베이스가 레퍼런스를 확인할 수 없기 때문에 레퍼런스가 끊어지게 됩니다. |
어셈블리 정의(.asmdef)는 Unity 에디터의 컴파일 파이프라인에서 별도의 관리되는 어셈블리(.dll)로 변환하는 스크립트 그룹을 정의합니다. 이러한 .asmdef 에셋에는 결과 어셈블리의 프로퍼티를 결정하는 프로퍼티가 포함되어 있습니다. 이 경우는 다음과 같습니다.
대부분의 프로퍼티는 어셈블리 사용자에게 영향을 미치므로 이러한 프로퍼티를 변경하면 패키지의 공개 API가 변경됩니다. 다른 프로퍼티는 어셈블리 사용자에게 영향을 미치지 않으므로 이러한 프로퍼티를 변경해도 패키지 API를 변경하는 것으로 간주되지 않습니다.
경고: Auto Referenced 프로퍼티는 특별한 경우입니다. 일반적으로 API를 변경하지 않거나 이전 버전과 호환 가능한 방식으로 API를 변경하면 이 프로퍼티의 활성화 여부에 따라 컴파일 오류가 발생할 수 있기 때문입니다. 자세한 내용은 자동 참조를 참조하십시오.
Unity는 어셈블리를 사전 컴파일하거나 스크립트와 어셈블리 정의에서 컴파일할 수 있습니다. 따라서 어셈블리 정의에 적용되는 모든 사항은 일반적으로 사전 컴파일된 어셈블리에도 적용됩니다.
이 섹션에서는 어셈블리 정의와 사전 컴파일된 어셈블리의 변경 사항과 패키지 버전에 미치는 영향에 대해 자세히 설명합니다.
공개 API에 중대한 변경 사항을 도입하는 경우 컴파일과 런타임 오류가 발생할 수 있으므로 새로운 MAJOR 릴리스가 필요합니다. 이러한 시나리오에서는 모두 어셈블리를 참조하는 다른 어셈블리에서 어셈블리를 제거하거나 숨깁니다. 참조된 어셈블리에 정의된 유형을 사용하는 어셈블리가 컴파일될 때 컴파일러가 해당 다른 어셈블리를 찾을 수 없는 경우 컴파일 오류가 발생합니다. 어셈블리와 어셈블리 정의 작업에 대한 자세한 내용은 어셈블리 정의를 참조하십시오.
다음은 패키지가 소비하고 사용하는 런타임 및 에디터 어셈블리에 모두 적용됩니다. 테스트 어셈블리는 적용되지 않는데, 패키지가 일반적으로 테스트 어셈블리를 사용하지 않으므로 패키지의 API에 포함되지 않기 때문입니다.
| 시나리오: | 컴파일러가 참조된 어셈블리를 찾을 수 없는 이유: |
|---|---|
| 어셈블리 정의 또는 사전 컴파일된 어셈블리 제거 | 어셈블리 정의 파일을 제거하면 컴파일 파이프라인이 해당 어셈블리를 생성하지 못합니다. 참고: 2019.1부터 ‘선택적 레퍼런스’ 사용 사례를 지원하기 위해 레퍼런스 누락이 허용되지만, Unity가 어셈블리 정의를 컴파일하는 데 필요한 어셈블리 이름 변경을 수행하면 컴파일 오류가 발생합니다. 마찬가지로 컴파일된 코드가 어셈블리의 유형을 필요로 하는 경우 해당 어셈블리의 이름을 변경하면 TypeLoadException 같은 런타임 오류가 발생할 수 있습니다. |
| 어셈블리 이름 변경(.asmdef 파일에서 변경 또는 .dll 파일 이름 변경) | 어셈블리 이름을 변경하는 것은 어셈블리를 제거한 후 이름이 다른 새 어셈블리를 추가하는 것과 같습니다. 즉, API에 동일한 어셈블리 코드가 다른 이름으로 포함되어 있더라도 Unity는 원래 어셈블리가 누락된 것으로 간주합니다. |
| .asmdef에 정의 제약 추가 | 정의 제약을 추가하면 정의 제약이 충족되지 않을 때마다 Unity가 어셈블리 컴파일을 건너뜁니다. 그러면 이전에 사용 가능했던 어셈블리가 누락되는 경우가 발생합니다. |
| 플랫폼 제거 | 특정 플랫폼에 대한 지원을 제거하면 Unity는 해당 플랫폼에서 더 이상 어셈블리를 임포트하지 않으며, 이는 어셈블리를 제거하는 것과 동일합니다. 다음 프로퍼티 중 하나를 활성화하여 플랫폼을 제거할 수 있습니다. • 모든 등록되지 않은 플랫폼과의 호환성을 깨뜨리는 includePlatforms • 항목을 추가하는 excludePlatforms |
| 공용 API를 한 어셈블리에서 다른 어셈블리로 이동 | 공개적으로 액세스 가능한 코드를 어셈블리 A에서 어셈블리 B로 이동하면 A를 참조하지만 B를 참조하지 않는 어셈블리가 컴파일되지 않습니다. 어셈블리 정의의 경우, 스크립트를 이동하면 공개 API를 다른 어셈블리로 이동시킬 수 있습니다. |
| Auto Referenced 프로퍼티 변경 |
Auto Referenced 프로퍼티를 비활성화하면 명시적인 레퍼런스 없이 이 어셈블리의 공개 API를 더 이상 사용할 수 없습니다. • 사전 컴파일된 어셈블리의 경우 이 프로퍼티를 비활성화하면 Unity가 어셈블리 정의와 프로젝트에서 컴파일된 어셈블리에 대한 레퍼런스로 사전 컴파일된 어셈블리를 암시적으로 추가하지 못합니다. • 어셈블리 정의의 경우 이 프로퍼티를 비활성화하면 Unity가 결과 어셈블리를 프로젝트에서 컴파일된 어셈블리에 대한 레퍼런스로 암시적으로 추가하지 못합니다. Auto Referenced 프로퍼티를 활성화하면 API, 프로퍼티, 종속성에 대한 다른 변경 사항과 충돌할 수 있습니다. 자세한 내용은 자동 참조 섹션을 참조하십시오. |
| 어셈블리 정의에서 Unity References → Test Assemblies 프로퍼티 활성화 | Unity References → Test Assemblies 프로퍼티를 활성화하면 이 어셈블리가 테스트 어셈블리로 표시되며, 일반적으로 Unity는 이를 빌드에 포함하지 않고 일부 경우에는 컴파일하지 않습니다. 이 경우 누락된 어셈블리를 참조하는 어셈블리는 테스트 어셈블리인 경우를 제외하고는 어셈블리를 찾지 못합니다. |
다음 변경 사항은 이전 버전과 호환되거나 중대하지 않은 API 변경 사항입니다. 이러한 시나리오에서는 모두 어셈블리를 제거하는 중대한 변경과 다르게 어셈블리를 추가합니다. 어셈블리를 추가하면 API 표면(API의 노출된 부분)이 증가하므로 API 변경 사항으로 간주됩니다. 하지만 기존 레퍼런스가 없으므로 새 어셈블리를 추가해도 이전 API로 생성된 다른 어셈블리에는 영향을 미치지 않습니다.
이전 버전과 호환되는 변경 사항은 최소한 새로운 MINOR 릴리스가 필요합니다. 중대한 변경 사항이 포함된 다른 업데이트를 포함하는 경우에는 새로운 MAJOR 릴리스에 포함될 수도 있습니다.
경고: 이러한 변경 사항은 Auto Referenced 프로퍼티가 비활성화된 경우에만 이전 버전과 호환됩니다. Auto Referenced 프로퍼티를 활성화하면 이 표에 나열된 변경 사항으로 인해 큰 변경 사항이 발생할 수 있습니다. 자세한 내용은 자동 참조 섹션을 참조하십시오.
| 시나리오 | 이 변경 사항이 컴파일을 중단하지 않는 이유 |
|---|---|
| .asmdef에 대한 정의 제약 제거 | 정의 제약을 제거하면 컴파일 및 스크립팅 파이프라인이 더 이상 이 어셈블리를 건너뛸 수 없습니다. Unity가 항상 해당 어셈블리를 빌드하기 때문에 컴파일러는 정의 제약이 충족되는지 여부와 관계없이 언제든지 해당 어셈블리에 대한 레퍼런스를 확인할 수 있습니다. |
| 플랫폼 추가 | 플랫폼을 추가해도 기존 플랫폼 지원에 영향을 미치지 않으므로 이전 버전과 호환됩니다. 이 경우 API 표면이 증가하므로 API 변경입니다. 다음 프로퍼티를 수정하여 플랫폼을 추가할 수 있습니다. • includePlatforms 프로퍼티에 항목을 추가합니다. • includePlatforms 프로퍼티를 완전히 제거합니다. 이는 includePlatforms 프로퍼티에 아직 없는 모든 플랫폼을 추가하는 것과 같습니다. • excludePlatforms 프로퍼티에서 항목을 제거합니다. |
| 새 스크립트를 사용하여 어셈블리 정의 생성(이전에 다른 .asmdef 파일에 없었음) | 새 어셈블리를 추가하면 기존 구현을 변경하지 않고 API 표면(API의 노출 부분)을 증가시킵니다. |
| 어셈블리 정의 파일에서 Unity References → Test Assemblies 프로퍼티 비활성화 | Unity References → Test Assemblies 프로퍼티를 비활성화하면 이 어셈블리가 일반 어셈블리로 표시되므로 Unity는 어셈블리 정의와 다르게 취급하지 않습니다. 이 경우 API 표면이 증가하므로 API 변경입니다. |
다음 변경 사항은 공개 API에 영향을 주지 않으며 PATCH 릴리스에서 허용됩니다. 이러한 시나리오의 변경 사항은 API 표면(API의 노출 부분)에 영향을 주지 않고 다른 사용자의 입장에서는 아무것도 변경되지 않으므로 공개 API를 변경하지 않습니다.
공개 API를 변경하지 않는 변경 사항에는 최소한 새 PATCH 릴리스가 필요합니다. 중대하거나 중대하지 않은 변경 사항이 적용되는 다른 업데이트를 포함하는 경우 MAJOR 또는 MINOR 릴리스에 포함될 수도 있습니다.
| 시나리오 | 이 변경 사항이 다른 소비자에 영향을 주지 않는 이유 |
|---|---|
| .asmdef 파일에서 참조된 어셈블리 및 어셈블리 정의 목록 변경 | 다른 어셈블리를 참조하는 어셈블리는 해당 다른 어셈블리의 자체 레퍼런스를 자동으로 참조하지 않지만 명시적으로 나열해야 합니다. 따라서 어셈블리 정의나 어셈블리의 레퍼런스를 변경해도 다른 사용자에게는 영향을 미치지 않습니다. |
| 어셈블리 정의에서 Allow unsafe code 프로퍼티 변경 | 이 프로퍼티는 컴파일러가 안전하지 않은 수정자를 가진 코드를 컴파일할 수 있는지 제어합니다. 자체 플래그를 변경해도 공개 API는 변경되지 않습니다. |
| 어셈블리 정의에서 Override References 프로퍼티 변경 | 이 프로퍼티는 Unity가 이 어셈블리에 대한 컴파일러를 호출하는 방법을 제어하며, 결과 어셈블리의 사용자에게 아무 영향도 미치지 않습니다. 자체 플래그를 변경해도 공개 API는 변경되지 않습니다. |
패키지 매니페스트 파일(package.json)은 패키지 자체에 대한 이름, 버전, 패키지 종속성, 기타 메타데이터를 지정합니다.
이 섹션에서는 패키지 매니페스트 파일의 변경 사항과 패키지 버전에 미치는 영향에 대해 자세히 설명합니다.
name 프로퍼티를 변경하는 것은 하나의 패키지를 제거하고 다른 이름의 새 패키지를 추가하는 것과 동일하며, 이는 지원되지 않는 작업입니다. 업데이트를 릴리스하려고 하면 패키지의 이름을 변경할 수 없습니다. 완전히 새로운 패키지로 릴리스해야 합니다. 기존 프로젝트와 패키지는 이름을 동의어로 해석할 수 없으므로 이름을 변경할 수 없습니다.
프로젝트의 종속성을 변경했다고 해서 MAJOR 또는 MINOR 버전을 변경해야 하는 것은 아닙니다. 단, API 변경의 일부이거나 Auto Referenced 프로퍼티가 활성화된 경우는 예외입니다.
이 섹션에서는 종속성 변경의 예시와 그러한 변경 사항이 적용되는 컨텍스트에 대해 설명합니다(Auto Referenced 프로퍼티가 비활성화되어 있고 각 사례에서 설명하는 API 변경을 제외하고 다른 변경 사항은 없다고 가정).
| 종속성 변경 | 컨텍스트 | 최소 버전 변경 |
|---|---|---|
| 새 종속성 추가 | • 기능 동작을 변경하지 않고 새 패키지를 사용하며, API 표면을 변경하지 않습니다. | PATCH |
| • 새 패키지를 사용하여 API 표면을 수정하지 않고 새로운 동작을 도입합니다. • 새 패키지에 정의된 유형을 노출하는 새 API를 생성합니다. |
MINOR | |
| • 새 패키지를 사용하여 API 표면을 수정하지 않고 이전 버전과 호환되지 않는 방식으로 기존 동작을 변경합니다. • 이전 버전과 호환되지 않는 방식으로 기존 API를 수정하여 새 패키지에 정의된 유형을 노출합니다. |
MAJOR | |
| 종속성 제거 | • 기능 동작을 변경하지 않고 패키지를 제거하며, API 표면을 변경하지 않습니다. | PATCH |
| • 패키지를 제거하면 API 표면을 변경하지 않고 이전 버전과 호환되지 않는 방식으로 기존 동작을 변경합니다. • 해당 종속성에 정의된 유형을 노출하는 API를 제거합니다. |
MAJOR | |
| 종속성 변경 | • 기능 동작을 변경하지 않고 수정된 패키지를 사용하며, API 표면을 변경하지 않습니다. | PATCH |
| • 수정된 패키지를 사용하여 API 표면을 수정하지 않고 새로운 동작을 도입합니다. • 수정된 패키지에 정의된 유형을 노출하는 새 API를 생성합니다. |
MINOR | |
| • 수정된 패키지를 사용하여 API 표면을 수정하지 않고 이전 버전과 호환되지 않는 방식으로 기존 동작을 변경합니다. • 이전 버전과 호환되지 않는 방식으로 기존 API를 변경하여 수정된 패키지에 정의된 유형을 노출합니다. • 수정된 패키지에서 이전 버전과 호환되지 않는 방식으로 변경된 일부 유형을 API에 노출합니다. • 수정된 패키지에 더 이상 정의되지 않은 일부 유형을 API에 노출합니다. |
MAJOR |
릴리스 버전의 패키지 관리자, 빌드 파이프라인, 스크립팅 파이프라인 또는 에셋 데이터베이스에 특별한 영향을 미치지 않는 패키지 매니페스트 속성을 변경할 수 있습니다. 여기에는 설명, 카테고리, 키워드 또는 displayName 변경이 포함됩니다.
이 필드를 변경하면 변경 사항에 버그 수정 이상이 포함된다는 의미일 수 있습니다. 새로운 버전의 다른 변경 사항으로 인해 PATCH 릴리스가 아닌 새로운 MINOR 또는 MAJOR 릴리스가 필요한지 항상 고려하십시오.
참고: 패키지 매니페스트의 unity 또는 unityRelease 프로퍼티를 변경하려면 항상 MINOR 또는 MAJOR 릴리스가 필요합니다. 프로퍼티는 패키지 API 자체에 영향을 주지 않지만 Unity 버전을 높이면 이전 Unity 에디터에서 패키지 버전이 작동하지 않으며 종속 프로젝트나 패키지가 중단될 수 있습니다. Unity 버전을 낮추면 이전 Unity 에디터에서 패키지를 사용할 수 있습니다.
API에서 일부 기능을 제거하려면 먼저 지원 중단이 포함된 MINOR 버전을 하나 이상 릴리스해야 합니다. 이를 통해 사용자에게 곧 제거될 예정임을 경고하여 새 API로 원활하게 전환할 수 있도록 합니다. 그런 다음 새 MAJOR 릴리스에서 기능을 제거할 수 있습니다.
다른 개발자가 사용되지 않는 패키지에 경고 표시를 하고 프로젝트에서 Warnings as Errors가 활성화된 경우 코드가 여전히 이전처럼 작동하기 때문에 실제 중단이 아닌 경우에도 사용되지 않는 패키지로 인해 기술적으로 프로젝트가 중단될 수 있습니다.
이 경우 오류 경고를 수정할 방법을 선택할 수 있습니다(일반적인 타당성에 따라 내림차순 정렬).
#pragma warning 지시문에 API를 사용하는 코드를 래핑하여 경고를 끕니다.