Skip to content

Commit b2cab6e

Browse files
authored
Merge pull request #17773 from ethereum/staging
Deploy v10.27.0
2 parents 7f1b142 + 90b8f4b commit b2cab6e

File tree

326 files changed

+11246
-2605
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

326 files changed

+11246
-2605
lines changed

.all-contributorsrc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14058,6 +14058,33 @@
1405814058
"contributions": [
1405914059
"tool"
1406014060
]
14061+
},
14062+
{
14063+
"login": "jgresham",
14064+
"name": "Johns Gresham",
14065+
"avatar_url": "https://avatars.githubusercontent.com/u/3721291?v=4",
14066+
"profile": "http://jgresham.xyz",
14067+
"contributions": [
14068+
"maintenance"
14069+
]
14070+
},
14071+
{
14072+
"login": "Dragoon0x",
14073+
"name": "Dragoon",
14074+
"avatar_url": "https://avatars.githubusercontent.com/u/255907778?v=4",
14075+
"profile": "https://github.com/Dragoon0x",
14076+
"contributions": [
14077+
"tool"
14078+
]
14079+
},
14080+
{
14081+
"login": "0xMushow",
14082+
"name": "0xMushow",
14083+
"avatar_url": "https://avatars.githubusercontent.com/u/105550256?v=4",
14084+
"profile": "https://mushow.uk/",
14085+
"contributions": [
14086+
"maintenance"
14087+
]
1406114088
}
1406214089
],
1406314090
"contributorsPerLine": 7,
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# Plan: Migrate GitHub Contributors to Data Layer
2+
3+
## Summary
4+
5+
Replace the current per-request GitHub API fetching with pre-computed data stored in Netlify Blobs via the existing data-layer infrastructure. This eliminates ~173K-347K API calls per build.
6+
7+
## Files to Delete (Previous Implementation)
8+
9+
- `src/scripts/github/getGitHubContributors.ts`
10+
- `src/data/github/contributors.json`
11+
- `src/data/github/app-contributors.json`
12+
- `.github/workflows/get-github-contributors.yml`
13+
14+
## Files to Create
15+
16+
### 1. `src/data-layer/fetchers/fetchGitHubContributors.ts`
17+
18+
New fetcher that:
19+
- Fetches contributors for all content files from GitHub API
20+
- Fetches contributors for all app pages
21+
- Returns `GitHubContributorsData` type
22+
- Follows existing fetcher patterns (logging, error handling, rate limiting)
23+
24+
```typescript
25+
export const FETCH_GITHUB_CONTRIBUTORS_TASK_ID = "fetch-github-contributors"
26+
27+
export async function fetchGitHubContributors(): Promise<GitHubContributorsData> {
28+
// Fetch all content file contributors
29+
// Fetch all app page contributors
30+
// Return combined data
31+
}
32+
```
33+
34+
### 2. `src/data-layer/mocks/fetch-github-contributors.json`
35+
36+
Mock data for local development with `USE_MOCK_DATA=true`.
37+
38+
## Files to Modify
39+
40+
### 1. `src/lib/types.ts`
41+
42+
Add type definition:
43+
```typescript
44+
export type GitHubContributorsData = {
45+
content: Record<string, FileContributor[]> // slug -> contributors
46+
appPages: Record<string, FileContributor[]> // pagePath -> contributors
47+
generatedAt: string
48+
}
49+
```
50+
51+
### 2. `src/data-layer/tasks.ts`
52+
53+
- Add import for `fetchGitHubContributors`
54+
- Add key: `GITHUB_CONTRIBUTORS: "fetch-github-contributors"`
55+
- Add to `DAILY` array: `[KEYS.GITHUB_CONTRIBUTORS, fetchGitHubContributors]`
56+
57+
### 3. `src/data-layer/index.ts`
58+
59+
Add getter:
60+
```typescript
61+
export const getGitHubContributors = () =>
62+
get<GitHubContributorsData>(KEYS.GITHUB_CONTRIBUTORS)
63+
```
64+
65+
### 4. `src/lib/data/index.ts`
66+
67+
Add cached wrapper:
68+
```typescript
69+
export const getGitHubContributors = createCachedGetter(
70+
dataLayer.getGitHubContributors,
71+
["github-contributors"],
72+
CACHE_REVALIDATE_DAY
73+
)
74+
```
75+
76+
### 5. `src/lib/utils/gh.ts`
77+
78+
- Remove the static JSON imports I added earlier
79+
- Remove `getStaticContentContributors` and `getStaticAppContributors`
80+
- Keep `fetchAndCacheGitHubContributors` as fallback for dev/new files
81+
82+
### 6. `src/lib/utils/contributors.ts`
83+
84+
Update to use data-layer:
85+
```typescript
86+
import { getGitHubContributors } from "@/lib/data"
87+
88+
export const getMarkdownFileContributorInfo = async (...) => {
89+
const contributorsData = await getGitHubContributors()
90+
let gitHubContributors = contributorsData?.content[slug] || null
91+
92+
// Fallback to API if not in data layer (new files during dev)
93+
if (!gitHubContributors) {
94+
gitHubContributors = await fetchAndCacheGitHubContributors(...)
95+
}
96+
// ... rest unchanged
97+
}
98+
99+
export const getAppPageContributorInfo = async (...) => {
100+
const contributorsData = await getGitHubContributors()
101+
let uniqueGitHubContributors = contributorsData?.appPages[pagePath] || null
102+
103+
// Fallback to API if not in data layer
104+
if (!uniqueGitHubContributors) {
105+
// ... existing API fetch logic
106+
}
107+
// ... rest unchanged
108+
}
109+
```
110+
111+
## Data Flow
112+
113+
```
114+
Trigger.dev (daily)
115+
116+
fetchGitHubContributors() - fetches from GitHub API
117+
118+
set(KEYS.GITHUB_CONTRIBUTORS, data) - stores in Netlify Blobs
119+
120+
Page render calls getGitHubContributors()
121+
122+
unstable_cache + React cache (request dedup)
123+
124+
storage.get() - retrieves from Netlify Blobs
125+
126+
contributors.ts uses data (zero API calls)
127+
```
128+
129+
## Implementation Order
130+
131+
1. Delete previous implementation files
132+
2. Add `GitHubContributorsData` type to `src/lib/types.ts`
133+
3. Create `src/data-layer/fetchers/fetchGitHubContributors.ts`
134+
4. Create `src/data-layer/mocks/fetch-github-contributors.json`
135+
5. Update `src/data-layer/tasks.ts` (key + import + DAILY registration)
136+
6. Update `src/data-layer/index.ts` (add getter)
137+
7. Update `src/lib/data/index.ts` (add cached wrapper)
138+
8. Update `src/lib/utils/gh.ts` (remove static imports/functions)
139+
9. Update `src/lib/utils/contributors.ts` (use data-layer)
140+
10. Run `pnpm lint:fix` and `npx tsc --noEmit`
141+
142+
## Notes
143+
144+
- **No filesystem access** in Trigger.dev - use GitHub Contents API to list files
145+
- Rate limiting: Use delays between requests (100-500ms)
146+
- App pages list: Predefined static list (changes infrequently)
147+
- Content files: Use GitHub API `GET /repos/{owner}/{repo}/contents/{path}` to recursively list `public/content/`
148+
149+
## GitHub API for File Discovery
150+
151+
```typescript
152+
// List directory contents recursively
153+
async function listContentFiles(path = "public/content"): Promise<string[]> {
154+
const url = `https://api.github.com/repos/ethereum/ethereum-org-website/contents/${path}`
155+
const response = await fetch(url, {
156+
headers: { Authorization: `token ${token}` }
157+
})
158+
const items = await response.json()
159+
160+
const slugs: string[] = []
161+
for (const item of items) {
162+
if (item.type === "dir" && item.name !== "translations") {
163+
// Recursively list subdirectories
164+
slugs.push(...await listContentFiles(item.path))
165+
} else if (item.name === "index.md") {
166+
// Found a content file, extract slug
167+
slugs.push(path.replace("public/content/", ""))
168+
}
169+
}
170+
return slugs
171+
}
172+
```

.github/workflows/claude-review-translations.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,21 @@ jobs:
5252
github.event_name == 'issue_comment' &&
5353
contains(github.event.comment.body, '@claude') &&
5454
contains(github.event.comment.body, '/review-translations') &&
55-
contains(fromJSON('["minimalsm","pettinarip","wackerow","nloureiro","konopkja"]'), github.event.comment.user.login) &&
55+
contains(fromJSON('["minimalsm","pettinarip","wackerow","nloureiro","konopkja","mnelsonBT","lukassim"]'), github.event.comment.user.login) &&
5656
github.event.issue.pull_request
5757
) ||
5858
(
5959
github.event_name == 'pull_request_review_comment' &&
6060
contains(github.event.comment.body, '@claude') &&
6161
contains(github.event.comment.body, '/review-translations') &&
62-
contains(fromJSON('["minimalsm","pettinarip","wackerow","nloureiro","konopkja"]'), github.event.comment.user.login)
62+
contains(fromJSON('["minimalsm","pettinarip","wackerow","nloureiro","konopkja","mnelsonBT","lukassim"]'), github.event.comment.user.login)
6363
) ||
6464
(
6565
github.event_name == 'pull_request' &&
6666
startsWith(github.event.pull_request.title, 'i18n:') &&
6767
startsWith(github.event.pull_request.head.ref, 'i18n/') &&
6868
github.event.pull_request.head.repo.full_name == github.repository &&
69-
contains(fromJSON('["minimalsm","pettinarip","wackerow","nloureiro","konopkja"]'), github.event.pull_request.user.login)
69+
contains(fromJSON('["minimalsm","pettinarip","wackerow","nloureiro","konopkja","mnelsonBT","lukassim"]'), github.event.pull_request.user.login)
7070
)
7171
runs-on: ubuntu-latest
7272
permissions:

.github/workflows/claude.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,25 @@ jobs:
1818
github.event_name == 'issue_comment' &&
1919
contains(github.event.comment.body, '@claude') &&
2020
!contains(github.event.comment.body, '/review-translations') &&
21-
contains(fromJSON('["minimalsm","pettinarip","wackerow","nloureiro","konopkja"]'), github.event.comment.user.login)
21+
contains(fromJSON('["minimalsm","pettinarip","wackerow","nloureiro","konopkja","mnelsonBT","lukassim"]'), github.event.comment.user.login)
2222
) ||
2323
(
2424
github.event_name == 'pull_request_review_comment' &&
2525
contains(github.event.comment.body, '@claude') &&
2626
!contains(github.event.comment.body, '/review-translations') &&
27-
contains(fromJSON('["minimalsm","pettinarip","wackerow","nloureiro","konopkja"]'), github.event.comment.user.login)
27+
contains(fromJSON('["minimalsm","pettinarip","wackerow","nloureiro","konopkja","mnelsonBT","lukassim"]'), github.event.comment.user.login)
2828
) ||
2929
(
3030
github.event_name == 'pull_request_review' &&
3131
contains(github.event.review.body, '@claude') &&
3232
!contains(github.event.review.body, '/review-translations') &&
33-
contains(fromJSON('["minimalsm","pettinarip","wackerow","nloureiro","konopkja"]'), github.event.review.user.login)
33+
contains(fromJSON('["minimalsm","pettinarip","wackerow","nloureiro","konopkja","mnelsonBT","lukassim"]'), github.event.review.user.login)
3434
) ||
3535
(
3636
github.event_name == 'issues' &&
3737
contains(github.event.issue.body, '@claude') &&
3838
!contains(github.event.issue.body, '/review-translations') &&
39-
contains(fromJSON('["minimalsm","pettinarip","wackerow","nloureiro","konopkja"]'), github.event.issue.user.login)
39+
contains(fromJSON('["minimalsm","pettinarip","wackerow","nloureiro","konopkja","mnelsonBT","lukassim"]'), github.event.issue.user.login)
4040
)
4141
runs-on: ubuntu-latest
4242
permissions:

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2183,6 +2183,11 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
21832183
<td align="center" valign="top" width="14.28%"><a href="https://github.com/khawlahssn"><img src="https://avatars.githubusercontent.com/u/69622217?v=4?s=100" width="100px;" alt="Khawla"/><br /><sub><b>Khawla</b></sub></a><br /><a href="#tool-khawlahssn" title="Tools">🔧</a></td>
21842184
<td align="center" valign="top" width="14.28%"><a href="https://github.com/nicolasbalao"><img src="https://avatars.githubusercontent.com/u/61119970?v=4?s=100" width="100px;" alt="Nicolas Balao"/><br /><sub><b>Nicolas Balao</b></sub></a><br /><a href="https://github.com/ethereum/ethereum-org-website/issues?q=author%3Anicolasbalao" title="Bug reports">🐛</a></td>
21852185
<td align="center" valign="top" width="14.28%"><a href="http://neal.is"><img src="https://avatars.githubusercontent.com/u/3241395?v=4?s=100" width="100px;" alt="Neal O'Grady"/><br /><sub><b>Neal O'Grady</b></sub></a><br /><a href="#tool-Nealo" title="Tools">🔧</a></td>
2186+
<td align="center" valign="top" width="14.28%"><a href="http://jgresham.xyz"><img src="https://avatars.githubusercontent.com/u/3721291?v=4?s=100" width="100px;" alt="Johns Gresham"/><br /><sub><b>Johns Gresham</b></sub></a><br /><a href="#maintenance-jgresham" title="Maintenance">🚧</a></td>
2187+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Dragoon0x"><img src="https://avatars.githubusercontent.com/u/255907778?v=4?s=100" width="100px;" alt="Dragoon"/><br /><sub><b>Dragoon</b></sub></a><br /><a href="#tool-Dragoon0x" title="Tools">🔧</a></td>
2188+
</tr>
2189+
<tr>
2190+
<td align="center" valign="top" width="14.28%"><a href="https://mushow.uk/"><img src="https://avatars.githubusercontent.com/u/105550256?v=4?s=100" width="100px;" alt="0xMushow"/><br /><sub><b>0xMushow</b></sub></a><br /><a href="#maintenance-0xMushow" title="Maintenance">🚧</a></td>
21862191
</tr>
21872192
</tbody>
21882193
</table>

app/[locale]/10years/page.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
setRequestLocale,
66
} from "next-intl/server"
77

8-
import type { CommitHistory, Lang, PageParams } from "@/lib/types"
8+
import type { Lang, PageParams } from "@/lib/types"
99

1010
import Emoji from "@/components/Emoji"
1111
import I18nProvider from "@/components/I18nProvider"
@@ -64,11 +64,9 @@ const Page = async ({ params }: { params: PageParams }) => {
6464
const innovationCards = await getInnovationCards()
6565
const adoptionCards = await getAdoptionCards()
6666

67-
const commitHistoryCache: CommitHistory = {}
6867
const { contributors } = await getAppPageContributorInfo(
6968
"10years",
70-
locale as Lang,
71-
commitHistoryCache
69+
locale as Lang
7270
)
7371

7472
return (

app/[locale]/apps/[application]/page.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
setRequestLocale,
77
} from "next-intl/server"
88

9-
import type { ChainName, CommitHistory, Lang, PageParams } from "@/lib/types"
9+
import type { ChainName, Lang, PageParams } from "@/lib/types"
1010

1111
import AppCard from "@/components/AppCard"
1212
import ChainImages from "@/components/ChainImages"
@@ -131,11 +131,9 @@ const Page = async ({
131131
return new Date(app.dateOfLaunch).getFullYear()
132132
}
133133

134-
const commitHistoryCache: CommitHistory = {}
135134
const { contributors } = await getAppPageContributorInfo(
136135
"apps/[application]",
137-
locale as Lang,
138-
commitHistoryCache
136+
locale as Lang
139137
)
140138

141139
return (

app/[locale]/apps/categories/[catetgoryName]/page.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88

99
import {
1010
AppCategoryEnum,
11-
type CommitHistory,
1211
type Lang,
1312
type PageParams,
1413
type SectionNavDetails,
@@ -104,11 +103,9 @@ const Page = async ({
104103
})
105104
)
106105

107-
const commitHistoryCache: CommitHistory = {}
108106
const { contributors } = await getAppPageContributorInfo(
109107
"apps/categories/[catetgoryName]",
110-
locale as Lang,
111-
commitHistoryCache
108+
locale as Lang
112109
)
113110

114111
return (

app/[locale]/apps/page.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
setRequestLocale,
66
} from "next-intl/server"
77

8-
import { CommitHistory, Lang, PageParams } from "@/lib/types"
8+
import { Lang, PageParams } from "@/lib/types"
99

1010
import AppCard from "@/components/AppCard"
1111
import Breadcrumbs from "@/components/Breadcrumbs"
@@ -67,11 +67,9 @@ const Page = async ({ params }: { params: PageParams }) => {
6767
const requiredNamespaces = getRequiredNamespacesForPage("/apps")
6868
const messages = pick(allMessages, requiredNamespaces)
6969

70-
const commitHistoryCache: CommitHistory = {}
7170
const { contributors } = await getAppPageContributorInfo(
7271
"apps",
73-
locale as Lang,
74-
commitHistoryCache
72+
locale as Lang
7573
)
7674

7775
return (

app/[locale]/assets/page.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
setRequestLocale,
66
} from "next-intl/server"
77

8-
import type { CommitHistory, Lang, PageParams } from "@/lib/types"
8+
import type { Lang, PageParams } from "@/lib/types"
99

1010
import I18nProvider from "@/components/I18nProvider"
1111

@@ -26,11 +26,9 @@ export default async function Page({ params }: { params: PageParams }) {
2626
const requiredNamespaces = getRequiredNamespacesForPage("/assets")
2727
const messages = pick(allMessages, requiredNamespaces)
2828

29-
const commitHistoryCache: CommitHistory = {}
3029
const { contributors } = await getAppPageContributorInfo(
3130
"assets",
32-
locale as Lang,
33-
commitHistoryCache
31+
locale as Lang
3432
)
3533

3634
return (

0 commit comments

Comments
 (0)