Skip to content

Commit 100c9cf

Browse files
authored
ci: add styled-components migration report (#6158)
1 parent 0e04210 commit 100c9cf

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed

.github/workflows/migration-status.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,21 @@ on:
55
workflow_dispatch:
66

77
jobs:
8+
styled-components:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
12+
- name: Set up Node.js
13+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
14+
with:
15+
node-version: 22
16+
cache: 'npm'
17+
- name: Install dependencies
18+
run: npm ci
19+
- name: Run migration script
20+
run: |
21+
node --experimental-strip-types script/styled-components-migration-status.mts >> $GITHUB_STEP_SUMMARY
22+
823
vitest:
924
runs-on: ubuntu-latest
1025
steps:
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import path from 'node:path'
2+
import fs from 'node:fs'
3+
import glob from 'fast-glob'
4+
5+
const directory = path.resolve(import.meta.dirname, '..')
6+
const matches = glob
7+
.sync('packages/react/src/**/*.{ts,tsx}', {
8+
cwd: directory,
9+
ignore: [
10+
'**/e2e/**',
11+
'**/node_modules/**',
12+
'**/.playwright/**',
13+
'**/lib/**',
14+
'**/dist/**',
15+
'**/lib-esm/**',
16+
'**/storybook-static/**',
17+
'**/.next/**',
18+
'**/*.test.{ts,tsx}',
19+
'**/*.types.test.{ts,tsx}',
20+
'**/*.module.css.d.ts',
21+
],
22+
})
23+
.map(match => {
24+
const filepath = path.resolve(directory, match)
25+
const stats = fs.statSync(filepath)
26+
return {
27+
filepath,
28+
size: stats.size,
29+
}
30+
})
31+
.sort((a, b) => {
32+
return b.size - a.size
33+
})
34+
35+
const migrated = matches.filter(({filepath}) => {
36+
const contents = fs.readFileSync(filepath, 'utf8')
37+
return !hasStyledComponents(contents)
38+
})
39+
40+
const notMigrated = matches.filter(({filepath}) => {
41+
const contents = fs.readFileSync(filepath, 'utf8')
42+
return hasStyledComponents(contents)
43+
})
44+
45+
let totalSize = 0
46+
47+
for (const {size} of matches) {
48+
totalSize += size
49+
}
50+
51+
let migratedSize = 0
52+
53+
for (const {size} of migrated) {
54+
migratedSize += size
55+
}
56+
57+
console.log(`
58+
# styled-components Migration
59+
60+
This report tracks our status migrating files from styled-components to CSS Modules.
61+
62+
## Status
63+
64+
**Status by file count**
65+
66+
![Status by file count](https://geps.dev/progress/${Math.floor((migrated.length / matches.length) * 100)})
67+
68+
**Status by file size**
69+
70+
![Status by file size](https://geps.dev/progress/${Math.floor((migratedSize / totalSize) * 100)})
71+
`)
72+
73+
console.log(`
74+
## Not Migrated (${notMigrated.length})
75+
76+
| Filepath | Size (kB) |
77+
| :------- | :-------- |`)
78+
79+
for (const {filepath, size} of notMigrated) {
80+
const relativePath = path.relative(directory, filepath)
81+
const link = `[\`${relativePath}\`](https://github.com/primer/react/blob/main/${relativePath})`
82+
console.log(`| ${link} | ${round(size / 1024)}kB |`)
83+
}
84+
85+
console.log(`## Migrated (${migrated.length})
86+
87+
There are ${migrated.length} files that do not include styled-components in Primer React.
88+
89+
<details>
90+
<summary>All files</summary>
91+
92+
| Filepath | Size (kB) |
93+
| :------- | :-------- |`)
94+
95+
for (const {filepath, size} of notMigrated) {
96+
const relativePath = path.relative(directory, filepath)
97+
const link = `[\`${relativePath}\`](https://github.com/primer/react/blob/main/${relativePath})`
98+
console.log(`| ${link} | ${round(size / 1024)}kB |`)
99+
}
100+
101+
console.log(`\n</details>`)
102+
103+
function round(value: number): number {
104+
return Math.round((value + Number.EPSILON) * 100) / 100
105+
}
106+
107+
function hasStyledComponents(contents: string): boolean {
108+
if (contents.match(/styled-components/)) {
109+
return true
110+
}
111+
112+
if (contents.match(/SxProp/)) {
113+
return true
114+
}
115+
116+
if (contents.match(/Box/)) {
117+
return true
118+
}
119+
120+
if (contents.match(/BoxWithFallback/)) {
121+
return true
122+
}
123+
124+
if (contents.match(/toggleSxComponent/)) {
125+
return true
126+
}
127+
128+
return false
129+
}

0 commit comments

Comments
 (0)