зеркало из https://github.com/github/docs.git
Merge branch 'main' into patch-1
This commit is contained in:
Коммит
00311134ff
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"name": "test",
|
||||
"image": "mcr.microsoft.com/devcontainers/universal:linux",
|
||||
|
||||
"settings": {
|
||||
"terminal.integrated.shell.linux": "/bin/zsh",
|
||||
|
|
|
@ -21,7 +21,7 @@ topics:
|
|||
|
||||
## About {% data variables.product.prodname_secret_scanning %}
|
||||
|
||||
If someone checks a secret with a known pattern into a repository, {% data variables.product.prodname_secret_scanning %} catches the secret as it's checked in, and helps you mitigate the impact of the leak. Repository administrators are notified about any commit that contains a secret, and they can quickly view all detected secrets in the Security tab for the repository. For more information, see "[About {% data variables.product.prodname_secret_scanning %}](/code-security/secret-scanning/about-secret-scanning)."
|
||||
If someone checks a secret with a known pattern into a repository, {% data variables.product.prodname_secret_scanning %} catches the secret as it's checked in, and helps you mitigate the impact of the leak. Repository administrators are notified about any commit that contains a secret, and they can quickly view all detected secrets in the **Security** tab for the repository. For more information, see "[About {% data variables.product.prodname_secret_scanning %}](/code-security/secret-scanning/about-secret-scanning)."
|
||||
|
||||
## Checking whether your license includes {% data variables.product.prodname_GH_advanced_security %}
|
||||
|
||||
|
|
|
@ -513,7 +513,7 @@ query-filters:
|
|||
- exclude:
|
||||
id: js/useless-assignment-to-local
|
||||
```
|
||||
To find the id of a query, you can click the alert in the list of alerts in the Security tab. This opens the alert details page. The `Rule ID` field contains the query id. For more information about the alert details page, see "[About {% data variables.product.prodname_code_scanning %} alerts](/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/about-code-scanning-alerts#about-alert-details)."
|
||||
To find the id of a query, you can click the alert in the list of alerts in the **Security** tab. This opens the alert details page. The `Rule ID` field contains the query id. For more information about the alert details page, see "[About {% data variables.product.prodname_code_scanning %} alerts](/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/about-code-scanning-alerts#about-alert-details)."
|
||||
|
||||
{% tip %}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ You can also create a new issue to track an alert:
|
|||
|
||||
- Via the API as you normally would, and then provide the code scanning link within the body of the issue. You must use the task list syntax to create the tracked relationship:
|
||||
- `- [ ] <full-URL- to-the-code-scanning-alert>`
|
||||
- For example, if you add `- [ ] https://github.com/octocat-org/octocat-repo/security/code-scanning/17` to an issue, the issue will track the code scanning alert that has an ID number of 17 in the "Security" tab of the `octocat-repo` repository in the `octocat-org` organization.
|
||||
- For example, if you add `- [ ] https://github.com/octocat-org/octocat-repo/security/code-scanning/17` to an issue, the issue will track the code scanning alert that has an ID number of 17 in the **Security** tab of the `octocat-repo` repository in the `octocat-org` organization.
|
||||
|
||||
You can use more than one issue to track the same {% data variables.product.prodname_code_scanning %} alert, and issues can belong to different repositories from the repository where the {% data variables.product.prodname_code_scanning %} alert was found.
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ For information about access requirements for actions related to {% data variabl
|
|||
{% data variables.product.product_name %} starts generating the dependency graph immediately and generates alerts for any insecure dependencies as soon as they are identified. The graph is usually populated within minutes but this may take longer for repositories with many dependencies. For more information, see "[Managing data use settings for your private repository](/get-started/privacy-on-github/managing-data-use-settings-for-your-private-repository)."
|
||||
{% endif %}
|
||||
|
||||
When {% data variables.product.product_name %} identifies a vulnerable dependency{% ifversion GH-advisory-db-supports-malware %} or malware{% endif %}, we generate a {% data variables.product.prodname_dependabot %} alert and display it {% ifversion fpt or ghec or ghes %} on the Security tab for the repository and{% endif %} in the repository's dependency graph. The alert includes {% ifversion fpt or ghec or ghes %}a link to the affected file in the project, and {% endif %}information about a fixed version. {% data variables.product.product_name %} may also notify the maintainers of affected repositories about the new alert according to their notification preferences. For more information, see "[Configuring notifications for {% data variables.product.prodname_dependabot_alerts %}](/code-security/dependabot/dependabot-alerts/configuring-notifications-for-dependabot-alerts)."
|
||||
When {% data variables.product.product_name %} identifies a vulnerable dependency{% ifversion GH-advisory-db-supports-malware %} or malware{% endif %}, we generate a {% data variables.product.prodname_dependabot %} alert and display it {% ifversion fpt or ghec or ghes %} on the **Security** tab for the repository and{% endif %} in the repository's dependency graph. The alert includes {% ifversion fpt or ghec or ghes %}a link to the affected file in the project, and {% endif %}information about a fixed version. {% data variables.product.product_name %} may also notify the maintainers of affected repositories about the new alert according to their notification preferences. For more information, see "[Configuring notifications for {% data variables.product.prodname_dependabot_alerts %}](/code-security/dependabot/dependabot-alerts/configuring-notifications-for-dependabot-alerts)."
|
||||
|
||||
{% ifversion fpt or ghec or ghes %}
|
||||
For repositories where {% data variables.product.prodname_dependabot_security_updates %} are enabled, the alert may also contain a link to a pull request to update the manifest or lock file to the minimum version that resolves the vulnerability. For more information, see "[About {% data variables.product.prodname_dependabot_security_updates %}](/github/managing-security-vulnerabilities/about-dependabot-security-updates)."
|
||||
|
@ -89,7 +89,7 @@ For repositories where {% data variables.product.prodname_dependabot_security_up
|
|||
|
||||
## Access to {% data variables.product.prodname_dependabot_alerts %}
|
||||
|
||||
You can see all of the alerts that affect a particular project{% ifversion fpt or ghec %} on the repository's Security tab or{% endif %} in the repository's dependency graph. For more information, see "[Viewing and updating {% data variables.product.prodname_dependabot_alerts %}](/code-security/dependabot/dependabot-alerts/viewing-and-updating-dependabot-alerts)."
|
||||
You can see all of the alerts that affect a particular project{% ifversion fpt or ghec %} on the repository's **Security** tab or{% endif %} in the repository's dependency graph. For more information, see "[Viewing and updating {% data variables.product.prodname_dependabot_alerts %}](/code-security/dependabot/dependabot-alerts/viewing-and-updating-dependabot-alerts)."
|
||||
|
||||
By default, we notify people with admin permissions in the affected repositories about new {% data variables.product.prodname_dependabot_alerts %}. {% ifversion fpt or ghec %}{% data variables.product.product_name %} never publicly discloses insecure dependencies for any repository. You can also make {% data variables.product.prodname_dependabot_alerts %} visible to additional people or teams working with repositories that you own or have admin permissions for. For more information, see "[Managing security and analysis settings for your repository](/github/administering-a-repository/managing-security-and-analysis-settings-for-your-repository#granting-access-to-security-alerts)."
|
||||
{% endif %}
|
||||
|
|
|
@ -23,7 +23,7 @@ topics:
|
|||
|
||||
## About notifications for {% data variables.product.prodname_dependabot_alerts %}
|
||||
|
||||
When {% data variables.product.prodname_dependabot %} detects vulnerable dependencies{% ifversion GH-advisory-db-supports-malware %} or malware{% endif %} in your repositories, we generate a {% data variables.product.prodname_dependabot %} alert and display it on the Security tab for the repository. {% data variables.product.product_name %} notifies the maintainers of affected repositories about the new alert according to their notification preferences.{% ifversion fpt or ghec %} {% data variables.product.prodname_dependabot %} is enabled by default on all public repositories. For {% data variables.product.prodname_dependabot_alerts %}, by default, you will receive {% data variables.product.prodname_dependabot_alerts %} by email, grouped by the specific vulnerability.
|
||||
When {% data variables.product.prodname_dependabot %} detects vulnerable dependencies{% ifversion GH-advisory-db-supports-malware %} or malware{% endif %} in your repositories, we generate a {% data variables.product.prodname_dependabot %} alert and display it on the **Security** tab for the repository. {% data variables.product.product_name %} notifies the maintainers of affected repositories about the new alert according to their notification preferences.{% ifversion fpt or ghec %} {% data variables.product.prodname_dependabot %} is enabled by default on all public repositories. For {% data variables.product.prodname_dependabot_alerts %}, by default, you will receive {% data variables.product.prodname_dependabot_alerts %} by email, grouped by the specific vulnerability.
|
||||
{% endif %}
|
||||
|
||||
{% ifversion fpt or ghec %}If you're an organization owner, you can enable or disable {% data variables.product.prodname_dependabot_alerts %} for all repositories in your organization with one click. You can also set whether {% data variables.product.prodname_dependabot_alerts %} will be enabled or disabled for newly-created repositories. For more information, see "[Managing security and analysis settings for your organization](/organizations/keeping-your-organization-secure/managing-security-and-analysis-settings-for-your-organization#enabling-or-disabling-a-feature-for-all-new-repositories-when-they-are-added)."
|
||||
|
@ -62,7 +62,7 @@ You can configure notification settings for yourself or your organization from t
|
|||
|
||||
## How to reduce the noise from notifications for {% data variables.product.prodname_dependabot_alerts %}
|
||||
|
||||
If you are concerned about receiving too many notifications for {% data variables.product.prodname_dependabot_alerts %}, we recommend you opt into the weekly email digest, or turn off notifications while keeping {% data variables.product.prodname_dependabot_alerts %} enabled. You can still navigate to see your {% data variables.product.prodname_dependabot_alerts %} in your repository's Security tab. For more information, see "[Viewing and updating {% data variables.product.prodname_dependabot_alerts %}](/code-security/dependabot/dependabot-alerts/viewing-and-updating-dependabot-alerts)."
|
||||
If you are concerned about receiving too many notifications for {% data variables.product.prodname_dependabot_alerts %}, we recommend you opt into the weekly email digest, or turn off notifications while keeping {% data variables.product.prodname_dependabot_alerts %} enabled. You can still navigate to see your {% data variables.product.prodname_dependabot_alerts %} in your repository's **Security** tab. For more information, see "[Viewing and updating {% data variables.product.prodname_dependabot_alerts %}](/code-security/dependabot/dependabot-alerts/viewing-and-updating-dependabot-alerts)."
|
||||
|
||||
## Further reading
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ Limited to free public repositories.
|
|||
Available only with a license for {% data variables.product.prodname_GH_advanced_security %}.
|
||||
{% endif %}
|
||||
|
||||
Automatically detect tokens or credentials that have been checked into a repository. You can view alerts for any secrets that {% data variables.product.company_short %} finds in your code, in the "Security" tab of the repository, so that you know which tokens or credentials to treat as compromised. For more information, see {% ifversion fpt or ghec %}"[About {% data variables.secret-scanning.user_alerts %}](/code-security/secret-scanning/about-secret-scanning#about-secret-scanning-alerts-for-users)"{% elsif ghes %}"[About {% data variables.secret-scanning.user_alerts %} on {% data variables.product.product_name %}](/code-security/secret-scanning/about-secret-scanning#about-secret-scanning-on-github-enterprise-server){% elsif ghae %}"[About {% data variables.secret-scanning.user_alerts %} on {% data variables.product.product_name %}](/code-security/secret-scanning/about-secret-scanning#about-secret-scanning-on-github-ae){% endif %}."
|
||||
Automatically detect tokens or credentials that have been checked into a repository. You can view alerts for any secrets that {% data variables.product.company_short %} finds in your code, in the **Security** tab of the repository, so that you know which tokens or credentials to treat as compromised. For more information, see {% ifversion fpt or ghec %}"[About {% data variables.secret-scanning.user_alerts %}](/code-security/secret-scanning/about-secret-scanning#about-secret-scanning-alerts-for-users)"{% elsif ghes %}"[About {% data variables.secret-scanning.user_alerts %} on {% data variables.product.product_name %}](/code-security/secret-scanning/about-secret-scanning#about-secret-scanning-on-github-enterprise-server){% elsif ghae %}"[About {% data variables.secret-scanning.user_alerts %} on {% data variables.product.product_name %}](/code-security/secret-scanning/about-secret-scanning#about-secret-scanning-on-github-ae){% endif %}."
|
||||
|
||||
### Dependency review
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ If your project communicates with an external service, you might use a token or
|
|||
- Organizations using {% data variables.product.prodname_ghe_cloud %} with a license for {% data variables.product.prodname_GH_advanced_security %}, on repositories owned by the organization, including _private_ and _internal_ repositories.{% elsif ghec %}You can enable and configure additional scanning for repositories owned by organizations that use {% data variables.product.prodname_ghe_cloud %} and have a license for {% data variables.product.prodname_GH_advanced_security %}. This includes private and internal repositories.{% endif %}
|
||||
{%- indented_data_reference reusables.secret-scanning.secret-scanning-alerts-beta %}
|
||||
|
||||
Any strings that match patterns provided by secret scanning partners, by other service providers, or defined by you or your organization, are reported as alerts in the "Security" tab of repositories. If a string in a public repository matches a partner pattern, it is also reported to the partner. For more information, see the "[About {% data variables.secret-scanning.user_alerts %}](#about-secret-scanning-alerts-for-users)" section below.{% endif %}
|
||||
Any strings that match patterns provided by secret scanning partners, by other service providers, or defined by you or your organization, are reported as alerts in the **Security** tab of repositories. If a string in a public repository matches a partner pattern, it is also reported to the partner. For more information, see the "[About {% data variables.secret-scanning.user_alerts %}](#about-secret-scanning-alerts-for-users)" section below.{% endif %}
|
||||
|
||||
|
||||
Service providers can partner with {% data variables.product.company_short %} to provide their secret formats for scanning. {% data reusables.secret-scanning.partner-program-link %}
|
||||
|
@ -88,7 +88,7 @@ If {% data variables.product.prodname_secret_scanning %} detects a secret, {% da
|
|||
|
||||
- {% data variables.product.prodname_dotcom %} sends an email alert to the repository administrators and organization owners. You'll receive an alert if you are watching the repository, and if you have enabled notifications either for security alerts or for all the activity on the repository.
|
||||
- If the contributor who committed the secret isn't ignoring the repository, {% data variables.product.prodname_dotcom %} will also send an email alert to the contributor. The emails contains a link to the related {% data variables.product.prodname_secret_scanning %} alert. The commit author can then view the alert in the repository, and resolve the alert.
|
||||
- {% data variables.product.prodname_dotcom %} displays an alert in the "Security" tab of the repository.
|
||||
- {% data variables.product.prodname_dotcom %} displays an alert in the **Security** tab of the repository.
|
||||
|
||||
For more information about viewing and resolving {% data variables.secret-scanning.alerts %}, see "[Managing alerts from {% data variables.product.prodname_secret_scanning %}](/github/administering-a-repository/managing-alerts-from-secret-scanning)."
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ shortTitle: Enable push protection
|
|||
Up to now, {% data variables.product.prodname_secret_scanning %} checks for secrets _after_ a push and alerts users to exposed secrets. {% data reusables.secret-scanning.push-protection-overview %} {% ifversion secret-scanning-push-protection-custom-patterns %}{% data variables.product.prodname_secret_scanning_caps %} can also check pushes for custom patterns. For more information, see "[Defining custom patterns for secret scanning](/code-security/secret-scanning/defining-custom-patterns-for-secret-scanning)."{% endif %}
|
||||
|
||||
If a contributor bypasses a push protection block for a secret, {% data variables.product.prodname_dotcom %}:
|
||||
- creates an alert in the "Security" tab of the repository in the state described in the table below.
|
||||
- creates an alert in the **Security** tab of the repository in the state described in the table below.
|
||||
- adds the bypass event to the audit log.{% ifversion secret-scanning-push-protection-email %}
|
||||
- sends an email alert to organization owners, security managers, and repository administrators who are watching the repository, with a link to the secret and the reason why it was allowed.{% endif %}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ Owners of public repositories, as well as organizations using {% data variables.
|
|||
|
||||
{% data reusables.secret-scanning.secret-scanning-alerts-beta %}
|
||||
|
||||
When {% data variables.secret-scanning.user_alerts %} {% ifversion fpt or ghec %}are{% else %}is{% endif %} enabled, {% data variables.product.prodname_dotcom %} scans repositories for secrets issued by the following service providers and generates {% data variables.secret-scanning.alerts %}. You can see these alerts on the "Security" tab of the repository. {% ifversion fpt or ghec %}For more information about {% data variables.secret-scanning.user_alerts %}, see "[About {% data variables.secret-scanning.user_alerts %}](/code-security/secret-scanning/about-secret-scanning#about-secret-scanning-alerts-for-users)."{% endif %}
|
||||
When {% data variables.secret-scanning.user_alerts %} {% ifversion fpt or ghec %}are{% else %}is{% endif %} enabled, {% data variables.product.prodname_dotcom %} scans repositories for secrets issued by the following service providers and generates {% data variables.secret-scanning.alerts %}. You can see these alerts on the **Security** tab of the repository. {% ifversion fpt or ghec %}For more information about {% data variables.secret-scanning.user_alerts %}, see "[About {% data variables.secret-scanning.user_alerts %}](/code-security/secret-scanning/about-secret-scanning#about-secret-scanning-alerts-for-users)."{% endif %}
|
||||
|
||||
{% data reusables.secret-scanning.secret-scanning-pattern-pair-matches %}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{%- ifversion ghec or ghes > 3.4 or ghae > 3.4 %}
|
||||
1. In the left sidebar, click **Authentication security**.
|
||||
{% ifversion ghae %}![Security tab in the enterprise account settings sidebar](/assets/images/enterprise/github-ae/enterprise-account-settings-authentication-security-tab.png){% else %}![Security tab in the enterprise account settings sidebar](/assets/images/help/business-accounts/enterprise-account-settings-authentication-security-tab.png){% endif %}
|
||||
{% ifversion ghae %}![**Security** tab in the enterprise account settings sidebar](/assets/images/enterprise/github-ae/enterprise-account-settings-authentication-security-tab.png){% else %}![**Security** tab in the enterprise account settings sidebar](/assets/images/help/business-accounts/enterprise-account-settings-authentication-security-tab.png){% endif %}
|
||||
{%- else %}
|
||||
1. In the left sidebar, click **Security**.
|
||||
{% ifversion ghae %}![Security tab in the enterprise account settings sidebar](/assets/images/enterprise/github-ae/enterprise-account-settings-security-tab.png){% else %}![Security tab in the enterprise account settings sidebar](/assets/images/help/business-accounts/enterprise-account-settings-security-tab.png){% endif %}
|
||||
{% ifversion ghae %}![**Security** tab in the enterprise account settings sidebar](/assets/images/enterprise/github-ae/enterprise-account-settings-security-tab.png){% else %}![**Security** tab in the enterprise account settings sidebar](/assets/images/help/business-accounts/enterprise-account-settings-security-tab.png){% endif %}
|
||||
{%- endif %}
|
||||
|
|
|
@ -1 +1 @@
|
|||
When you allow a secret to be pushed, an alert is created in the "Security" tab. {% data variables.product.prodname_dotcom %} closes the alert and doesn't send a notification if you specify that the secret is a false positive or used only in tests. If you specify that the secret is real and that you will fix it later, {% data variables.product.prodname_dotcom %} keeps the security alert open and sends notifications to the author of the commit, as well as to repository administrators. For more information, see "[Managing alerts from secret scanning](/code-security/secret-scanning/managing-alerts-from-secret-scanning)."
|
||||
When you allow a secret to be pushed, an alert is created in the **Security** tab. {% data variables.product.prodname_dotcom %} closes the alert and doesn't send a notification if you specify that the secret is a false positive or used only in tests. If you specify that the secret is real and that you will fix it later, {% data variables.product.prodname_dotcom %} keeps the security alert open and sends notifications to the author of the commit, as well as to repository administrators. For more information, see "[Managing alerts from secret scanning](/code-security/secret-scanning/managing-alerts-from-secret-scanning)."
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import { getLanguageCode } from './patterns.js'
|
||||
import getRedirect from './get-redirect.js'
|
||||
|
||||
export default function findPage(href, pageMap, redirects) {
|
||||
export default function findPage(href, pages, redirects) {
|
||||
// remove any fragments
|
||||
href = href.replace(/#.*$/, '')
|
||||
|
||||
const redirectsContext = { redirects, pages: pageMap }
|
||||
const redirectsContext = { redirects, pages }
|
||||
|
||||
// find the page
|
||||
const page = pageMap[href] || pageMap[getRedirect(href, redirectsContext)]
|
||||
const page = pages[href] || pages[getRedirect(href, redirectsContext)]
|
||||
if (page) return page
|
||||
|
||||
// get the current language
|
||||
|
@ -16,5 +16,5 @@ export default function findPage(href, pageMap, redirects) {
|
|||
|
||||
// try to fall back to English if the translated page can't be found
|
||||
const englishHref = href.replace(`/${currentLang}/`, '/en/')
|
||||
return pageMap[englishHref] || pageMap[getRedirect(englishHref, redirectsContext)]
|
||||
return pages[englishHref] || pages[getRedirect(englishHref, redirectsContext)]
|
||||
}
|
||||
|
|
|
@ -44,10 +44,7 @@ export default function createProcessor(context) {
|
|||
.use(raw)
|
||||
.use(wrapInElement, { selector: 'ol > li img', wrapper: 'span.procedural-image-wrapper' })
|
||||
.use(rewriteImgSources)
|
||||
.use(rewriteLocalLinks, {
|
||||
languageCode: context.currentLanguage,
|
||||
version: context.currentVersion,
|
||||
})
|
||||
.use(rewriteLocalLinks, context)
|
||||
.use(html)
|
||||
}
|
||||
|
||||
|
@ -58,9 +55,6 @@ export function createMinimalProcessor(context) {
|
|||
.use(remark2rehype, { allowDangerousHtml: true })
|
||||
.use(slug)
|
||||
.use(raw)
|
||||
.use(rewriteLocalLinks, {
|
||||
languageCode: context.currentLanguage,
|
||||
version: context.currentVersion,
|
||||
})
|
||||
.use(rewriteLocalLinks, context)
|
||||
.use(html)
|
||||
}
|
||||
|
|
|
@ -8,10 +8,14 @@ import nonEnterpriseDefaultVersion from '../../non-enterprise-default-version.js
|
|||
import { allVersions } from '../../all-versions.js'
|
||||
import removeFPTFromPath from '../../remove-fpt-from-path.js'
|
||||
import readJsonFile from '../../read-json-file.js'
|
||||
import findPage from '../../find-page.js'
|
||||
|
||||
const supportedPlans = new Set(Object.values(allVersions).map((v) => v.plan))
|
||||
const externalRedirects = readJsonFile('./lib/redirects/external-sites.json')
|
||||
|
||||
// Meaning it can be 'AUTOTITLE ' or ' AUTOTITLE' or 'AUTOTITLE'
|
||||
const AUTOTITLE = /^\s*AUTOTITLE\s*$/
|
||||
|
||||
// Matches any <a> tags with an href that starts with `/`
|
||||
const matcher = (node) =>
|
||||
node.type === 'element' &&
|
||||
|
@ -22,20 +26,34 @@ const matcher = (node) =>
|
|||
|
||||
// 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
|
||||
export default function rewriteLocalLinks({ languageCode, version }) {
|
||||
export default function rewriteLocalLinks(context) {
|
||||
const { currentLanguage, currentVersion } = context
|
||||
// There's no languageCode or version passed, so nothing to do
|
||||
if (!languageCode || !version) return
|
||||
if (!currentLanguage || !currentVersion) return
|
||||
|
||||
return (tree) => {
|
||||
visit(tree, matcher, (node) => {
|
||||
const newHref = getNewHref(node, languageCode, version)
|
||||
const newHref = getNewHref(node, currentLanguage, currentVersion)
|
||||
if (newHref) {
|
||||
node.properties.href = newHref
|
||||
}
|
||||
for (const child of node.children) {
|
||||
if (child.value && AUTOTITLE.test(child.value)) {
|
||||
child.value = getNewTitle(node.properties.href, context)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function getNewTitle(href, context) {
|
||||
const page = findPage(href, context.pages, context.redirects)
|
||||
if (!page) {
|
||||
throw new Error(`Unable to find Page by href '${href}'`)
|
||||
}
|
||||
return page.title
|
||||
}
|
||||
|
||||
function getNewHref(node, languageCode, version) {
|
||||
const { href } = node.properties
|
||||
// Exceptions to link rewriting
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
import assert from 'assert'
|
||||
import path from 'path'
|
||||
import { getPathWithoutLanguage, getVersionStringFromPath } from './path-utils.js'
|
||||
import { getNewVersionedPath } from './old-versions-utils.js'
|
||||
import patterns from './patterns.js'
|
||||
import { deprecated, latest } from './enterprise-server-releases.js'
|
||||
import nonEnterpriseDefaultVersion from './non-enterprise-default-version.js'
|
||||
import { allVersions } from './all-versions.js'
|
||||
import removeFPTFromPath from './remove-fpt-from-path.js'
|
||||
import readJsonFile from './read-json-file.js'
|
||||
const supportedVersions = Object.keys(allVersions)
|
||||
const supportedPlans = Object.values(allVersions).map((v) => v.plan)
|
||||
const externalRedirects = readJsonFile('./lib/redirects/external-sites.json')
|
||||
|
||||
// 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
|
||||
export default function rewriteLocalLinks($, version, languageCode) {
|
||||
assert(languageCode, 'languageCode is required')
|
||||
|
||||
$('a[href^="/"]').each((i, el) => {
|
||||
getNewHref($(el), languageCode, version)
|
||||
})
|
||||
}
|
||||
|
||||
function getNewHref(link, languageCode, version) {
|
||||
const href = link.attr('href')
|
||||
|
||||
// Exceptions to link rewriting
|
||||
if (href.startsWith('/assets/')) return
|
||||
if (href.startsWith('/public/')) return
|
||||
if (Object.keys(externalRedirects).includes(href)) return
|
||||
|
||||
let newHref = href
|
||||
// If the link has a hardcoded plan or version in it, do not update other than adding a language code
|
||||
// Examples:
|
||||
// /enterprise-server@2.20/rest/reference/oauth-authorizations
|
||||
// /enterprise-server/rest/reference/oauth-authorizations (this redirects to the latest version)
|
||||
// /enterprise-server@latest/rest/reference/oauth-authorizations (this redirects to the latest version)
|
||||
const firstLinkSegment = href.split('/')[1]
|
||||
if (
|
||||
[...supportedPlans, ...supportedVersions, 'enterprise-server@latest'].includes(firstLinkSegment)
|
||||
) {
|
||||
newHref = path.join('/', languageCode, href)
|
||||
}
|
||||
|
||||
// If the link includes a deprecated version, do not update other than adding a language code
|
||||
// Example: /enterprise/11.10.340/admin/articles/upgrading-to-the-latest-release
|
||||
const oldEnterpriseVersionNumber = href.match(patterns.getEnterpriseVersionNumber)
|
||||
if (oldEnterpriseVersionNumber && deprecated.includes(oldEnterpriseVersionNumber[1])) {
|
||||
newHref = path.join('/', languageCode, href)
|
||||
}
|
||||
|
||||
if (newHref === href) {
|
||||
// start clean with no language (TOC pages already include the lang codes via lib/liquid-tags/link.js)
|
||||
const hrefWithoutLang = getPathWithoutLanguage(href)
|
||||
|
||||
// normalize any legacy links so they conform to new link structure
|
||||
newHref = path.posix.join('/', languageCode, getNewVersionedPath(hrefWithoutLang))
|
||||
|
||||
// get the current version from the link
|
||||
const versionFromHref = getVersionStringFromPath(newHref)
|
||||
|
||||
// ------ BEGIN ONE-OFF OVERRIDES ------//
|
||||
// dotcom-only links always point to dotcom
|
||||
if (link.hasClass('dotcom-only')) {
|
||||
version = nonEnterpriseDefaultVersion
|
||||
}
|
||||
|
||||
// desktop links always point to dotcom
|
||||
if (patterns.desktop.test(hrefWithoutLang)) {
|
||||
version = nonEnterpriseDefaultVersion
|
||||
}
|
||||
|
||||
// admin links on dotcom always point to Enterprise
|
||||
if (patterns.adminProduct.test(hrefWithoutLang) && version === nonEnterpriseDefaultVersion) {
|
||||
version = `enterprise-server@${latest}`
|
||||
}
|
||||
|
||||
// insights links on dotcom always point to Enterprise
|
||||
if (patterns.insightsProduct.test(hrefWithoutLang) && version === nonEnterpriseDefaultVersion) {
|
||||
version = `enterprise-server@${latest}`
|
||||
}
|
||||
// ------ END ONE-OFF OVERRIDES ------//
|
||||
|
||||
// update the version in the link
|
||||
newHref = removeFPTFromPath(newHref.replace(versionFromHref, version))
|
||||
}
|
||||
|
||||
newHref = newHref.replace(patterns.trailingSlash, '$1')
|
||||
|
||||
if (href !== newHref) link.attr('href', newHref)
|
||||
}
|
|
@ -8,6 +8,7 @@ import warmServer from '../lib/warm-server.js'
|
|||
import searchVersions from '../lib/search/versions.js'
|
||||
import nonEnterpriseDefaultVersion from '../lib/non-enterprise-default-version.js'
|
||||
import { getDataByLanguage, getUIDataMerged } from '../lib/get-data.js'
|
||||
|
||||
const activeProducts = Object.values(productMap).filter(
|
||||
(product) => !product.wip && !product.hidden
|
||||
)
|
||||
|
@ -90,5 +91,6 @@ export default async function contextualize(req, res, next) {
|
|||
return context.enPage
|
||||
}
|
||||
}
|
||||
|
||||
return next()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { expect, jest } from '@jest/globals'
|
||||
|
||||
import { getDOM } from '../helpers/e2etest.js'
|
||||
import { getDOMCached as getDOM } from '../helpers/e2etest.js'
|
||||
|
||||
jest.setTimeout(3 * 60 * 1000)
|
||||
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
import { jest, expect } from '@jest/globals'
|
||||
|
||||
import { getDOM } from '../helpers/e2etest.js'
|
||||
import { loadPages } from '../../lib/page-data.js'
|
||||
|
||||
describe('process learning tracks', () => {
|
||||
// Because calling `loadPages` will trigger a warmup, this can potentially
|
||||
// be very slow in CI. So we need a timeout.
|
||||
jest.setTimeout(60 * 1000)
|
||||
|
||||
test('pages with learningTracks ', async () => {
|
||||
const pageList = await loadPages(undefined, ['en'])
|
||||
|
||||
for (const page of pageList) {
|
||||
if (page.learningTracks && page.learningTracks.length > 0) {
|
||||
for (const permalink of page.permalinks) {
|
||||
const $ = await getDOM(permalink.href)
|
||||
expect($('[data-testid="learning-track"]').length).toBeGreaterThanOrEqual(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
Загрузка…
Ссылка в новой задаче