Skip to content

Commit cedfe4d

Browse files
authored
repo sync (github#4236)
1 parent 136a6bd commit cedfe4d

File tree

15 files changed

+226
-16
lines changed

15 files changed

+226
-16
lines changed

.github/workflows/browser-test.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ name: Browser Tests
22

33
on:
44
workflow_dispatch:
5-
push:
6-
branches:
7-
- main
8-
pull_request:
5+
# push:
6+
# branches:
7+
# - main
8+
# pull_request:
99

1010
jobs:
1111
see_if_should_skip:

content/github/searching-for-information-on-github/about-searching-on-github.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ You can search for the following information across all repositories you can acc
4545
- [Discussions](/github/searching-for-information-on-github/searching-discussions){% endif %}
4646
- [Code](/articles/searching-code)
4747
- [Commits](/articles/searching-commits)
48-
- [Users](/articles/searching-users){% if currentVersion == "free-pro-team@latest" or currentVersion == "github-ae@latest" or currentVersion ver_gt "enterprise-server@2.1" %}
48+
- [Users](/articles/searching-users){% if currentVersion == "free-pro-team@latest" or currentVersion == "github-ae@latest" or currentVersion ver_gt "enterprise-server@2.21" %}
4949
- [Packages](/github/searching-for-information-on-github/searching-for-packages){% endif %}
5050
- [Wikis](/articles/searching-wikis)
5151

content/github/setting-up-and-managing-your-github-user-account/permission-levels-for-a-user-account-repository.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ The repository owner has full control of the repository. In addition to the acti
3535
| Delete the repository | "[Deleting a repository](/github/administering-a-repository/deleting-a-repository)" |
3636
| Manage the repository's topics | "[Classifying your repository with topics](/github/administering-a-repository/classifying-your-repository-with-topics)" |{% if currentVersion == "free-pro-team@latest" %}
3737
| Manage security and analysis settings for the repository | "[Managing security and analysis settings for your repository](/github/administering-a-repository/managing-security-and-analysis-settings-for-your-repository)" |{% endif %}{% if currentVersion == "free-pro-team@latest" %}
38-
| Enable the dependency graph for a private repository | "[Exploring the dependencies of a repository](/github/visualizing-repository-data-with-graphs/exploring-the-dependencies-of-a-repository#enabling-and-disabling-the-dependency-graph-for-a-private-repository)" |{% endif %}
39-
{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "[email protected]" %}| Delete and restore packages | "[Deleting and restoring a package](/packages/learn-github-packages/deleting-and-restoring-a-package)" |{% elsif currentVersion ver_lt "[email protected]" or currentVersion == "github-ae@latest" %}| Delete packages | "[Deleting packages](/packages/learn-github-packages/deleting-a-package)" |{% endif %}
38+
| Enable the dependency graph for a private repository | "[Exploring the dependencies of a repository](/github/visualizing-repository-data-with-graphs/exploring-the-dependencies-of-a-repository#enabling-and-disabling-the-dependency-graph-for-a-private-repository)" |{% endif %}{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "[email protected]" %}
39+
| Delete and restore packages | "[Deleting and restoring a package](/packages/learn-github-packages/deleting-and-restoring-a-package)" |{% endif %}{% if currentVersion == "[email protected]" or currentVersion == "[email protected]" or currentVersion == "github-ae@latest" %}
40+
| Delete packages | "[Deleting packages](/packages/learn-github-packages/deleting-a-package)" |{% endif %}
4041
| Customize the repository's social media preview | "[Customizing your repository's social media preview](/github/administering-a-repository/customizing-your-repositorys-social-media-preview)" |
4142
| Create a template from the repository | "[Creating a template repository](/github/creating-cloning-and-archiving-repositories/creating-a-template-repository)" |{% if currentVersion == "free-pro-team@latest" or enterpriseServerVersions contains currentVersion %}
4243
| Receive {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "[email protected]" %}{% data variables.product.prodname_dependabot_alerts %}{% else %}security alerts{% endif %} for vulnerable dependencies | "[About alerts for vulnerable dependencies](/github/managing-security-vulnerabilities/about-alerts-for-vulnerable-dependencies)" |{% endif %}{% if currentVersion == "free-pro-team@latest" %}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
1. In the left sidebar, click **OAuth Apps**.
2-
![OAuth Apps section](/assets/images/settings/developer-settings-oauth-apps.png)
2+
![OAuth Apps section](/assets/images/help/settings/developer-settings-oauth-apps.png)

