Skip to content

Commit 1f88135

Browse files
committed
Final pass internal-platform-api-versioning-deprecation-breaking-changes article
1 parent 590efff commit 1f88135

4 files changed

Lines changed: 165 additions & 67 deletions

File tree

‎src/components/List/__tests__/index.spec.ts‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,41 @@ describe('List (Astro)', () => {
162162
expect(lead?.textContent).toContain('Owner clarity matters.')
163163
})
164164
})
165+
166+
test('stacks lead and text vertically for the colored-marker-list variant', async () => {
167+
const List = (await import('@components/List/index.astro')).default
168+
169+
const renderedHtml = await container.renderToString(List, {
170+
props: {
171+
variant: 'colored-marker-list',
172+
items: [
173+
{
174+
lead: 'Compatibility adapters',
175+
text: 'Provide a translation layer during migration.',
176+
color: 'bg-success',
177+
},
178+
],
179+
},
180+
})
181+
182+
await withJsdomEnvironment(async ({ window }) => {
183+
window.document.body.innerHTML = renderedHtml
184+
185+
const listItem = window.document.querySelector('ul li')
186+
const marker = window.document.querySelector('ul li > span:first-child')
187+
const contentWrapper = window.document.querySelector('ul li > div')
188+
const lead = window.document.querySelector('ul li em')
189+
const text = window.document.querySelector('ul li div > span')
190+
191+
expect(listItem).toBeTruthy()
192+
expect(marker?.className).toContain('bg-success')
193+
expect(contentWrapper?.className).toContain('flex-col')
194+
expect(contentWrapper?.className).not.toContain('sm:flex-row')
195+
expect(contentWrapper?.className).toContain('items-start')
196+
expect(contentWrapper?.className).toContain('gap-1')
197+
expect(lead?.className).not.toContain('sm:mr-2')
198+
expect(lead?.textContent).toContain('Compatibility adapters')
199+
expect(text?.textContent).toContain('Provide a translation layer during migration.')
200+
})
201+
})
165202
})

