Skip to content

Commit b93457c

Browse files
committed
Rewrote the breaking changes policy to clarify many points
1 parent a780806 commit b93457c

5 files changed

Lines changed: 379 additions & 49 deletions

File tree

Lines changed: 376 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,376 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<topic id="9c4a6074-9d84-4488-9565-50ecb5049ffe" revisionNumber="1">
3+
<developerConceptualDocument
4+
xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5"
5+
xmlns:xlink="http://www.w3.org/1999/xlink">
6+
7+
<introduction>
8+
<para>
9+
To ensure the long-term reliability of both the SDK and applications which rely on the SDK, the following
10+
policy is enforced for each release of the SDK.
11+
</para>
12+
</introduction>
13+
14+
<section>
15+
<title>Scope</title>
16+
<content>
17+
<para>
18+
This breaking changes policy is only enforced for libraries which explicitly state it as their governing
19+
policy. In certain cases, a library governed by this breaking changes policy may depend on a library which is
20+
not governed by the same policy, or which does not provide any breaking changes policy. In those cases, a
21+
best-effort is provided to ensure changes to the dependency do not affect dependent code. For maximum
22+
long-term compatibility, dependent applications and libraries should treat dependencies not governed by this
23+
policy in accordance with the rules described for preliminary features, even though they are not marked as
24+
such within the documentation.
25+
</para>
26+
</content>
27+
</section>
28+
29+
<section>
30+
<title>Definitions</title>
31+
<content>
32+
<definitionTable>
33+
<definedTerm>Binary compatible</definedTerm>
34+
<definition>
35+
<para>
36+
An assembly <literal>x</literal> is <newTerm>binary compatible</newTerm> with an assembly
37+
<literal>y</literal> if replacing <literal>y</literal> with <literal>x</literal> will not cause an
38+
application previously compiled against <literal>y</literal> to stop functioning at runtime.
39+
</para>
40+
<alert class="note">
41+
<para>
42+
Binary compatibility is transitive, but not necessarily symmetric. Specifically, the assembly
43+
<literal>x</literal> may include new APIs that are not included in <literal>y</literal>; since the
44+
application compiled against <literal>y</literal> is clearly not using any of these new APIs, they do
45+
not prevent <literal>x</literal> from being binary compatible with <literal>y</literal>.
46+
</para>
47+
</alert>
48+
</definition>
49+
<definedTerm>Source compatible</definedTerm>
50+
<definition>
51+
<para>
52+
An assembly <literal>x</literal> is <newTerm>source compatible</newTerm> with an assembly
53+
<literal>y</literal> if replacing <literal>y</literal> with <literal>x</literal> will not cause an
54+
application previously compiled against <literal>y</literal> to encounter build errors when it is
55+
recompiled.
56+
</para>
57+
</definition>
58+
<definedTerm>Version</definedTerm>
59+
<definition>
60+
<para>
61+
A <newTerm>version</newTerm> is comprised of four parts, with the following form.
62+
</para>
63+
<quote>
64+
major.minor.patch.revision
65+
</quote>
66+
<para>
67+
Each part of the version number is an integer in the range 0-65535, inclusive.
68+
</para>
69+
</definition>
70+
<definedTerm>Major release</definedTerm>
71+
<definition>
72+
<para>
73+
A <newTerm>major release</newTerm> is a release which increments the "major" part of the version.
74+
</para>
75+
</definition>
76+
<definedTerm>Minor release</definedTerm>
77+
<definition>
78+
<para>
79+
A <newTerm>minor release</newTerm> is a release which increments the "minor" part of the version, but does
80+
not change the "major" part.
81+
</para>
82+
</definition>
83+
<definedTerm>Patch release</definedTerm>
84+
<definition>
85+
<para>
86+
A <newTerm>patch release</newTerm> is a release which increments the "patch" and/or "revision" parts of
87+
the version, but does not change either the "major" or "minor" parts.
88+
</para>
89+
</definition>
90+
<definedTerm>Preliminary feature</definedTerm>
91+
<definition>
92+
<para>
93+
A <newTerm>preliminary feature</newTerm> is a special designation for a publicly-exposed API in the
94+
library which is exempted from certain rules within the breaking changes policy for the purpose of
95+
improving the agility of library development without compromising reliability for business users primarily
96+
interested in API stability.
97+
</para>
98+
</definition>
99+
<definedTerm>Stable feature</definedTerm>
100+
<definition>
101+
<para>
102+
A <newTerm>stable feature</newTerm> is any type or member within the publicly-exposed API of the library
103+
which is not designated as a preliminary feature.
104+
</para>
105+
</definition>
106+
</definitionTable>
107+
</content>
108+
</section>
109+
110+
<section>
111+
<title>Major and Minor Releases</title>
112+
<content>
113+
<para>
114+
Major and minor releases do not preserve binary compatibility. For dependent assemblies which use a strong
115+
name, the binary incompatibility is enforced by a change to the strong name of the assembly. Major and minor
116+
releases update the value of the
117+
<codeEntityReference>T:System.Reflection.AssemblyVersionAttribute</codeEntityReference> attribute, which
118+
always changes the strong name of the assembly.
119+
</para>
120+
<para>
121+
Minor releases are typically used for the following.
122+
</para>
123+
<list class="bullet">
124+
<listItem>
125+
<para>
126+
Promotion of features previously marked as preliminary to stable features of the API.
127+
</para>
128+
</listItem>
129+
<listItem>
130+
<para>
131+
Changes to stable features of the API where necessary for the purpose of introducing new functionality,
132+
addressing performance concerns, or correcting bugs in the library.
133+
</para>
134+
</listItem>
135+
</list>
136+
<para>
137+
Major releases are typically used for substantial refactoring or other alterations in order to meet the needs
138+
of a broader user base, or for the purpose of improving overall usability or flexibility of the library.
139+
</para>
140+
</content>
141+
</section>
142+
143+
<section>
144+
<title>Patch Releases</title>
145+
<content>
146+
<para>
147+
Patch releases preserve binary compatibility for all features of the library which are not marked preliminary.
148+
This includes but is not limited to the following guarantees.
149+
</para>
150+
<list class="bullet">
151+
<listItem>
152+
<para>
153+
Patch releases never change the strong name of the assembly. This means a patch release updates the
154+
<codeEntityReference>T:System.Reflection.AssemblyFileVersionAttribute</codeEntityReference> and
155+
<codeEntityReference>T:System.Reflection.AssemblyInformationalVersionAttribute</codeEntityReference>
156+
values, but does not change the
157+
<codeEntityReference>T:System.Reflection.AssemblyVersionAttribute</codeEntityReference> value.
158+
</para>
159+
</listItem>
160+
<listItem>
161+
<para>
162+
Patch releases do not change the runtime signature of any type or method which is not marked preliminary.
163+
The runtime signatures include type and method names
164+
</para>
165+
</listItem>
166+
<listItem>
167+
<para>
168+
Patch releases may only add elements to the public API of the assembly if they are marked preliminary.
169+
This rule ensures that patch releases preserve symmetric binary compatibility for applications and
170+
libraries which avoid the use of any feature marked as preliminary.
171+
</para>
172+
</listItem>
173+
</list>
174+
</content>
175+
<sections>
176+
<section>
177+
<title>Revision-Only Releases</title>
178+
<content>
179+
<para>
180+
In some cases, a release will only update the "revision" part of the version. With regard to this breaking
181+
changes policy, these releases are equivalent to patch releases. In practice, revision-only releases are
182+
typically reserved for correcting a previous patch or revision release which violated the breaking changes
183+
policy, or for correcting a bug which was introduced in the current patch cycle without making changes to
184+
the public API of the assembly.
185+
</para>
186+
</content>
187+
</section>
188+
189+
<section>
190+
<title>Exceptions</title>
191+
<content>
192+
<para>
193+
Certain exceptions apply to the binary compatibility requirement of patch releases. These include the
194+
following.
195+
</para>
196+
<list class="bullet">
197+
<listItem>
198+
<para>
199+
All implementation details, i.e. code which is not part of the public API of the assembly, is allowed
200+
to change during a patch release. Code using the reflection APIs to manipulate any aspect of the
201+
library may observe breaking changes at runtime as a result of changes to implementation details.
202+
</para>
203+
</listItem>
204+
<listItem>
205+
<para>
206+
All types and members which are marked as preliminary are exempted from the binary compatibility
207+
requirement, subject to the rules of
208+
<link xlink:href="#PreliminaryFeatures">preliminary features</link>.
209+
</para>
210+
</listItem>
211+
</list>
212+
</content>
213+
</section>
214+
</sections>
215+
</section>
216+
217+
<section>
218+
<title>Summary of Release Characteristics</title>
219+
<content>
220+
<para>The following table summarizes the intent of various releases.</para>
221+
<table>
222+
<tableHeader>
223+
<row>
224+
<entry>
225+
<para>Release Type</para>
226+
</entry>
227+
<entry>
228+
<para>Binary Compatibility</para>
229+
</entry>
230+
<entry>
231+
<para>Source Compatibility</para>
232+
</entry>
233+
<entry>
234+
<para>New Features</para>
235+
</entry>
236+
</row>
237+
</tableHeader>
238+
<row>
239+
<entry>
240+
<para>Major</para>
241+
</entry>
242+
<entry>
243+
<para>Unrestricted</para>
244+
</entry>
245+
<entry>
246+
<para>Unrestricted</para>
247+
</entry>
248+
<entry>
249+
<para>Unrestricted</para>
250+
</entry>
251+
</row>
252+
<row>
253+
<entry>
254+
<para>Minor</para>
255+
</entry>
256+
<entry>
257+
<para>
258+
Unrestricted<superscript>1</superscript>
259+
</para>
260+
</entry>
261+
<entry>
262+
<para>
263+
Relaxed Preferred<superscript>2</superscript>
264+
</para>
265+
</entry>
266+
<entry>
267+
<para>Unrestricted</para>
268+
</entry>
269+
</row>
270+
<row>
271+
<entry>
272+
<para>Patch</para>
273+
</entry>
274+
<entry>
275+
<para>Transitive: Required</para>
276+
<para>
277+
Symmetric: Preferred<superscript>3</superscript>
278+
</para>
279+
</entry>
280+
<entry>
281+
<para>
282+
Strict Preferred<superscript>4</superscript>
283+
</para>
284+
</entry>
285+
<entry>
286+
<para>
287+
Preliminary Only<superscript>3</superscript>
288+
</para>
289+
</entry>
290+
</row>
291+
</table>
292+
<list class="ordered">
293+
<listItem>
294+
<para>
295+
Since minor releases result in a change to the strong name of the assembly, binary compatibility is never
296+
preserved for strong-named applications or libraries which reference the assembly. These cases are rarely
297+
problematic due to the runtime's support for side-by-side loading of multiple versions of the same
298+
assembly.
299+
</para>
300+
</listItem>
301+
<listItem>
302+
<para>
303+
To minimize the cost of updating an application to use a new minor release of the library,
304+
source-incompatible changes should only be introduced when necessary to support a substantial improvement
305+
to the library. Eligible improvements include but are not limited to resource utilization, runtime
306+
performance, or new feature offerings.
307+
</para>
308+
</listItem>
309+
<listItem>
310+
<para>
311+
Restricting the introduction of features in a patch release to preliminary features provides applications
312+
the ability to leverage symmetric binary compatibility for maximum runtime reliability, by avoiding the
313+
use of any feature which is marked as preliminary.
314+
</para>
315+
</listItem>
316+
<listItem>
317+
<para>
318+
Changes to preliminary features may result in source code incompatibilities due to situations including
319+
but not limited to conflicts due to ambiguous names. In addition, changing the name of a required
320+
parameter for the purpose of correcting a spelling error or avoiding confusion is generally allowed due to
321+
a very low risk of actually causing compilation problems for users. Changes to the names of optional
322+
parameters, on the other hand, should be avoided whenever possible as users are likely to be referencing
323+
them directly by name.
324+
</para>
325+
</listItem>
326+
</list>
327+
</content>
328+
</section>
329+
330+
<section address="PreliminaryFeatures">
331+
<title>Preliminary Features</title>
332+
<content>
333+
<para>
334+
This library may include types and/or members which are designated as preliminary features. The preliminary
335+
feature designation is indicated by a clear note at the top of the associated documentation page. In the
336+
library source code, preliminary features are indicated by including the
337+
<codeInline>&lt;preliminary/&gt;</codeInline> element to the XML documentation comment for the feature. While
338+
preliminary features are much more "flexible" during the release cycle of the library, certain rules do apply
339+
in order to ensure the stronger rules provided for stable features will not be violated by a change to a
340+
preliminary feature. The following list includes examples of these rules, but other rules may be imposed by
341+
basic logical constraints. The API elements referred to in the following list are assumed to be restricted to
342+
the publicly-exposed API of the library. The terms "member" and "members" refer to any method, property, or
343+
event.
344+
</para>
345+
<list class="bullet">
346+
<listItem>
347+
<para>
348+
A member may only refer to a preliminary type in its signature if it is also marked preliminary.
349+
</para>
350+
</listItem>
351+
<listItem>
352+
<para>
353+
An interface may only include a preliminary member if it is also marked preliminary.
354+
</para>
355+
</listItem>
356+
<listItem>
357+
<para>
358+
An interface may only extend a preliminary interface if it is also marked preliminary.
359+
</para>
360+
</listItem>
361+
<listItem>
362+
<para>
363+
A class may only include a preliminary <codeInline>abstract</codeInline> member if either it is also
364+
marked preliminary, or all constructors for the class are marked <codeInline>internal</codeInline>. This
365+
restriction also applies to <codeInline>abstract</codeInline> classes which do not implement an
366+
<codeInline>abstract</codeInline> member declared in a base class.
367+
</para>
368+
</listItem>
369+
</list>
370+
</content>
371+
</section>
372+
373+
<relatedTopics>
374+
</relatedTopics>
375+
</developerConceptualDocument>
376+
</topic>

0 commit comments

Comments
 (0)