lib/render-content/renderContent.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ module.exports = async function renderContent (
6666
.trim()
6767
}
6868

69+
if (options.cheerioObject) {
70+
return cheerio.load(html, { xmlMode: true })
71+
}
72+
6973
if (options.encodeEntities) html = entities.encode(html)
7074

7175
return html.trim()

lib/rest/static/dereferenced/api.github.com.deref.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139709,7 +139709,7 @@
139709139709
"name",
139710139710
"head_sha"
139711139711
],
139712-
"anyOf": [
139712+
"oneOf": [
139713139713
{
139714139714
"properties": {
139715139715
"status": {
@@ -139719,6 +139719,7 @@
139719139719
}
139720139720
},
139721139721
"required": [
139722+
"status",
139722139723
"conclusion"
139723139724
],
139724139725
"additionalProperties": true

lib/rest/static/dereferenced/ghes-2.18.deref.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79203,7 +79203,7 @@
7920379203
"name",
7920479204
"head_sha"
7920579205
],
79206-
"anyOf": [
79206+
"oneOf": [
7920779207
{
7920879208
"properties": {
7920979209
"status": {
@@ -79213,6 +79213,7 @@
7921379213
}
7921479214
},
7921579215
"required": [
79216+
"status",
7921679217
"conclusion"
7921779218
],
7921879219
"additionalProperties": true

lib/rest/static/dereferenced/ghes-2.19.deref.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82135,7 +82135,7 @@
8213582135
"name",
8213682136
"head_sha"
8213782137
],
82138-
"anyOf": [
82138+
"oneOf": [
8213982139
{
8214082140
"properties": {
8214182141
"status": {
@@ -82145,6 +82145,7 @@
8214582145
}
8214682146
},
8214782147
"required": [
82148+
"status",
8214882149
"conclusion"
8214982150
],
8215082151
"additionalProperties": true

lib/rest/static/dereferenced/ghes-2.20.deref.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84244,7 +84244,7 @@
8424484244
"name",
8424584245
"head_sha"
8424684246
],
84247-
"anyOf": [
84247+
"oneOf": [
8424884248
{
8424984249
"properties": {
8425084250
"status": {
@@ -84254,6 +84254,7 @@
8425484254
}
8425584255
},
8425684256
"required": [
84257+
"status",
8425784258
"conclusion"
8425884259
],
8425984260
"additionalProperties": true

lib/rest/static/dereferenced/ghes-2.21.deref.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95077,7 +95077,7 @@
9507795077
"name",
9507895078
"head_sha"
9507995079
],
95080-
"anyOf": [
95080+
"oneOf": [
9508195081
{
9508295082
"properties": {
9508395083
"status": {
@@ -95087,6 +95087,7 @@
9508795087
}
9508895088
},
9508995089
"required": [
95090+
"status",
9509095091
"conclusion"
9509195092
],
9509295093
"additionalProperties": true

lib/rest/static/dereferenced/ghes-2.22.deref.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121969,7 +121969,7 @@
121969121969
"name",
121970121970
"head_sha"
121971121971
],
121972-
"anyOf": [
121972+
"oneOf": [
121973121973
{
121974121974
"properties": {
121975121975
"status": {
@@ -121979,6 +121979,7 @@
121979121979
}
121980121980
},
121981121981
"required": [
121982+
"status",
121982121983
"conclusion"
121983121984
],
121984121985
"additionalProperties": true

lib/rest/static/dereferenced/ghes-3.0.deref.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127095,7 +127095,7 @@
127095127095
"name",
127096127096
"head_sha"
127097127097
],
127098-
"anyOf": [
127098+
"oneOf": [
127099127099
{
127100127100
"properties": {
127101127101
"status": {
@@ -127105,6 +127105,7 @@
127105127105
}
127106127106
},
127107127107
"required": [
127108+
"status",
127108127109
"conclusion"
127109127110
],
127110127111
"additionalProperties": true

lib/rest/static/dereferenced/github.ae.deref.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109550,7 +109550,7 @@
109550109550
"name",
109551109551
"head_sha"
109552109552
],
109553-
"anyOf": [
109553+
"oneOf": [
109554109554
{
109555109555
"properties": {
109556109556
"status": {
@@ -109560,6 +109560,7 @@
109560109560
}
109561109561
},
109562109562
"required": [
109563+
"status",
109563109564
"conclusion"
109564109565
],
109565109566
"additionalProperties": true

script/update-internal-links.js

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
#!/usr/bin/env node
2+
3+
const fs = require('fs')
4+
const walk = require('walk-sync')
5+
const path = require('path')
6+
const astFromMarkdown = require('mdast-util-from-markdown')
7+
const visit = require('unist-util-visit')
8+
const { loadPages, loadPageMap } = require('../lib/pages')
9+
const loadSiteData = require('../lib/site-data')
10+
const loadRedirects = require('../lib/redirects/precompile')
11+
const { getPathWithoutLanguage, getPathWithoutVersion } = require('../lib/path-utils')
12+
const allVersions = Object.keys(require('../lib/all-versions'))
13+
const frontmatter = require('../lib/read-frontmatter')
14+
const renderContent = require('../lib/render-content')
15+
const patterns = require('../lib/patterns')
16+
17+
const walkFiles = (pathToWalk) => {
18+
return walk(path.posix.join(__dirname, '..', pathToWalk), { includeBasePath: true, directories: false })
19+
.filter(file => file.endsWith('.md') && !file.endsWith('README.md'))
20+
.filter(file => !file.includes('/early-access/')) // ignore EA for now
21+
}
22+
23+
const allFiles = walkFiles('content').concat(walkFiles('data'))
24+
25+
// The script will throw an error if it finds any markup not represented here.
26+
// Hacky but it captures the current rare edge cases.
27+
const linkInlineMarkup = {
28+
emphasis: '*',
29+
strong: '**'
30+
}
31+
32+
const currentVersionWithSpacesRegex = /\/enterprise\/{{ currentVersion }}/g
33+
const currentVersionWithoutSpaces = '/enterprise/{{currentVersion}}'
34+
35+
// [start-readme]
36+
//
37+
// Run this script to find internal links in all content and data Markdown files, check if either the title or link
38+
// (or both) are outdated, and automatically update them if so.
39+
//
40+
// Exceptions:
41+
// * Links with fragments (e.g., [Bar](/foo#bar)) will get their root links updated if necessary, but the fragment
42+
// and title will be unchanged (e.g., [Bar](/noo#bar)).
43+
// * Links with hardcoded versions (e.g., [Foo](/enterprise-server/baz)) will get their root links updated if
44+
// necessary, but the hardcoded versions will be preserved (e.g., [Foo](/enterprise-server/qux)).
45+
// * Links with Liquid in the titles will have their root links updated if necessary, but the titles will be preserved.
46+
//
47+
// [end-readme]
48+
49+
main()
50+
51+
async function main () {
52+
console.log('Working...')
53+
const pageList = await loadPages()
54+
const pageMap = await loadPageMap(pageList)
55+
const redirects = await loadRedirects(pageList)
56+
const site = await loadSiteData()
57+
58+
const context = {
59+
pages: pageMap,
60+
redirects,
61+
site: site.en.site,
62+
currentLanguage: 'en'
63+
}
64+
65+
for (const file of allFiles) {
66+
const { data, content } = frontmatter(fs.readFileSync(file, 'utf8'))
67+
let newContent = content
68+
69+
// Do a blanket find-replace for /enterprise/{{ currentVersion }}/ to /enterprise/{{currentVersion}}/
70+
// so that the AST parser recognizes the link as a link node. The spaces prevent it from doing so.
71+
newContent = newContent.replace(currentVersionWithSpacesRegex, currentVersionWithoutSpaces)
72+
73+
const ast = astFromMarkdown(newContent)
74+
75+
// We can't do async functions within visit, so gather the nodes upfront
76+
const nodesPerFile = []
77+
78+
visit(ast, node => {
79+
if (node.type !== 'link') return
80+
if (!node.url.startsWith('/')) return
81+
if (node.url.startsWith('/assets')) return
82+
if (node.url.startsWith('/public')) return
83+
if (node.url.includes('/11.10.340/')) return
84+
if (node.url.includes('/2.1/')) return
85+
if (node.url === '/') return
86+
87+
nodesPerFile.push(node)
88+
})
89+
90+
// For every Markdown link...
91+
for (const node of nodesPerFile) {
92+
const oldLink = node.url
93+
94+
// Find and preserve any inline markup in link titles, like [*Foo*](/foo)
95+
let inlineMarkup = ''
96+
if (node.children[0].children) {
97+
inlineMarkup = linkInlineMarkup[node.children[0].type]
98+
99+
if (!inlineMarkup) {
100+
console.error(`Cannot find an inline markup entry for ${node.children[0].type}!`)
101+
process.exit(1)
102+
}
103+
}
104+
105+
const oldTitle = node.children[0].value || node.children[0].children[0].value
106+
const oldMarkdownLink = `[${inlineMarkup}${oldTitle}${inlineMarkup}](${oldLink})`
107+
108+
// As a blanket rule, only update titles in links that begin with quotes. (Many links
109+
// have punctuation before the closing quotes, so we'll only check for opening quotes.)
110+
// Update: "[Foo](/foo)
111+
// Do not update: [Bar](/bar)
112+
const hasQuotesAroundLink = newContent.includes(`"${oldMarkdownLink}`)
113+
114+
let foundPage, fragmentMatch, versionMatch
115+
116+
// Run through all supported versions...
117+
for (const version of allVersions) {
118+
context.currentVersion = version
119+
// Render the link for each version using the renderContent pipeline, which includes the rewrite-local-links plugin.
120+
const $ = await renderContent(oldMarkdownLink, context, { cheerioObject: true })
121+
let linkToCheck = $('a').attr('href')
122+
123+
// We need to preserve fragments and hardcoded versions if any are found.
124+
fragmentMatch = oldLink.match(/(#.*$)/)
125+
versionMatch = oldLink.match(/(enterprise-server(?:@.[^/]*?)?)\//)
126+
127+
// Remove the fragment for now.
128+
linkToCheck = linkToCheck
129+
.replace(/#.*$/, '')
130+
.replace(patterns.trailingSlash, '$1')
131+
132+
// Try to find the rendered link in the set of pages!
133+
foundPage = findPage(linkToCheck, pageMap, redirects)
134+
135+
// Once a page is found for a particular version, exit immediately; we don't need to check the other versions
136+
// because all we care about is the page title and path.
137+
if (foundPage) {
138+
break
139+
}
140+
}
141+
142+
if (!foundPage) {
143+
console.error(`Can't find link in pageMap! ${oldLink} in ${file.replace(process.cwd(), '')}`)
144+
process.exit(1)
145+
}
146+
147+
// If the original link includes a fragment OR the original title includes Liquid, do not change;
148+
// otherwise, use the found page title. (We don't want to update the title if a fragment is found because
149+
// the title likely points to the fragment section header, not the page title.)
150+
const newTitle = fragmentMatch || oldTitle.includes('{%') || !hasQuotesAroundLink ? oldTitle : foundPage.title
151+
152+
// If the original link includes a fragment, append it to the found page path.
153+
// Also remove the language code because Markdown links don't include language codes.
154+
let newLink = getPathWithoutLanguage(fragmentMatch ? foundPage.path + fragmentMatch[1] : foundPage.path)
155+
156+
// If the original link includes a hardcoded version, preserve it; otherwise, remove versioning
157+
// because Markdown links don't include versioning.
158+
newLink = versionMatch ? `/${versionMatch[1]}${getPathWithoutVersion(newLink)}` : getPathWithoutVersion(newLink)
159+
160+
let newMarkdownLink = `[${inlineMarkup}${newTitle}${inlineMarkup}](${newLink})`
161+
162+
// Handle a few misplaced quotation marks.
163+
if (oldMarkdownLink.includes('["')) {
164+
newMarkdownLink = `"${newMarkdownLink}`
165+
}
166+
167+
// Stream the results to console as we find them.
168+
if (oldMarkdownLink !== newMarkdownLink) {
169+
console.log('old link', oldMarkdownLink)
170+
console.log('new link', newMarkdownLink)
171+
console.log('-------')
172+
}
173+
174+
newContent = newContent.replace(oldMarkdownLink, newMarkdownLink)
175+
}
176+
177+
fs.writeFileSync(file, frontmatter.stringify(newContent, data, { lineWidth: 10000 }))
178+
}
179+
180+
console.log('Done!')
181+
}
182+
183+
function findPage (tryPath, pageMap, redirects) {
184+
if (pageMap[tryPath]) {
185+
return {
186+
title: pageMap[tryPath].title,
187+
path: tryPath
188+
}
189+
}
190+
191+
if (pageMap[redirects[tryPath]]) {
192+
return {
193+
title: pageMap[redirects[tryPath]].title,
194+
path: redirects[tryPath]
195+
}
196+
}
197+
}

0 commit comments

Comments
 (0)