패키지는 시맨틱 버전 지정(SemVer)을 준수해야 합니다. 시맨틱 버전 지정은 패키지 작성자가 기존 버전 대비 특정 버전에 포함된 변경 사항 타입에 관한 정보를 자동화 툴이 사용할 수 있는 포맷으로 제공하도록 해주는 버전 전략입니다.
시맨틱 버전 지정은 버전을 MAJOR.MINOR.PATCH로 표시합니다. 여기에서 MAJOR는 한 번 이상의 중대한 변경, MINOR는 한 번 이상 이전 버전과 호환되는 방식으로 API 변경, PATCH는 API 변경 없는 버그 수정을 의미합니다.
패키지 개발을 시작하면 버전 숫자를 0.1.0
에서 시작하십시오. MAJOR 버전 숫자 0
은 초기 개발 단계의 패키지에 사용됩니다. 초기 개발 동안 패키지 API가 자주 크게 바뀝니다. 따라서 패키지가 충분히 안정화되고 프로덕션에 사용할 수 있을 때까지 MAJOR 버전 숫자를 0
으로 유지하십시오.
패키지가 공식적으로 프로덕션 단계에 들어서면 MAJOR 버전을 1
로 올리고 다음 가이드라인에 따라 후속 변경을 적용하십시오.
값 증분: | 해당 조건: | 예제: |
---|---|---|
MAJOR | 최소 하나의 대규모 변경 사항이 있고, 패키지의 버전을 다른 버전으로 대체할 수 없습니다. 중대한 변경에는 다음이 포함됩니다. • 컴파일 또는 런타임 오류의 위험을 감수하고 API 표면(API의 노출 부분) 또는 기능 변경. • 비 API 기능 제거(에셋 제거 포함) 또는 에셋의 GUID 변경. • 어셈블리와 에셋 제거 또는 이름 변경(이 경우 컴파일러가 찾지 못할 수 있기 때문). 참고: 메이저 버전을 증분할 때는 항상 PATCH 및 MINOR 값을 0 으로 초기화하십시오. |
1.2.3 버전과 2.0.0 버전은 호환 가능하지 않으며 안전하게 서로 교체하여 사용할 수 없습니다. |
MINOR (MAJOR 값과 동일) |
가장 높은 MINOR 값은 이전 버전과 호환되는 방식으로 기능을 도입합니다. 이전 버전과 호환 가능한(중대하지 않은) API 변경에는 다음이 포함됩니다. • 컴파일 또는 런타임 오류를 일으킬 염려 없이 API 표면 또는 기능 변경. • 비 API 기능 추가. • 어셈블리와 에셋 추가(새 항목에는 기존 레퍼런스가 없기 때문). 참고: 마이너 버전을 증분할 때는 항상 PATCH 버전을 0 으로 초기화하십시오. |
1.3.0 버전은 이전 버전과 호환되므로 1.3.0 버전을 사용하여 1.2.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 프로퍼티의 활성화 여부입니다.
어셈블리 정의에 설정할 수 있는 프로퍼티 중 하나는 Auto Referenced 프로퍼티입니다. 이 프로퍼티는 Unity가 컴파일 중에 파일을 자동으로 참조하는지 여부를 제어합니다. 이 프로퍼티를 사용하면 일반적으로 MINOR 또는 PATCH 버전 증분만 필요로 하는 일부 변경 사항이 중대한 변경 사항으로 바뀝니다.
자동 참조를 비활성화하면, 새로운 어셈블리를 이용할 수 있게 되는 변경 사항을 적용할 경우 이전 버전과 호환되는 변경 사항이 API에 도입됩니다. 플랫폼 추가, Unity 테스트 레퍼런스 비활성화, 새 .asmdef 추가, Define Constraints 제거 등 이전 버전과 호환이 가능한 API 변경 사항은 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는 원본 어셈블리가 누락되었다고 간주합니다. |
Define Constraint를 .asmdef에 추가 | Define Constraint를 추가하면 Unity는 Define Constraint가 충족되지 않을 때마다 어셈블리 컴파일을 건너 뜁니다. 이러한 경우 이전에 사용 가능했던 어셈블리가 누락될 수 있습니다. |
플랫폼 제거 | 특정 플랫폼에 대한 지원을 제거하면 Unity는 해당 플랫폼에서 어셈블리를 더 이상 임포트하지 않으며, 이는 어셈블리를 제거한 것과 같습니다. 다음 프로퍼티 중 하나를 활성화하여 플랫폼을 제거할 수 있습니다. • includePlatforms - 리스트에 없는 모든 플랫폼과의 호환성 차단 • excludePlatforms - 항목 추가 |
공용 API를 한 어셈블리에서 다른 어셈블리로 이동 | 공개적으로 액세스 가능한 코드를 어셈블리 A에서 어셈블리 B로 이동하면 A만 참조하고 B는 참조하지 않는 어셈블리는 컴파일되지 않습니다. 어셈블리 정의의 경우 스크립트를 이동하면 공용 API가 다른 어셈블리로 이동할 수 있습니다. |
Auto Referenced 프로퍼티 변경 |
Auto Referenced 프로퍼티를 비활성화하면 명시적 레퍼런스 없이는 공용 API를 더 이상 사용할 수 없습니다. • 사전 컴파일된 어셈블리의 경우 이 프로퍼티를 비활성화하면 Unity가 어셈블리 정의와 프로젝트 컴파일 어셈블리에 사전 컴파일된 어셈블리를 레퍼런스로 암시적으로 추가할 수 없습니다. • 어셈블리 정의의 경우 이 프로퍼티를 비활성화하면 프로젝트 컴파일 어셈블리에 결과 어셈블리를 레퍼런스로 암시적으로 추가할 수 없습니다. Auto Referenced 프로퍼티를 활성화하면 API, 프로퍼티 또는 종속성에 대한 다른 변경 사항과 충돌이 발생할 수 있습니다. 자세한 내용은 자동 참조 섹션을 참조하십시오. |
어셈블리 정의에서 Unity References → Test Assemblies 프로퍼티 활성화 | Unity References → Test Assemblies 프로퍼티를 활성화하면 이 어셈블리가 테스트 어셈블리로 표시되고, 일반적으로 Unity가 빌드에 포함하지 않습니다(일부 경우 컴파일하지 않음). 따라서 테스트 어셈블리인 경우를 제외하고 누락된 어셈블리를 참조하는 어셈블리가 해당 어셈블리를 찾을 수 없습니다. |
다음은 이전 버전과 호환 가능한(중대하지 않은) API 변경 사항입니다. 이 시나리오는 모두 어셈블리를 제거하는 중대한 변경 사항과 달리 어셈블리를 추가합니다. 어셈블리를 추가하면 API 표면(API의 노출 부분)이 증가하므로 API 변경 사항으로 간주됩니다. 하지만 기존 레퍼런스가 없으므로, 새 어셈블리를 추가해도 이전 API를 사용하여 생성된 다른 어셈블리에는 영향을 주지 않습니다.
이전 버전과 호환 가능한 변경 사항은 최소 새로운 MINOR 릴리스를 필요로 합니다. 중대한 변경 사항이 포함된 다른 업데이트를 포함하는 경우에는 새로운 MAJOR 릴리스에 포함될 수도 있습니다.
경고: Auto Referenced 프로퍼티를 비활성화하면 이러한 변경 사항은 이전 버전과만 호환됩니다. Auto Referenced 프로퍼티를 활성화하면 이 표에 나열된 변경 사항들이 중대한 변경 사항으로 바뀝니다. 자세한 내용은 자동 참조 섹션을 참조하십시오.
Scenario | 이 변경 사항이 컴파일을 중단하지 않는 이유 |
---|---|
.asmdef에 대한 Define Constraint 제거 | Define Constraint를 제거하면 컴파일 및 스크립팅 파이프라인이 이 어셈블리를 더 이상 건너 뛰지 않습니다. Unity는 항상 이 어셈블리를 빌드하므로 Define Constraint의 충족 여부에 관계없이 컴파일러는 항상 그에 대한 레퍼런스를 확인할 수 있습니다. |
플랫폼 추가 | 플랫폼 추가는 기존 플랫폼 지원에 영향을 주지 않으므로 이전 버전과 호환됩니다. 이는 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 릴리스에 포함할 수도 있습니다.
Scenario | 이 변경 사항이 다른 소비자에 영향을 주지 않는 이유 |
---|---|
.asmdef 파일에서 참조된 어셈블리 및 어셈블리 정의 리스트 변경 | 다른 어셈블리를 참조하는 어셈블리는 다른 어셈블리의 자체 레퍼런스를 자동으로 참조하지 않지만, 명시적으로 나열해야 합니다. 따라서 어셈블리 정의 또는 어셈블리의 레퍼런스를 변경해도 다른 소비자에게는 영향을 미치지 않습니다. |
어셈블리 정의에서 Allow unsafe code 프로퍼티 변경 | 이 프로퍼티는 컴파일러가 안전하지 않은 수정자를 가진 코드를 컴파일할 수 있는지 여부를 제어합니다. 자체 플래그를 변경해도 공용 API는 변경되지 않습니다. |
어셈블리 정의에서 Override References 프로퍼티 변경 | 이 프로퍼티는 Unity가 이 어셈블리에 대한 컴파일러를 호출하는 방법을 제어하며, 결과 어셈블리의 소비자에게 아무 영향도 미치지 않습니다. 자체 플래그를 변경해도 공용 API는 변경되지 않습니다. |
패키지 매니페스트 파일(package.json
)은 패키지 자체에 대한 이름, 버전, 패키지 종속성 및 기타 메타데이터를 지정합니다.
이 섹션에서는 패키지 매니페스트 파일의 변경 사항과 패키지 버전에 미치는 영향에 대해 자세히 설명합니다.
이름 프로퍼티를 변경하는 것은 한 패키지를 제거하고 이름이 다른 새 패키지를 추가하는 것과 동일합니다(이 동작은 지원되지 않음). 업데이트를 릴리스하여 패키지 이름을 변경할 수는 없으며, 완전히 새로운 패키지로 릴리스해야 합니다. 기존 프로젝트 및 패키지가 이름을 동의어로 해석할 수 없으므로 이름 변경이 허용되지 않습니다.
프로젝트의 종속성은 변경해도, 그 자체로는 다른 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 |
릴리스 버전의 패키지 관리자, 빌드 파이프라인, 스크립팅 파이프라인 또는 에셋 데이터베이스에 특별한 영향을 미치지 않는 패키지 매니페스트 속성을 변경할 수 있습니다. 여기에는 description, category, keywords 또는 displayName 변경이 포함됩니다.
이러한 필드를 변경하면 변경 사항으로 인해 버그 수정 이상의 작업이 동반될 수 있습니다. 새 버전의 다른 변경 사항이 PATCH 릴리스가 아니라 새로운 MINOR 또는 MAJOR 릴리스를 필요로 하는지 항상 고려하십시오.
API에서 일부 기능을 제거하려면 먼저 지원 중단에 대한 내용이 포함된 MINOR 릴리스를 최소 한 번 릴리스하십시오. 이렇게 하면 사용자들에게 제거 계획에 대해 알리고 새 API로 원활하게 이동하도록 만들 수 있습니다. 그러고 나서 새 MAJOR 릴리스에서 해당 기능을 제거할 수 있습니다.
다른 개발자가 사용되지 않는 패키지에 경고 표시를 하고 프로젝트에서 Warnings as Errors가 활성화된 경우 사용되지 않는 패키지는 기술적으로 프로젝트를 중단시킬 수 있습니다. 이는 코드가 여전히 이전처럼 동작하기 때문에 실제 중단이 아닌 경우에도 마찬가지입니다.
이 경우 오류 경고를 수정할 방법을 선택할 수 있습니다(일반적인 타당성에 따라 내림차순 정렬).
#pragma warning
지시문에 API를 사용하는 코드를 래핑하여 경고를 끄십시오.