Skip to content

Commit 1b0e651

Browse files
authored
Merge pull request #38479 from github/repo-sync
Repo sync
2 parents dddd72a + 80dbfc0 commit 1b0e651

File tree

10 files changed

+158
-102
lines changed

10 files changed

+158
-102
lines changed

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
"start": "cross-env NODE_ENV=development ENABLED_LANGUAGES=en nodemon src/frame/server.ts",
8787
"start-all-languages": "cross-env NODE_ENV=development tsx src/frame/server.ts",
8888
"start-for-playwright": "cross-env ROOT=src/fixtures/fixtures TRANSLATIONS_FIXTURE_ROOT=src/fixtures/fixtures/translations ENABLED_LANGUAGES=en,ja NODE_ENV=test tsx src/frame/server.ts",
89-
"symlink-from-local-repo": "tsx src/early-access/scripts/symlink-from-local-repo.js",
89+
"symlink-from-local-repo": "tsx src/early-access/scripts/symlink-from-local-repo.ts",
9090
"sync-audit-log": "tsx src/audit-logs/scripts/sync.ts",
9191
"sync-codeql-cli": "tsx src/codeql-cli/scripts/sync.js",
9292
"sync-graphql": "tsx src/graphql/scripts/sync.js",
@@ -98,13 +98,13 @@
9898
"test-moved-content": "tsx src/content-render/scripts/test-moved-content.ts",
9999
"tsc": "tsc --noEmit",
100100
"unallowed-contributions": "tsx src/workflows/unallowed-contributions.ts",
101-
"update-data-and-image-paths": "tsx src/early-access/scripts/update-data-and-image-paths.js",
101+
"update-data-and-image-paths": "tsx src/early-access/scripts/update-data-and-image-paths.ts",
102102
"update-enterprise-dates": "tsx src/ghes-releases/scripts/update-enterprise-dates.ts",
103103
"update-internal-links": "tsx src/links/scripts/update-internal-links.ts",
104104
"validate-asset-images": "tsx src/assets/scripts/validate-asset-images.ts",
105105
"validate-github-github-docs-urls": "tsx src/links/scripts/validate-github-github-docs-urls/index.ts",
106106
"warmup-remotejson": "tsx src/archives/scripts/warmup-remotejson.ts",
107-
"what-docs-early-access-branch": "tsx src/early-access/scripts/what-docs-early-access-branch.js"
107+
"what-docs-early-access-branch": "tsx src/early-access/scripts/what-docs-early-access-branch.ts"
108108
},
109109
"lint-staged": {
110110
"*.{js,mjs,ts,tsx}": "eslint --cache --fix",

src/early-access/scripts/migrate-early-access-product.js renamed to src/early-access/scripts/migrate-early-access-product.ts

Lines changed: 84 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ import { program } from 'commander'
1212
import { execFileSync } from 'child_process'
1313
import frontmatter from '#src/frame/lib/read-frontmatter.js'
1414
import patterns from '#src/frame/lib/patterns.js'
15-
import addRedirectToFrontmatter from '#src/redirects/scripts/helpers/add-redirect-to-frontmatter.js'
15+
import addRedirectToFrontmatter from '@/redirects/scripts/helpers/add-redirect-to-frontmatter'
1616
import walkFiles from '#src/workflows/walk-files.ts'
1717

18-
const contentFiles = walkFiles('content', '.md', { includeEarlyAccess: true })
19-
const contentDir = path.posix.join(process.cwd(), 'content')
18+
const contentFiles: string[] = walkFiles('content', '.md', { includeEarlyAccess: true })
19+
const contentDir: string = path.posix.join(process.cwd(), 'content')
2020

2121
program
2222
.description('Move a product-level early access docs set to a category level.')
@@ -34,29 +34,30 @@ program
3434
)
3535
.parse(process.argv)
3636

37-
const oldPathId = program.opts().oldPath.replace('content/', '')
38-
const newPathId = program.opts().newPath.replace('content/', '')
37+
const oldPathId: string = program.opts().oldPath.replace('content/', '')
38+
const newPathId: string = program.opts().newPath.replace('content/', '')
3939

