Skip to content
Closed
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
526c05f
support hardcoded versions in links
sarahs Dec 7, 2020
ba2ebcf
remove version number and leave plan name in Enterprise link
sarahs Dec 7, 2020
e2d114b
lint
sarahs Dec 8, 2020
6288998
Revert "Revert "Speed up warmServer by loading pages (and files) asyn…
heiskr Dec 9, 2020
da05754
Branch was updated using the 'autoupdate branch' Actions workflow.
Octomerger Dec 9, 2020
73f061c
repo sync
Octomerger Dec 9, 2020
64d3846
Add await to warmServer in all environments (#16841)
JasonEtco Dec 9, 2020
b025ba2
Merge branch 'main' into support-hardcoded-versions-in-links
sarahs Dec 9, 2020
9fef524
Move to a version of this that works with a cron (#16830)
chiedo Dec 9, 2020
639e324
Merge branch 'main' into support-hardcoded-versions-in-links
sarahs Dec 9, 2020
b807035
Merge pull request #16775 from github/support-hardcoded-versions-in-l…
sarahs Dec 9, 2020
575752a
re-add unsafe-eval to the CSP for deprecated docs
sarahs Dec 9, 2020
1b424df
Bring in data-directory, let's go async file reads (#16782)
heiskr Dec 9, 2020
910a94b
Remove skip-duplicate-actions for linting (#16845)
chiedo Dec 9, 2020
f21c2f3
update CSP for specific versions only
sarahs Dec 9, 2020
6a3d326
add one-off cases for hooks and pre-receive-hooks (#16784)
rachmari Dec 9, 2020
5b0207b
remove reusable (#16844)
megbird Dec 9, 2020
d24e54a
Merge branch 'main' into fix-deprecated-versions-bug
sarahs Dec 9, 2020
3fcc701
Merge pull request #16843 from github/fix-deprecated-versions-bug
sarahs Dec 9, 2020
6d8cb7c
Merge branch 'main' into repo-sync
heiskr Dec 9, 2020
6d637c7
Merge branch 'main' into repo-sync
heiskr Dec 9, 2020
11cfa68
Merge branch 'repo-sync' of https://github.com/github/docs into repo-…
heiskr Dec 9, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions .github/workflows/js-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,8 @@ on:
- translations

jobs:
see_if_should_skip:
runs-on: ubuntu-latest

outputs:
should_skip: ${{ steps.skip_check.outputs.should_skip }}
steps:
- id: skip_check
uses: fkirc/skip-duplicate-actions@36feb0d8d062137530c2e00bd278d138fe191289
with:
cancel_others: 'false'
github_token: ${{ github.token }}
paths: '["**/*.js", "package*.json", ".github/workflows/js-lint.yml", ".eslint*"]'

lint:
runs-on: ubuntu-latest
needs: see_if_should_skip
if: ${{ needs.see_if_should_skip.outputs.should_skip != 'true' }}
steps:
- name: Check out repo
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/repo-sync-stalls.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ jobs:
github-token: ${{ secrets.DOCUBOT_FR_PROJECT_BOARD_WORKFLOWS_REPO_ORG_READ_SCOPES }}
script: |
let pulls;
const owner = context.payload.repository.owner.login
const repo = context.payload.repository.name
const owner = context.repo.owner
const repo = context.repo.repo
try {
pulls = await github.pulls.list({
owner: owner,
Expand Down
15 changes: 0 additions & 15 deletions .github/workflows/yml-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,8 @@ on:
- translations

jobs:
see_if_should_skip:
runs-on: ubuntu-latest

outputs:
should_skip: ${{ steps.skip_check.outputs.should_skip }}
steps:
- id: skip_check
uses: fkirc/skip-duplicate-actions@36feb0d8d062137530c2e00bd278d138fe191289
with:
cancel_others: 'false'
github_token: ${{ github.token }}
paths: '["**/*.yml", "**/*.yaml", "package*.json", ".github/workflows/yml-lint.yml"]'

lint:
runs-on: ubuntu-latest
needs: see_if_should_skip
if: ${{ needs.see_if_should_skip.outputs.should_skip != 'true' }}
steps:
- name: Check out repo
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion content/discussions/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ Repository owners and people with write access can enable {% data variables.prod
When you first enable a {% data variables.product.prodname_discussions %}, you will be invited to configure a welcome post.

{% data reusables.repositories.navigate-to-repo %}
{% data reusables.repositories.sidebar-settings %}
1. Under your repository name, click {% octicon "gear" aria-label="The gear icon" %}
**Settings**.
![Public settings button](/assets/images/help/discussions/public-repo-settings.png)
1. Under "Features", click **Set up discussions**.
![Set up a discussion button under "Features" for enabling or disabling discussions for a repository](/assets/images/help/discussions/setup-discussions-button.png)
1. Under "Start a new discussion," edit the template to align with the resources and tone you want to set for your community.
Expand Down
1 change: 1 addition & 0 deletions content/github/working-with-github-support/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
title: Working with GitHub Support
redirect_from:
- /categories/working-with-github-support
- /forum
versions:
free-pro-team: '*'
---
Expand Down
2 changes: 1 addition & 1 deletion content/rest/overview/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ curl -H 'Authorization: token my-oauth-token' https://api.github.com/user/repos

#### Calls to OAuth Authorizations API

If you're making [OAuth Authorization API](/enterprise-server@2.22/rest/reference/oauth-authorizations) calls to manage your OAuth app's authorizations or to generate access tokens, similar to this example:
If you're making [OAuth Authorization API](/enterprise-server/rest/reference/oauth-authorizations) calls to manage your OAuth app's authorizations or to generate access tokens, similar to this example:

```bash
curl -u my_username:my_password -X POST "https://api.github.com/authorizations" -d '{"scopes":["public_repo"], "note":"my token", "client_id":"my_client_id", "client_secret":"my_client_secret"}'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
You can enable or disable discussions for a repository.

{% data reusables.repositories.navigate-to-repo %}
{% data reusables.repositories.sidebar-settings %}
1. Under your repository name, click {% octicon "gear" aria-label="The gear icon" %}
**Settings**.
![Repository settings button](/assets/images/help/discussions/public-repo-settings.png)
1. Under "Features", select **Discussions**.
![Checkbox under "Features" for enabling or disabling discussions for a repository](/assets/images/help/discussions/select-discussions-checkbox.png)
68 changes: 68 additions & 0 deletions lib/data-directory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const assert = require('assert')
const fs = require('fs').promises
const path = require('path')
const walk = require('walk-sync')
const yaml = require('js-yaml')
const { isRegExp, set } = require('lodash')
const filenameToKey = require('./filename-to-key')

module.exports = async function dataDirectory (dir, opts = {}) {
const defaultOpts = {
preprocess: (content) => { return content },
ignorePatterns: [/README\.md$/i],
extensions: [
'.json',
'.md',
'.markdown',
'.yaml',
'.yml'
]
}

opts = Object.assign({}, defaultOpts, opts)

// validate input
assert(Array.isArray(opts.ignorePatterns))
assert(opts.ignorePatterns.every(isRegExp))
assert(Array.isArray(opts.extensions))
assert(opts.extensions.length)

// start with an empty data object
const data = {}

// find YAML and Markdown files in the given directory, recursively
await Promise.all(walk(dir, { includeBasePath: true })
.filter(filename => {
// ignore files that match any of ignorePatterns regexes
if (opts.ignorePatterns.some(pattern => pattern.test(filename))) return false

// ignore files that don't have a whitelisted file extension
return opts.extensions.includes(path.extname(filename).toLowerCase())
})
.map(async filename => {
// derive `foo.bar.baz` object key from `foo/bar/baz.yml` filename
const key = filenameToKey(path.relative(dir, filename))
const extension = path.extname(filename).toLowerCase()

let fileContent = await fs.readFile(filename, 'utf8')

if (opts.preprocess) fileContent = opts.preprocess(fileContent)

// add this file's data to the global data object
switch (extension) {
case '.json':
set(data, key, JSON.parse(fileContent))
break
case '.yaml':
case '.yml':
set(data, key, yaml.safeLoad(fileContent, { filename }))
break
case '.md':
case '.markdown':
set(data, key, fileContent)
break
}
}))

return data
}
28 changes: 28 additions & 0 deletions lib/filename-to-key.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* eslint-disable prefer-regex-literals */
const path = require('path')
const { escapeRegExp } = require('lodash')

// slash at the beginning of a filename
const leadingPathSeparator = new RegExp(`^${escapeRegExp(path.sep)}`)
const windowsLeadingPathSeparator = new RegExp('^/')

// all slashes in the filename. path.sep is OS agnostic (windows, mac, etc)
const pathSeparator = new RegExp(escapeRegExp(path.sep), 'g')
const windowsPathSeparator = new RegExp('/', 'g')

// handle MS Windows style double-backslashed filenames
const windowsDoubleSlashSeparator = new RegExp('\\\\', 'g')

// derive `foo.bar.baz` object key from `foo/bar/baz.yml` filename
module.exports = function filenameToKey (filename) {
const extension = new RegExp(`${path.extname(filename)}$`)
const key = filename
.replace(extension, '')
.replace(leadingPathSeparator, '')
.replace(windowsLeadingPathSeparator, '')
.replace(pathSeparator, '.')
.replace(windowsPathSeparator, '.')
.replace(windowsDoubleSlashSeparator, '.')

return key
}
25 changes: 20 additions & 5 deletions lib/page.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const assert = require('assert')
const fs = require('fs')
const fs = require('fs').promises
const path = require('path')
const cheerio = require('cheerio')
const patterns = require('./patterns')
Expand All @@ -23,15 +23,30 @@ const slash = require('slash')
const statsd = require('./statsd')

class Page {
constructor (opts) {
static async init (opts) {
assert(opts.relativePath, 'relativePath is required')
assert(opts.basePath, 'basePath is required')

const relativePath = slash(opts.relativePath)
const fullPath = slash(path.join(opts.basePath, relativePath))
const raw = await fs.readFile(fullPath, 'utf8')

return new Page({ ...opts, relativePath, fullPath, raw })
}

static async exists (path) {
try {
return await fs.stat(path)
} catch (err) {
if (err.code === 'ENOENT') return false
console.error(err)
}
}

constructor (opts) {
assert(opts.languageCode, 'languageCode is required')

Object.assign(this, { ...opts })
this.relativePath = slash(this.relativePath)
this.fullPath = slash(path.join(this.basePath, this.relativePath))
this.raw = fs.readFileSync(this.fullPath, 'utf8')

// TODO remove this when crowdin-support issue 66 has been resolved
if (this.languageCode !== 'en' && this.raw.includes(': verdadero')) {
Expand Down
54 changes: 31 additions & 23 deletions lib/pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,50 @@ const path = require('path')
const walk = require('walk-sync').entries
const Page = require('./page')
const languages = require('./languages')
const fs = require('fs')
const { mapLimit, filterLimit } = require('async')
const FILE_READ_LIMIT = 500

async function loadPageList () {
const pageList = []

// load english pages
const englishPath = path.join(__dirname, '..', languages.en.dir, 'content')
const englishPages = walk(englishPath)
.filter(({ relativePath }) => {
return relativePath.endsWith('.md') &&
!relativePath.includes('README')
})
.map(fileData => new Page({ ...fileData, languageCode: languages.en.code }))

const englishPaths = walk(englishPath)
.filter(({ relativePath }) =>
relativePath.endsWith('.md') && !relativePath.includes('README')
)
const englishPages = await mapLimit(
englishPaths,
FILE_READ_LIMIT,
async fileData => await Page.init({ ...fileData, languageCode: languages.en.code })
)
pageList.push(...englishPages)

// load matching pages in other languages
for (const page of englishPages) {
for (const language of Object.values(languages)) {
if (language.code === 'en') continue

let localizedPaths = Object.values(languages)
.filter(({ code }) => code !== 'en')
.map(language => {
const basePath = path.join(__dirname, '..', language.dir, 'content')
const localizedPath = path.join(basePath, page.relativePath)
try {
fs.statSync(localizedPath)
} catch (_) {
continue
}

pageList.push(new Page({
relativePath: page.relativePath,
return englishPages.map(page => ({
basePath,
relativePath: page.relativePath,
localizedPath: path.join(basePath, page.relativePath),
languageCode: language.code
}))
}
}
})
.flat()
localizedPaths = await filterLimit(
localizedPaths,
FILE_READ_LIMIT,
async ({ localizedPath }) => Page.exists(localizedPath)
)
const localizedPages = await mapLimit(
localizedPaths,
FILE_READ_LIMIT,
async ({ basePath, relativePath, languageCode }) =>
await Page.init({ basePath, relativePath, languageCode })
)
pageList.push(...localizedPages)

return pageList
}
Expand Down
21 changes: 20 additions & 1 deletion lib/redirects/get-docs-path-from-developer-path.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,25 @@ module.exports = function getDocsPathFromDeveloperPath (oldDeveloperPath, allRed
// oneoff redirect
const v3OrgPreReceiveHooks = '/v3/orgs/pre_receive_hooks'
if (newPath.endsWith(v3OrgPreReceiveHooks)) {
newPath = newPath.replace(v3OrgPreReceiveHooks, '/v3/enterprise-admin/org_pre_receive_hooks')
newPath = newPath.replace(v3OrgPreReceiveHooks, '/v3/enterprise-admin/organization_pre_receive_hooks')
}

// oneoff redirect
const v3RepoPreReceiveHooks = '/v3/repos/pre_receive_hooks'
if (newPath.endsWith(v3RepoPreReceiveHooks)) {
newPath = newPath.replace(v3RepoPreReceiveHooks, '/v3/enterprise-admin/repository_pre_receive_hooks')
}

// oneoff redirect
const v3OrgHooks = '/v3/orgs/hooks'
if (newPath.endsWith(v3OrgHooks)) {
newPath = newPath.replace(v3OrgHooks, '/v3/orgs/webhooks')
}

// oneoff redirect
const v3RepoHooks = '/v3/repos/hooks'
if (newPath.endsWith(v3RepoHooks)) {
newPath = newPath.replace(v3RepoHooks, '/v3/repos/webhooks')
}

// oneoff redirect for a dotcom developer path to Enterprise-only path on docs.github.com
Expand Down Expand Up @@ -46,6 +64,7 @@ module.exports = function getDocsPathFromDeveloperPath (oldDeveloperPath, allRed
.replace(/_/g, '-')
// this is a special oneoff replacement
.replace('org-pre-receive-hooks', 'organization-pre-receive-hooks')
.replace('repo-pre-receive-hooks', 'repository-pre-receive-hooks')
: lastSegment
}

Expand Down
17 changes: 14 additions & 3 deletions lib/rewrite-local-links.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const externalRedirects = Object.keys(require('./redirects/external-sites'))
const pathUtils = require('./path-utils')
const assert = require('assert')
const nonEnterpriseDefaultVersion = require('./non-enterprise-default-version')
const supportedPlans = Object.values(require('./all-versions')).map(v => v.plan)

// Content authors write links like `/some/article/path`, but they need to be
// rewritten on the fly to match the current language and page version
Expand All @@ -24,11 +25,21 @@ function getNewHref (link, languageCode, version) {
// e.g. `/contact` should not be replaced with `/en/contact`
if (externalRedirects.includes(href)) return

let newHref

// If the link has a hardcoded plan name in it (e.g., /enterprise-server/rest/reference/oauth-authorizations),
// only rewrite it with a language code
if (supportedPlans.includes(href.split('/')[1])) {
newHref = pathUtils.getPathWithLanguage(href, languageCode)
}

// If link is dotcom-only, just get the language code
// Otherwise, get the versioned path with language code
const newHref = link.hasClass('dotcom-only')
? pathUtils.getVersionedPathWithLanguage(href, nonEnterpriseDefaultVersion, languageCode)
: pathUtils.getVersionedPathWithLanguage(href, version, languageCode)
if (!newHref) {
newHref = link.hasClass('dotcom-only')
? pathUtils.getVersionedPathWithLanguage(href, nonEnterpriseDefaultVersion, languageCode)
: pathUtils.getVersionedPathWithLanguage(href, version, languageCode)
}

if (href !== newHref) link.attr('href', newHref)
}
Loading