‎src/components/List/layouts/ColoredMarkerList.astro‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const { items, classes, size = 2 }: Props = Astro.props
1919
2020
const ulClass = ["list-none pl-0 text-content mt-4 mb-2 space-y-2", classes?.ul]
2121
const liClass = ["flex items-start", classes?.li]
22-
const emClass = ["mr-0 sm:mr-2 not-italic font-bold", classes?.em]
22+
const emClass = ["not-italic font-bold", classes?.em]
2323
const markerSizeInRem = `${size * 0.25}rem`
2424
const markerStyle = `width: ${markerSizeInRem}; height: ${markerSizeInRem};`
2525
const iconClass = ["rounded-full mt-2 mr-3 shrink-0", classes?.icon]
@@ -31,7 +31,7 @@ const textClass = classes?.text ? [classes.text] : []
3131
items.map((item) => (
3232
<li class:list={liClass}>
3333
<span class:list={[iconClass, item.color]} style={markerStyle} />
34-
<div class="flex flex-col sm:flex-row sm:items-start">
34+
<div class="flex min-w-0 flex-col items-start gap-1">
3535
{item.lead && <em class:list={emClass} set:html={item.lead}></em>}
3636
<span class:list={textClass} set:html={item.text}></span>
3737
</div>

‎src/content/articles/internal-platform-api-versioning-deprecation-breaking-changes/index.mdx‎

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Last week, a platform team I know shipped what they called a "small cleanup" to
1313

1414
Monday morning, 40 CI pipelines failed. Three teams scrambled to update their deployment scripts. A critical security hotfix got blocked because the team couldn't deploy. The platform team spent the entire week doing emergency migrations instead of planned work. And the trust they'd built over the previous year? Gone.
1515

16-
This happens constantly with internal APIs. There's a temptation to treat them differently than external ones: "we can just tell people to update," "everyone's in the same building," "we'll coordinate in Slack." But internal APIs deserve __more__ versioning discipline than external ones, not less.
16+
This happens constantly with internal APIs. There's a temptation to treat them differently than external ones: "we can just tell people to update," "everyone's in the same building," "we'll coordinate in Slack." <Highlighter>But internal APIs deserve _more_ versioning discipline than external ones, not less.</Highlighter>
1717

1818
Internal customers are captive customers. They can't switch to a competitor's platform. This makes breaking their workflows worse, not better - they have no recourse except escalating to leadership or building workarounds that create tech debt.
1919

@@ -26,7 +26,8 @@ __Will existing client code still work?__ That's the question that determines wh
2626
Some changes are obviously breaking - removing endpoints, changing HTTP methods, adding required fields. These require full deprecation process, no exceptions. Other changes are obviously safe - adding optional fields, new endpoints, loosening validation. The table below draws the line.
2727

2828
<Table
29-
variant="vertical-column-delineation-table"
29+
variant="criteria-highlight-table"
30+
fullWidth={false}
3031
content={{
3132
figure: "Breaking vs safe changes.",
3233
thead: {
@@ -102,7 +103,7 @@ Some changes are obviously breaking - removing endpoints, changing HTTP methods,
102103
The tricky cases fall in between - changes that are technically compatible but break consumer assumptions:
103104

104105
<List
105-
variant="check-icons-list"
106+
variant="side-by-side-list"
106107
items={[
107108
{
108109
lead: "Error code changes",
@@ -114,7 +115,7 @@ The tricky cases fall in between - changes that are technically compatible but b
114115
},
115116
{
116117
lead: "Semantic changes",
117-
text: "Making `count` include deleted items when it previously didn't - breaking even though the field name stays the same",
118+
text: 'Making <span class="font-mono">count</span> include deleted items when it previously didn\'t - breaking even though the field name stays the same',
118119
},
119120
]}
120121
/>
@@ -128,7 +129,10 @@ When you're unsure whether a change breaks existing clients, treat it as breakin
128129
Once you've identified a breaking change, follow a structured process that gives consumers time to adapt. Skipping steps is how you end up with 40 broken pipelines and a week of emergency migrations.
129130

130131
<List
131-
variant="check-icons-list"
132+
variant="chevron-list"
133+
classes={{
134+
wrapper: "sm:ml-6 sm:mr-12 mb-6",
135+
}}
132136
items={[
133137
{
134138
lead: "Step 1: Identify affected consumers.",
@@ -158,7 +162,11 @@ Once you've identified a breaking change, follow a structured process that gives
158162
The key insight is that urgency should escalate as the deadline approaches. Early communication is broad and informational - changelog updates, Slack posts, email announcements. As sunset nears, communication becomes targeted and direct.
159163

160164
<Table
161-
variant="vertical-column-delineation-table"
165+
variant="grid-and-accent-header-table"
166+
fullWidth={false}
167+
classes={{
168+
tbody: '!text-content',
169+
}}
162170
content={{
163171
figure: "Deprecation communication timeline.",
164172
thead: {
@@ -228,8 +236,6 @@ A good migration guide answers questions in the order developers ask them. Start
228236

229237
Tier your support by consumer need. Most migrations should be self-service with docs and validators. For stuck teams, offer office hours and PR reviews. For critical consumers or complex cases, the platform team writes the migration PRs directly.
230238

231-
Automation pays for itself quickly. A codemod that handles 80% of cases automatically and flags the remaining 20% for manual review dramatically reduces the burden on consuming teams. Compatibility adapters that translate v1 requests to v2 internally buy time for slow migrators without extending your maintenance window.
232-
233239
<Download
234240
resource="internal-platform-api-versioning-deprecation-breaking-changes"
235241
title="Download the API Versioning Guide"
@@ -250,6 +256,8 @@ Automation pays for itself quickly. A codemod that handles 80% of cases automati
250256
]}
251257
/>
252258

259+
Automation pays for itself quickly. A codemod that handles 80% of cases automatically and flags the remaining 20% for manual review dramatically reduces the burden on consuming teams. Compatibility adapters that translate v1 requests to v2 internally buy time for slow migrators without extending your maintenance window.
260+
253261
## The Invisible Success
254262

255263
Good API versioning is invisible. Consumers barely notice migrations because they're well-communicated, well-supported, and well-timed. The new version shows up with deprecation warnings months in advance. The migration guide makes the change trivial. By the time sunset arrives, everyone's already moved on.

0 commit comments

Comments
 (0)