40-
const oldPath = path.posix.join(contentDir, oldPathId)
41-
const newPath = path.posix.join(contentDir, newPathId)
40+
const oldPath: string = path.posix.join(contentDir, oldPathId)
41+
const newPath: string = path.posix.join(contentDir, newPathId)
4242

4343
if (!fs.existsSync(oldPath)) {
4444
console.error(`Error! Can't find ${oldPath}`)
4545
process.exit(1)
4646
}
4747

48-
const filesToMigrate = contentFiles.filter((file) => file.includes(`/${oldPathId}/`))
48+
const filesToMigrate: string[] = contentFiles.filter((file) => file.includes(`/${oldPathId}/`))
4949

5050
if (!filesToMigrate.length) {
5151
console.error(`Error! Can't find any files in ${oldPath}`)
5252
process.exit(1)
5353
}
5454

55-
const migratePath = path.posix.join(contentDir, newPathId)
55+
const migratePath: string = path.posix.join(contentDir, newPathId)
5656

5757
// 1. Update the image and data refs in the to-be-migrated early access files BEFORE moving them.
5858
try {
59-
execFileSync('src/early-access/scripts/update-data-and-image-paths.js', [
59+
execFileSync('tsx', [
60+
'src/early-access/scripts/update-data-and-image-paths.ts',
6061
'-p',
6162
`content/${oldPathId}`,
6263
'--remove',
@@ -66,28 +67,30 @@ try {
6667
process.exit(1)
6768
}
6869

69-
const variablesToMove = []
70-
const reusablesToMove = []
71-
const imagesToMove = []
70+
const variablesToMove: string[] = []
71+
const reusablesToMove: string[] = []
72+
const imagesToMove: string[] = []
7273

7374
// 2. Add redirects to and update frontmatter in the to-be-migrated early access files BEFORE moving them.
7475
filesToMigrate.forEach((filepath) => {
7576
const { content, data } = frontmatter(fs.readFileSync(filepath, 'utf8'))
76-
const redirectString = filepath
77+
const redirectString: string = filepath
7778
.replace('content/', '/')
7879
.replace('/index.md', '')
7980
.replace('.md', '')
80-
data.redirect_from = addRedirectToFrontmatter(data.redirect_from, redirectString)
81-
delete data.hidden
82-
delete data.noEarlyAccessBanner
83-
delete data.earlyAccessToc
84-
fs.writeFileSync(filepath, frontmatter.stringify(content, data, { lineWidth: 10000 }))
81+
if (data) {
82+
data.redirect_from = addRedirectToFrontmatter(data.redirect_from, redirectString)
83+
delete data.hidden
84+
delete data.noEarlyAccessBanner
85+
delete data.earlyAccessToc
86+
fs.writeFileSync(filepath, frontmatter.stringify(content || '', data))
87+
}
8588

8689
// 4. Find the data files and images referenced in the early access files so we can move them over.
87-
const dataRefs = content.match(patterns.dataReference) || []
88-
const variables = dataRefs.filter((ref) => ref.includes('variables'))
89-
const reusables = dataRefs.filter((ref) => ref.includes('reusables'))
90-
const images = content.match(patterns.imagePath) || []
90+
const dataRefs: string[] = content ? content.match(patterns.dataReference) || [] : []
91+
const variables: string[] = dataRefs.filter((ref) => ref.includes('variables'))
92+
const reusables: string[] = dataRefs.filter((ref) => ref.includes('reusables'))
93+
const images: string[] = content ? content.match(patterns.imagePath) || [] : []
9194

9295
variablesToMove.push(...variables)
9396
reusablesToMove.push(...reusables)
@@ -103,73 +106,78 @@ Array.from(new Set(imagesToMove)).forEach((imageRef) => moveImage(imageRef))
103106
execFileSync('mv', [oldPath, migratePath])
104107

105108
// 5. Update the parent product TOC with the new child path.
106-
const parentProductTocPath = path.posix.join(path.dirname(newPath), 'index.md')
107-
const parentProducToc = frontmatter(fs.readFileSync(parentProductTocPath, 'utf-8'))
108-
parentProducToc.data.children.push(`/${path.basename(newPathId)}`)
109+
const parentProductTocPath: string = path.posix.join(path.dirname(newPath), 'index.md')
110+
const parentProductToc = frontmatter(fs.readFileSync(parentProductTocPath, 'utf-8'))
111+
if (parentProductToc.data && Array.isArray(parentProductToc.data.children)) {
112+
parentProductToc.data.children.push(`/${path.basename(newPathId)}`)
113+
}
109114

110115
fs.writeFileSync(
111116
parentProductTocPath,
112-
frontmatter.stringify(parentProducToc.content, parentProducToc.data, { lineWidth: 10000 }),
117+
frontmatter.stringify(parentProductToc.content || '', parentProductToc.data || {}),
113118
)
114119

115120
// 6. Optionally, update the new product TOC with the new title.
116121
if (program.opts().newTitle) {
117-
const productTocPath = path.posix.join(newPath, 'index.md')
122+
const productTocPath: string = path.posix.join(newPath, 'index.md')
118123
const productToc = frontmatter(fs.readFileSync(productTocPath, 'utf-8'))
119-
productToc.data.title = program.opts().newTitle
124+
if (productToc.data) {
125+
productToc.data.title = program.opts().newTitle
126+
}
120127

121128
fs.writeFileSync(
122129
productTocPath,
123-
frontmatter.stringify(productToc.content, productToc.data, { lineWidth: 10000 }),
130+
frontmatter.stringify(productToc.content || '', productToc.data || {}),
124131
)
125132
}
126133

127134
// 7. Update internal links now that the files have been moved.
128135
console.log('\nRunning script to update internal links...')
129-
execFileSync('src/links/scripts/update-internal-links.js')
136+
execFileSync('tsx', ['src/links/scripts/update-internal-links.ts'])
130137

131138
console.log(`
132139
Done! Did the following:
133140
- Moved content/${oldPathId} files to content/${newPathId}
134-
- Ran ./src/early-access/scripts/update-data-and-images-paths.js
141+
- Ran ./src/early-access/scripts/update-data-and-image-paths.ts
135142
- Added redirects to the moved files
136143
- Updated children frontmatter entries in index.md files
137-
- Ran ./src/links/scripts/update-internal-links.js
144+
- Ran ./src/links/scripts/update-internal-links.ts
138145
139146
Please review all the changes in docs-internal and docs-early-access, especially to index.md files. You may need to do some manual cleanup.
140147
`)
141148

142-
function moveVariable(dataRef) {
149+
function moveVariable(dataRef: string): void {
143150
// Get the data filepath from the data reference,
144151
// where the data reference looks like: {% data variables.foo.bar %}
145152
// and the data filepath looks like: data/variables/foo.yml with key of 'bar'.
146-
const variablePathArray = dataRef
147-
.match(/{% (?:data|indented_data_reference) (.*?) %}/)[1]
148-
.split('.')
149-
// If early access is part of the path, remove it (since the path below already includes it)
150-
.filter((n) => n !== 'early-access')
153+
const variablePathArray: string[] =
154+
dataRef
155+
.match(/{% (?:data|indented_data_reference) (.*?) %}/)?.[1]
156+
.split('.')
157+
// If early access is part of the path, remove it (since the path below already includes it)
158+
.filter((n) => n !== 'early-access') || []
151159

152160
// Given a string `variables.foo.bar` split into an array, we want the last segment 'bar', which is the variable key.
153161
// Then pop 'bar' off the array because it's not really part of the filepath.
154162
// The filepath we want is `variables/foo.yml`.
155-
const variableKey = last(variablePathArray)
163+
const variableKey: string = last(variablePathArray) as string
156164

157165
variablePathArray.pop()
158166

159-
const oldVariablePath = path.posix.join(
167+
const oldVariablePath: string = path.posix.join(
160168
process.cwd(),
161169
'data/early-access',
162170
`${variablePathArray.join('/')}.yml`,
163171
)
164-
const newVariablePath = path.posix.join(
172+
const newVariablePath: string = path.posix.join(
165173
process.cwd(),
166174
'data',
167175
`${variablePathArray.join('/')}.yml`,
168176
)
169-
const nonAltPath = newVariablePath.replace('-alt.yml', '.yml')
170-
const oldAltPath = oldVariablePath.replace('.yml', '-alt.yml')
177+
const nonAltPath: string = newVariablePath.replace('-alt.yml', '.yml')
178+
const oldAltPath: string = oldVariablePath.replace('.yml', '-alt.yml')
171179

172-
let oldPath = oldVariablePath
180+
let oldPath: string = oldVariablePath
173181

174182
// If the old variable path doesn't exist, assume no migration needed.
175183
if (!fs.existsSync(oldVariablePath)) {
@@ -184,12 +192,17 @@ function moveVariable(dataRef) {
184192
}
185193
}
186194

187-
const variableFileContent = yaml.load(fs.readFileSync(oldPath, 'utf8'))
188-
const value = variableFileContent[variableKey]
195+
const variableFileContent: Record<string, any> = yaml.load(
196+
fs.readFileSync(oldPath, 'utf8'),
197+
) as Record<string, any>
198+
const value: any = variableFileContent[variableKey]
189199

190200
// If the variable file already exists, add the key/value pair.
191201
if (fs.existsSync(nonAltPath)) {
192-
const content = yaml.load(fs.readFileSync(nonAltPath, 'utf8'))
202+
const content: Record<string, any> = yaml.load(fs.readFileSync(nonAltPath, 'utf8')) as Record<
203+
string,
204+
any
205+
>
193206
if (!content[variableKey]) {
194207
const newString = `\n\n${variableKey}: ${value}`
195208
fs.appendFileSync(nonAltPath, newString)
@@ -199,19 +212,24 @@ function moveVariable(dataRef) {
199212
}
200213
}
201214

202-
function moveReusable(dataRef) {
215+
function moveReusable(dataRef: string): void {
203216
// Get the data filepath from the data reference,
204217
// where the data reference looks like: {% data reusables.foo.bar %}
205218
// and the data filepath looks like: data/reusables/foo/bar.md.
206-
const reusablePath = dataRef
207-
.match(/{% (?:data|indented_data_reference) (\S*?) .*%}/)[1]
208-
.split('.')
209-
// If early access is part of the path, remove it (since the path below already includes it)
210-
.filter((n) => n !== 'early-access')
211-
.join('/')
212-
213-
const oldReusablePath = path.posix.join(process.cwd(), 'data/early-access', `${reusablePath}.md`)
214-
const newReusablePath = path.posix.join(process.cwd(), 'data', `${reusablePath}.md`)
219+
const reusablePath: string =
220+
dataRef
221+
.match(/{% (?:data|indented_data_reference) (\S*?) .*%}/)?.[1]
222+
.split('.')
223+
// If early access is part of the path, remove it (since the path below already includes it)
224+
.filter((n) => n !== 'early-access')
225+
.join('/') || ''
226+
227+
const oldReusablePath: string = path.posix.join(
228+
process.cwd(),
229+
'data/early-access',
230+
`${reusablePath}.md`,
231+
)
232+
const newReusablePath: string = path.posix.join(process.cwd(), 'data', `${reusablePath}.md`)
215233

216234
// If the old reusable path doesn't exist, assume no migration needed.
217235
if (!fs.existsSync(oldReusablePath)) {
@@ -229,14 +247,18 @@ function moveReusable(dataRef) {
229247
}
230248
}
231249

232-
function moveImage(imageRef) {
233-
const imagePath = imageRef
250+
function moveImage(imageRef: string): void {
251+
const imagePath: string = imageRef
234252
.replace('/assets/images/', '')
235253
// If early access is part of the path, remove it (since the path below already includes it)
236254
.replace('early-access', '')
237255

238-
const oldImagePath = path.posix.join(process.cwd(), 'assets/images/early-access', imagePath)
239-
const newImagePath = path.posix.join(process.cwd(), 'assets/images', imagePath)
256+
const oldImagePath: string = path.posix.join(
257+
process.cwd(),
258+
'assets/images/early-access',
259+
imagePath,
260+
)
261+
const newImagePath: string = path.posix.join(process.cwd(), 'assets/images', imagePath)
240262

241263
// If the old image path doesn't exist, assume no migration needed.
242264
if (!fs.existsSync(oldImagePath)) {

src/early-access/scripts/symlink-from-local-repo.js renamed to src/early-access/scripts/symlink-from-local-repo.ts

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ const earlyAccessRepo = 'docs-early-access'
1616
const earlyAccessDirName = 'early-access'
1717
const earlyAccessRepoUrl = `https://github.com/github/${earlyAccessRepo}`
1818

19+
interface ProgramOptions {
20+
pathToEarlyAccessRepo?: string
21+
unlink?: boolean
22+
}
23+
1924
program
2025
.description(`Create or destroy symlinks to your local "${earlyAccessRepo}" repository.`)
2126
.option(
@@ -25,44 +30,45 @@ program
2530
.option('-u, --unlink', 'remove the symlinks')
2631
.parse(process.argv)
2732

28-
const { pathToEarlyAccessRepo, unlink } = program.opts()
33+
const { pathToEarlyAccessRepo, unlink }: ProgramOptions = program.opts()
2934

3035
if (!pathToEarlyAccessRepo && !unlink) {
3136
throw new Error('Must provide either `--path-to-early-access-repo <PATH>` or `--unlink`')
3237
}
3338

34-
let earlyAccessLocalRepoDir
39+
let earlyAccessLocalRepoDir: string | undefined
3540

3641
// If creating symlinks, run some extra validation
3742
if (!unlink && pathToEarlyAccessRepo) {
3843
earlyAccessLocalRepoDir = path.resolve(process.cwd(), pathToEarlyAccessRepo)
3944

40-
let dirStats
45+
let dirStats: fs.Stats | null
4146
try {
4247
dirStats = fs.statSync(earlyAccessLocalRepoDir)
43-
} catch (err) {
48+
} catch {
4449
dirStats = null
4550
}
4651

4752
if (!dirStats) {
4853
throw new Error(
49-
`The local "${earlyAccessRepo}" repo directory does not exist:`,
50-
earlyAccessLocalRepoDir,
54+
`The local "${earlyAccessRepo}" repo directory does not exist: ${earlyAccessLocalRepoDir}`,
5155
)
5256
}
5357
if (dirStats && !dirStats.isDirectory()) {
5458
throw new Error(
55-
`A non-directory entry exists at the local "${earlyAccessRepo}" repo directory location:`,
56-
earlyAccessLocalRepoDir,
59+
`A non-directory entry exists at the local "${earlyAccessRepo}" repo directory location: ${earlyAccessLocalRepoDir}`,
5760
)
5861
}
5962
}
6063

61-
const destinationDirNames = ['content', 'data', 'assets/images']
62-
const destinationDirsMap = destinationDirNames.reduce((map, dirName) => {
63-
map[dirName] = path.join(process.cwd(), dirName, earlyAccessDirName)
64-
return map
65-
}, {})
64+
const destinationDirNames: string[] = ['content', 'data', 'assets/images']
65+
const destinationDirsMap: Record<string, string> = destinationDirNames.reduce(
66+
(map, dirName) => {
67+
map[dirName] = path.join(process.cwd(), dirName, earlyAccessDirName)
68+
return map
69+
},
70+
{} as Record<string, string>,
71+
)
6672

6773
// Remove all existing early access directories from this repo
6874
destinationDirNames.forEach((dirName) => {
@@ -82,6 +88,8 @@ if (unlink) {
8288

8389
// Move the latest early access source directories into this repo
8490
destinationDirNames.forEach((dirName) => {
91+
if (!earlyAccessLocalRepoDir) return
92+
8593
const sourceDir = path.join(earlyAccessLocalRepoDir, dirName)
8694
const destDir = destinationDirsMap[dirName]
8795

0 commit comments

Comments
 (0)