зеркало из https://github.com/github/docs.git
Remove code examples on code security and codespaces landing pages (#36496)
This commit is contained in:
Родитель
ab817e4964
Коммит
784e937b85
|
@ -42,7 +42,6 @@ export type ProductLandingContextT = {
|
|||
productVideo: string
|
||||
productVideoTranscript: string
|
||||
featuredLinks: Record<string, Array<FeaturedLink>>
|
||||
productCodeExamples: Array<CodeExample>
|
||||
productUserExamples: Array<{ username: string; description: string }>
|
||||
productCommunityExamples: Array<{ repo: string; description: string }>
|
||||
featuredArticles: Array<{
|
||||
|
@ -117,7 +116,6 @@ export const getProductLandingContextFromRequest = async (
|
|||
},
|
||||
whatsNewChangelog: req.context.whatsNewChangelog || [],
|
||||
changelogUrl: req.context.changelogUrl || [],
|
||||
productCodeExamples: req.context.productCodeExamples || [],
|
||||
productCommunityExamples: req.context.productCommunityExamples || [],
|
||||
ghesReleases: req.context.ghesReleases || [],
|
||||
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
import { RepoIcon } from '@primer/octicons-react'
|
||||
import { CodeExample } from 'components/context/ProductLandingContext'
|
||||
import { TruncateLines } from 'components/ui/TruncateLines'
|
||||
import { Label } from '@primer/react'
|
||||
|
||||
type Props = {
|
||||
example: CodeExample
|
||||
}
|
||||
export const CodeExampleCard = ({ example }: Props) => {
|
||||
return (
|
||||
<a
|
||||
className="Box d-flex flex-column flex-justify-between height-full color-shadow-medium hover-shadow-large no-underline color-fg-default"
|
||||
data-testid="code-example-card"
|
||||
href={`https://github.com/${example.href}`}
|
||||
>
|
||||
<div className="p-4">
|
||||
<h3 className="f4">{example.title}</h3>
|
||||
<p className="mt-2 mb-4 color-fg-muted">{example.description}</p>
|
||||
<div className="d-flex flex-wrap">
|
||||
{example.tags.map((tag) => {
|
||||
return (
|
||||
<Label key={tag} variant="accent" sx={{ mb: 1, mr: 2 }}>
|
||||
{tag}
|
||||
</Label>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<footer className="border-top p-4 color-fg-muted d-flex flex-items-center">
|
||||
<RepoIcon aria-label="repository URL" className="flex-shrink-0" />
|
||||
<TruncateLines
|
||||
as="span"
|
||||
maxLines={1}
|
||||
className="ml-2 text-mono text-small color-fg-accent line-break-anywhere"
|
||||
>
|
||||
{example.href}
|
||||
</TruncateLines>
|
||||
</footer>
|
||||
</a>
|
||||
)
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
import { useEffect, useState } from 'react'
|
||||
import { ArrowRightIcon, SearchIcon } from '@primer/octicons-react'
|
||||
import { Text } from '@primer/react'
|
||||
|
||||
import { useProductLandingContext } from 'components/context/ProductLandingContext'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { CodeExampleCard } from 'components/landing/CodeExampleCard'
|
||||
import { Link } from 'components/Link'
|
||||
|
||||
const PAGE_SIZE = 6
|
||||
export const CodeExamples = () => {
|
||||
const { productCodeExamples } = useProductLandingContext()
|
||||
const { t } = useTranslation('product_landing')
|
||||
const [numVisible, setNumVisible] = useState(PAGE_SIZE)
|
||||
const [search, setSearch] = useState('')
|
||||
const [typed, setTyped] = useState('')
|
||||
|
||||
useEffect(() => {
|
||||
setNumVisible(PAGE_SIZE) // reset the visible count (only matters after searching)
|
||||
}, [search])
|
||||
|
||||
const isSearching = !!search
|
||||
let searchResults: typeof productCodeExamples = []
|
||||
if (isSearching) {
|
||||
// The following replace method escapes special characters in regular expression creation.
|
||||
const matchReg = new RegExp(search.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'), 'i')
|
||||
searchResults = productCodeExamples.filter((example) => {
|
||||
const searchableStr = `${example.tags.join(' ')} ${example.title} ${example.description}`
|
||||
return matchReg.test(searchableStr)
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<form
|
||||
data-search="hide"
|
||||
className="pr-lg-3 mb-5 mt-3"
|
||||
onSubmit={(event) => {
|
||||
event.preventDefault()
|
||||
setSearch(typed.trim())
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
className="ml-1 mr-2"
|
||||
fontWeight="bold"
|
||||
fontSize={2}
|
||||
as="label"
|
||||
htmlFor="searchCodeExamples"
|
||||
id="searchCodeExamples"
|
||||
>
|
||||
{t('code_example.search_examples')}
|
||||
</Text>
|
||||
<input
|
||||
data-testid="code-examples-input"
|
||||
className="input-lg py-2 px-3 col-12 col-lg-8 form-control"
|
||||
placeholder={t('search_code_examples')}
|
||||
type="search"
|
||||
autoComplete="off"
|
||||
aria-label={t('search_code_examples')}
|
||||
onChange={(event) => setTyped(event.target.value)}
|
||||
value={typed}
|
||||
/>
|
||||
<button data-testid="code-examples-search-btn" className="btn ml-2 py-2" type="submit">
|
||||
{t('code_example.search_button')}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
{isSearching && (
|
||||
<div role="status">
|
||||
<h3>
|
||||
{t('search_results_for')}: {search}
|
||||
</h3>
|
||||
<p className="mb-4">
|
||||
{t('matches_displayed')}: {searchResults.length}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
<ul data-testid="code-example-results" className="d-flex flex-wrap gutter">
|
||||
{(isSearching ? searchResults : productCodeExamples.slice(0, numVisible)).map((example) => {
|
||||
return (
|
||||
<li key={example.href} className="col-12 col-xl-4 col-lg-6 mb-4 list-style-none">
|
||||
<CodeExampleCard example={example} />
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
|
||||
{numVisible < productCodeExamples.length && !isSearching && (
|
||||
<button
|
||||
data-testid="code-examples-show-more"
|
||||
className="btn btn-outline float-right"
|
||||
onClick={() => setNumVisible(numVisible + PAGE_SIZE)}
|
||||
>
|
||||
{t('show_more')} <ArrowRightIcon />
|
||||
</button>
|
||||
)}
|
||||
|
||||
{isSearching && searchResults.length === 0 && (
|
||||
<div
|
||||
role="status"
|
||||
data-testid="code-examples-no-results"
|
||||
className="py-4 text-center color-fg-muted"
|
||||
>
|
||||
<div className="mb-3">
|
||||
<SearchIcon size={24} />{' '}
|
||||
</div>
|
||||
<h3 className="text-normal">
|
||||
{t('sorry')} <strong>{search}</strong>
|
||||
</h3>
|
||||
<p className="my-3 f4">
|
||||
{t('no_example')} <br /> {t('try_another')}
|
||||
</p>
|
||||
<Link href="https://github.com/github/docs/tree/main/data/product-examples">
|
||||
{t('learn')} <ArrowRightIcon />
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -7,7 +7,6 @@ import { FeaturedArticles } from 'components/landing/FeaturedArticles'
|
|||
import { GuideCards } from 'components/landing/GuideCards'
|
||||
import { SponsorsExamples } from 'components/landing/SponsorsExamples'
|
||||
import { CommunityExamples } from 'components/landing/CommunityExamples'
|
||||
import { CodeExamples } from 'components/landing/CodeExamples'
|
||||
import { LandingSection } from 'components/landing/LandingSection'
|
||||
import { useTranslation } from 'components/hooks/useTranslation'
|
||||
import { ProductArticlesList } from 'components/landing/ProductArticlesList'
|
||||
|
@ -18,14 +17,8 @@ import { RestRedirect } from 'components/RestRedirect'
|
|||
export const ProductLanding = () => {
|
||||
const router = useRouter()
|
||||
const { isEnterpriseServer } = useVersion()
|
||||
const {
|
||||
title,
|
||||
shortTitle,
|
||||
featuredLinks,
|
||||
productUserExamples,
|
||||
productCommunityExamples,
|
||||
productCodeExamples,
|
||||
} = useProductLandingContext()
|
||||
const { title, shortTitle, featuredLinks, productUserExamples, productCommunityExamples } =
|
||||
useProductLandingContext()
|
||||
const { t } = useTranslation('product_landing')
|
||||
|
||||
return (
|
||||
|
@ -40,16 +33,6 @@ export const ProductLanding = () => {
|
|||
<FeaturedArticles />
|
||||
</LandingSection>
|
||||
|
||||
{productCodeExamples.length > 0 && (
|
||||
<LandingSection
|
||||
title={t('code_examples')}
|
||||
sectionLink="code-examples"
|
||||
className="my-6 pb-6"
|
||||
>
|
||||
<CodeExamples />
|
||||
</LandingSection>
|
||||
)}
|
||||
|
||||
{productCommunityExamples.length > 0 && (
|
||||
<LandingSection title={t('communities_using_discussions')} className="my-6 pb-6">
|
||||
<CommunityExamples />
|
||||
|
|
|
@ -37,7 +37,6 @@ changelog:
|
|||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
examples_source: data/product-examples/code-security/code-examples.yml
|
||||
layout: product-landing
|
||||
versions:
|
||||
fpt: '*'
|
||||
|
|
|
@ -37,7 +37,6 @@ redirect_from:
|
|||
- /github/developing-online-with-github-codespaces
|
||||
- /github/developing-online-with-codespaces
|
||||
layout: product-landing
|
||||
examples_source: data/product-examples/codespaces/code-examples.yml
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
|
|
|
@ -2,18 +2,15 @@
|
|||
|
||||
Pages that use the `product-landing` layout may optionally include an `Examples` section. Currently, we support three types of examples:
|
||||
|
||||
1. Code examples
|
||||
See https://docs.github.com/en/codespaces#code-examples.
|
||||
|
||||
2. Community examples
|
||||
1. Community examples
|
||||
See https://docs.github.com/en/discussions#community-examples.
|
||||
|
||||
3. User examples
|
||||
2. User examples
|
||||
See https://docs.github.com/en/sponsors#community-examples.
|
||||
|
||||
## How it works
|
||||
|
||||
Example data for each product is defined in `data/product-landing-examples`, in a subdirectory named for the **product** and a YML file named for the **example type** (e.g., `data/product-examples/sponsors/user-examples.yml` or `data/product-examples/codespaces/code-examples.yml`). We currently only support one type of example per product.
|
||||
Example data for each product is defined in `data/product-landing-examples`, in a subdirectory named for the **product** and a YML file named for the **example type** (e.g., `data/product-examples/sponsors/user-examples.yml` or `data/product-examples/discussions/community-examples.yml`). We currently only support one type of example per product.
|
||||
|
||||
### Versioning
|
||||
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
# Code scanning configurations
|
||||
- title: CodeQL code scanning at Microsoft
|
||||
description: Example code scanning workflow for the CodeQL action from the Microsoft Open Source repository.
|
||||
href: /microsoft/opensource.microsoft.com/blob/main/.github/workflows/codeql-analysis.yml
|
||||
languages:
|
||||
- javascript
|
||||
tags:
|
||||
- CodeQL
|
||||
- Code scanning
|
||||
- GitHub Actions
|
||||
- title: Adversarial Robustness Toolbox (ART) CodeQL code scanning
|
||||
description: Example code scanning workflow for the CodeQL action from the Trusted AI repository.
|
||||
href: /Trusted-AI/adversarial-robustness-toolbox/blob/main/.github/workflows/codeql-analysis.yml
|
||||
languages:
|
||||
- python
|
||||
tags:
|
||||
- CodeQL
|
||||
- Code scanning
|
||||
- GitHub Actions
|
||||
|
||||
# Security policies
|
||||
- title: Microsoft security policy template
|
||||
description: Example security policy
|
||||
href: /microsoft/repo-templates/blob/main/shared/SECURITY.md
|
||||
tags:
|
||||
- Security policy
|
||||
- title: Electron security policy
|
||||
description: Example security policy
|
||||
href: /electron/electron/blob/master/SECURITY.md
|
||||
tags:
|
||||
- Security policy
|
||||
|
||||
# Example of security advisory in a major product
|
||||
- title: Security advisory for Rails
|
||||
description: Security advisory published by Rails for CVE-2020-15169.
|
||||
href: /rails/rails/security/advisories/GHSA-cfjv-5498-mph5
|
||||
tags:
|
||||
- Security advisory
|
||||
|
||||
# Sample scripts for enabling Dependabot alerts and security updates across a whole organization
|
||||
- title: Enable Dependabot alerts and security updates automatically
|
||||
description: Sample scripts for enabling Dependabot alerts and security updates across an entire organization.
|
||||
href: /github/enable-security-alerts-sample
|
||||
tags:
|
||||
- Dependabot
|
||||
- Alerts
|
||||
- Security updates
|
||||
- Organization
|
||||
- Scripts
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
ghes: '>=3.3'
|
||||
|
||||
# Dependabot configuration only relevant to GitHub.com and GHES 3.3+
|
||||
# Convert "languages" to "package-ecosystems" for Dependabot configurations
|
||||
- title: Super linter configuration
|
||||
description: Example Dependabot version updates configuration from the Super linter repository.
|
||||
href: /github/super-linter/blob/master/.github/dependabot.yml
|
||||
languages:
|
||||
- github-actions
|
||||
- npm
|
||||
- bundler
|
||||
- docker
|
||||
- pip
|
||||
tags:
|
||||
- Dependabot
|
||||
- Version updates
|
||||
- Configuration
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
ghes: '>=3.3'
|
||||
|
||||
- title: Dependabot version update PR
|
||||
description: Example pull request generated by the Dependabot version updates configuration in the Super linter repository.
|
||||
href: /github/super-linter/pull/1398
|
||||
languages:
|
||||
tags:
|
||||
- Dependabot
|
||||
- Version updates
|
||||
- Pull requests
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
ghes: '>=3.3'
|
|
@ -1,54 +0,0 @@
|
|||
- title: .NET sample project
|
||||
description: Try a .NET project with a custom dev container
|
||||
languages: .NET
|
||||
href: microsoft/vscode-remote-try-dotnet
|
||||
tags:
|
||||
- development containers
|
||||
- title: C++ sample project
|
||||
description: Try a C++ project with a custom dev container
|
||||
languages: C++
|
||||
href: microsoft/vscode-remote-try-cpp
|
||||
tags:
|
||||
- development containers
|
||||
- title: Java sample project
|
||||
description: Try a Java project with a custom dev container
|
||||
languages: Java
|
||||
href: microsoft/vscode-remote-try-java
|
||||
tags:
|
||||
- development containers
|
||||
- title: Node.js sample project
|
||||
description: Try a Node.js project with a custom dev container
|
||||
languages: Javascript
|
||||
href: microsoft/vscode-remote-try-node
|
||||
tags:
|
||||
- development containers
|
||||
- title: Go sample project
|
||||
description: Try a Go project with a custom dev container
|
||||
languages: Go
|
||||
href: microsoft/vscode-remote-try-go
|
||||
tags:
|
||||
- development containers
|
||||
- title: Python sample project
|
||||
description: Try a Python project with a custom dev container
|
||||
languages: Python
|
||||
href: microsoft/vscode-remote-try-python
|
||||
tags:
|
||||
- development containers
|
||||
- title: Rust sample project
|
||||
description: Try a Rust project with a custom dev container
|
||||
languages: Rust
|
||||
href: microsoft/vscode-remote-try-rust
|
||||
tags:
|
||||
- development containers
|
||||
- title: PHP sample project
|
||||
description: Try a PHP project with a custom dev container
|
||||
languages: PHP
|
||||
href: microsoft/vscode-remote-try-php
|
||||
tags:
|
||||
- development containers
|
||||
- title: Azure SQL and SQL Server sample project
|
||||
description: Try an Azure SQL or SQL Server project with a custom dev container
|
||||
languages: SQL
|
||||
href: microsoft/vscode-remote-try-sqlserver
|
||||
tags:
|
||||
- development containers
|
|
@ -1,4 +1,3 @@
|
|||
import getApplicableVersions from '../../lib/get-applicable-versions.js'
|
||||
import { getDataByLanguage } from '../../lib/get-data.js'
|
||||
|
||||
function getProductExampleData(product, key, language) {
|
||||
|
@ -34,23 +33,5 @@ export default async function productExamples(req, res, next) {
|
|||
currentLanguage
|
||||
)
|
||||
|
||||
const productCodeExamples = getProductExampleData(
|
||||
currentProduct,
|
||||
'code-examples',
|
||||
currentLanguage
|
||||
)
|
||||
|
||||
// We currently only support versioning in code examples.
|
||||
// TODO support versioning across all example types.
|
||||
req.context.productCodeExamples =
|
||||
productCodeExamples &&
|
||||
productCodeExamples.filter((example) => {
|
||||
// If an example block does NOT contain the versions prop, assume it's available in all versions
|
||||
return (
|
||||
!example.versions ||
|
||||
getApplicableVersions(example.versions).includes(req.context.currentVersion)
|
||||
)
|
||||
})
|
||||
|
||||
return next()
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ title: Code security documentation
|
|||
shortTitle: Code security
|
||||
intro: 'Code security'
|
||||
layout: product-landing
|
||||
examples_source: data/product-examples/code-security/code-examples.yml
|
||||
featuredLinks:
|
||||
startHere:
|
||||
- /code-security/getting-started/quickstart
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
# Code scanning configurations
|
||||
- title: CodeQL code scanning at Microsoft
|
||||
description: Example code scanning workflow for the CodeQL action from the Microsoft Open Source repository.
|
||||
href: /microsoft/opensource.microsoft.com/blob/main/.github/workflows/codeql-analysis.yml
|
||||
languages:
|
||||
- javascript
|
||||
tags:
|
||||
- CodeQL
|
||||
- Code scanning
|
||||
- GitHub Actions
|
||||
- title: Adversarial Robustness Toolbox (ART) CodeQL code scanning
|
||||
description: Example code scanning workflow for the CodeQL action from the Trusted AI repository.
|
||||
href: /Trusted-AI/adversarial-robustness-toolbox/blob/main/.github/workflows/codeql-analysis.yml
|
||||
languages:
|
||||
- python
|
||||
tags:
|
||||
- CodeQL
|
||||
- Code scanning
|
||||
- GitHub Actions
|
||||
|
||||
# Security policies
|
||||
- title: Microsoft security policy template
|
||||
description: Example security policy
|
||||
href: /microsoft/repo-templates/blob/main/shared/SECURITY.md
|
||||
tags:
|
||||
- Security policy
|
||||
- title: Electron security policy
|
||||
description: Example security policy
|
||||
href: /electron/electron/blob/master/SECURITY.md
|
||||
tags:
|
||||
- Security policy
|
||||
|
||||
# Example of security advisory in a major product
|
||||
- title: Security advisory for Rails
|
||||
description: Security advisory published by Rails for CVE-2020-15169.
|
||||
href: /rails/rails/security/advisories/GHSA-cfjv-5498-mph5
|
||||
tags:
|
||||
- Security advisory
|
||||
|
||||
# Sample scripts for enabling Dependabot alerts and security updates across a whole organization
|
||||
- title: Enable Dependabot alerts and security updates automatically
|
||||
description: Sample scripts for enabling Dependabot alerts and security updates across an entire organization.
|
||||
href: /github/enable-security-alerts-sample
|
||||
tags:
|
||||
- Dependabot
|
||||
- Alerts
|
||||
- Security updates
|
||||
- Organization
|
||||
- Scripts
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
ghes: '>=3.3'
|
||||
|
||||
# Dependabot configuration only relevant to GitHub.com and GHES 3.3+
|
||||
# Convert "languages" to "package-ecosystems" for Dependabot configurations
|
||||
- title: Super linter configuration
|
||||
description: Example Dependabot version updates configuration from the Super linter repository.
|
||||
href: /github/super-linter/blob/master/.github/dependabot.yml
|
||||
languages:
|
||||
- github-actions
|
||||
- npm
|
||||
- bundler
|
||||
- docker
|
||||
- pip
|
||||
tags:
|
||||
- Dependabot
|
||||
- Version updates
|
||||
- Configuration
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
ghes: '>=3.3'
|
||||
|
||||
- title: Dependabot version update PR
|
||||
description: Example pull request generated by the Dependabot version updates configuration in the Super linter repository.
|
||||
href: /github/super-linter/pull/1398
|
||||
languages:
|
||||
tags:
|
||||
- Dependabot
|
||||
- Version updates
|
||||
- Pull requests
|
||||
versions:
|
||||
fpt: '*'
|
||||
ghec: '*'
|
||||
ghes: '>=3.3'
|
|
@ -160,34 +160,6 @@ test('navigate with side bar into article inside a map-topic inside a category',
|
|||
await expect(page).toHaveURL(/actions\/category\/map-topic\/article/)
|
||||
})
|
||||
|
||||
test('code examples search', async ({ page }) => {
|
||||
await page.goto('/code-security')
|
||||
const codeExampleResults = page.getByTestId('code-example-results')
|
||||
|
||||
// more results after clicking the 'Show more' button
|
||||
const initialResultsCount = (await codeExampleResults.getByRole('listitem').all()).length
|
||||
await page.getByTestId('code-examples-show-more').click()
|
||||
const showedMoreResultsCount = (await codeExampleResults.getByRole('listitem').all()).length
|
||||
expect(showedMoreResultsCount).toBeGreaterThan(initialResultsCount)
|
||||
|
||||
// search for the 2 'policy' code examples
|
||||
await page.getByTestId('code-examples-input').click()
|
||||
await page.getByTestId('code-examples-input').fill('policy')
|
||||
await page.getByTestId('code-examples-search-btn').click()
|
||||
expect((await codeExampleResults.getByRole('listitem').all()).length).toBe(2)
|
||||
await expect(codeExampleResults.getByText('Microsoft security policy template')).toBeVisible()
|
||||
await expect(codeExampleResults.getByText('Electron security policy')).toBeVisible()
|
||||
|
||||
// what happens when there's no search results
|
||||
await page.getByTestId('code-examples-input').click()
|
||||
await page.getByTestId('code-examples-input').fill('should be no results')
|
||||
await page.getByTestId('code-examples-search-btn').click()
|
||||
await expect(page.locator('#code-examples').getByText('Matches displayed: 0')).toBeVisible()
|
||||
await expect(
|
||||
page.locator('#code-examples').getByText('Sorry, there is no result for should be no results')
|
||||
).toBeVisible()
|
||||
})
|
||||
|
||||
test('hovercards', async ({ page }) => {
|
||||
await page.goto('/pages/quickstart')
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче