Co-authored-by: Rachael Sewell <rachmari@github.com>
This commit is contained in:
Grace Park 2023-05-09 12:39:36 -07:00 коммит произвёл GitHub
Родитель 61fd4ca80b
Коммит e8d75f960e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
18 изменённых файлов: 72 добавлений и 46 удалений

4
.github/workflows/test.yml поставляемый
Просмотреть файл

@ -47,7 +47,7 @@ jobs:
{ name: 'graphql', path: 'src/graphql/tests', },
{ name: 'rest', path: 'src/rest/tests', },
{ name: 'webhooks', path: 'src/webhooks/tests', },
{ name: 'linting', path: 'tests/linting', },
{ name: 'linting', path: 'src/content-linter/tests', },
{ name: 'meta', path: 'tests/meta', },
{ name: 'routing', path: 'tests/routing', },
{ name: 'rendering', path: 'tests/rendering', },
@ -140,7 +140,7 @@ jobs:
echo $DIFF
# So that becomes a string like `foo.js path/bar.md`
# Must to do this because the list of files can be HUGE. Especially
# Must do this because the list of files can be HUGE. Especially
# in a repo-sync when there are lots of translation files involved.
echo __ format, write to get_diff_files.txt __
echo $DIFF | tr '\n' ' ' > get_diff_files.txt

Просмотреть файл

@ -40,7 +40,7 @@ You cannot use `feature:` to specify multiple concurrent versions, as this is no
## Schema enforcement
The schema for validating the feature versioning lives in [`tests/helpers/schemas/feature-versions-schema.js`](/tests/helpers/schemas/feature-versions-schema.js) and is exercised by [`tests/linting/lint-versioning.js`](/tests/linting/lint-versioning.js).
The schema for validating the feature versioning lives in [`src/content-linter/lib/feature-versions-schema.js`](src/content-linter/lib/feature-versions-schema.js) and is exercised by [`tests/linting/lint-versioning.js`](tests/linting/lint-versioning.js).
## Script to remove feature tags

Просмотреть файл

@ -53,4 +53,4 @@ If the `versions` property is not included, it's assumed the track is available
## Schema enforcement
The schema for validating the learning track YAML lives in [`tests/helpers/schemas/learning-tracks-schema.js`](tests/helpers/schemas/learning-tracks-schema.js) and is exercised by [`tests/content/lint-files.js`](tests/content/lint-files.js).
The schema for validating the learning track YAML lives in [`src/content-linter/lib/learning-tracks-schema.js`](src/content-linter/lib/learning-tracks-schema.js) and is exercised by [`tests/content/lint-files.js`](tests/content/lint-files.js).

Просмотреть файл

@ -41,6 +41,6 @@ The release notes page has a custom design with CSS in `stylesheets/release-note
### Schema
The schema that validates the YAML data lives in `tests/helpers/schemas/release-notes-schema.js`. See the schema file to find out the required and optional properties.
The schema that validates the YAML data lives in `src/content-linter/lib/release-notes-schema.js`. See the schema file to find out the required and optional properties.
The schema is exercised by a test in `tests/linting/lint-files.js`. The test will fail if the data does not pass validation.
The schema is exercised by a test in `src/content-linter/tests/lint-files.js`. The test will fail if the data does not pass validation.

Просмотреть файл

@ -30,6 +30,6 @@ The release notes page has a custom design with CSS in `stylesheets/release-note
### Schema
The schema that validates the YAML data lives in `tests/helpers/schemas/release-notes-schema.js`. See the schema file to find out the required and optional properties.
The schema that validates the YAML data lives in `src/content-linter/lib/release-notes-schema.js`. See the schema file to find out the required and optional properties.
The schema is exercised by a test in `tests/linting/lint-files.js`. The test will fail if the data does not pass validation.
The schema is exercised by a test in `src/content-linter/tests/lint-files.js`. The test will fail if the data does not pass validation.

Просмотреть файл

@ -189,7 +189,7 @@
"fixture-test": "cross-env ROOT=tests/fixtures npm test -- tests/rendering-fixtures",
"index-test-fixtures": "node src/search/scripts/index-elasticsearch.js -l en -l ja -V ghae -V dotcom --index-prefix tests -- src/search/tests/fixtures/search-indexes",
"lint": "eslint '**/*.{js,mjs,ts,tsx}'",
"lint-translation": "cross-env NODE_OPTIONS=--experimental-vm-modules jest tests/linting/lint-files.js",
"lint-translation": "cross-env NODE_OPTIONS=--experimental-vm-modules jest src/content-linter/tests/lint-files.js",
"playwright-test": "playwright test --project=\"Google Chrome\"",
"prepare": "husky install",
"prettier": "prettier -w \"**/*.{ts,tsx,js,mjs,scss,yml,yaml}\"",

Просмотреть файл

@ -0,0 +1,21 @@
# Content Linter
## Linting Tests
- [lint-files](lint-files.js): Linter for `content`, `data/reusables`, `data/variables`, `data/glossaries`, `data/release-notes`, `data/learning-tracks`, and `data/features`. This lints markdown in the `content` and `data` directories, including early-access, GitHub Enterprise Server release notes, and yaml content. It checks for:
- No placeholder strings
- Hidden docs
- Transcripts
- Valid links
- Yaml content
- Early Access controls
- Hard-coded code/versions/domains
- Valid schema
- Valid liquid
- Valid syntax
- Valid frontmatter
- [lint-secret-scanning-data](lint-secret-scanning-data.js): Linter for `data/secret-scanning.yml`, which validates that the secret scanning data matches its schema.
- [lint-versioning](lint-versioning.js): This validates the `data/features` `versions` according to the same frontmatter schema.
- [category-pages](category-pages.js): This checks that the `children` frontmatter has a matching markdown article.
- [liquid-line-breaks](liquid-line-breaks.js): This will match Liquid variable references that contain at least one line break
between the variable reference and either the `{{` or `}}` tag boundaries.
- [site-data-references](site-data-references.js): Validates that any data reference found in the English content files is defined and has a value.

Просмотреть файл

Просмотреть файл

@ -2,20 +2,21 @@ import { fileURLToPath } from 'url'
import path from 'path'
import fs from 'fs'
import walk from 'walk-sync'
import matter from '../../lib/read-frontmatter.js'
import { zip, difference } from 'lodash-es'
import GithubSlugger from 'github-slugger'
import { decode } from 'html-entities'
import renderContent from '../../lib/render-content/index.js'
import getApplicableVersions from '../../lib/get-applicable-versions.js'
import contextualize from '../../middleware/context.js'
import shortVersions from '../../middleware/contextualizers/short-versions.js'
import matter from '../../../lib/read-frontmatter.js'
import renderContent from '../../../lib/render-content/index.js'
import getApplicableVersions from '../../../lib/get-applicable-versions.js'
import contextualize from '../../../middleware/context.js'
import shortVersions from '../../../middleware/contextualizers/short-versions.js'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const slugger = new GithubSlugger()
const contentDir = path.join(__dirname, '../../content')
const contentDir = path.join(__dirname, '../../../content')
describe('category pages', () => {
const walkOptions = {

Просмотреть файл

@ -12,17 +12,18 @@ import { visit } from 'unist-util-visit'
import fs from 'fs/promises'
import { existsSync } from 'fs'
import semver from 'semver'
import { frontmatter, deprecatedProperties } from '../../lib/frontmatter.js'
import languages from '../../lib/languages.js'
import { tags } from '../../lib/liquid-tags/extended-markdown.js'
import releaseNotesSchema from '../helpers/schemas/release-notes-schema.js'
import learningTracksSchema from '../helpers/schemas/learning-tracks-schema.js'
import renderContent from '../../lib/render-content/index.js'
import getApplicableVersions from '../../lib/get-applicable-versions.js'
import { allVersions } from '../../lib/all-versions.js'
import { jest } from '@jest/globals'
import { getDiffFiles } from '../helpers/diff-files.js'
import { formatAjvErrors } from '../helpers/schemas.js'
import { frontmatter, deprecatedProperties } from '../../../lib/frontmatter.js'
import languages from '../../../lib/languages.js'
import { tags } from '../../../lib/liquid-tags/extended-markdown.js'
import releaseNotesSchema from '../lib/release-notes-schema.js'
import learningTracksSchema from '../lib/learning-tracks-schema.js'
import renderContent from '../../../lib/render-content/index.js'
import getApplicableVersions from '../../../lib/get-applicable-versions.js'
import { allVersions } from '../../../lib/all-versions.js'
import { getDiffFiles } from '../lib/diff-files.js'
import { formatAjvErrors } from '../../../tests/helpers/schemas.js'
jest.useFakeTimers({ legacyFakeTimers: true })
@ -31,7 +32,7 @@ const enterpriseServerVersions = Object.keys(allVersions).filter((v) =>
v.startsWith('enterprise-server@')
)
const rootDir = path.join(__dirname, '../..')
const rootDir = path.join(__dirname, '../../..')
const contentDir = path.join(rootDir, 'content')
const reusablesDir = path.join(rootDir, 'data/reusables')
const variablesDir = path.join(rootDir, 'data/variables')

Просмотреть файл

@ -4,7 +4,9 @@ import { get } from 'lodash-es'
import Ajv from 'ajv'
import addErrors from 'ajv-errors'
import semver from 'semver'
import schema from '../helpers/schemas/secret-scanning-schema.js'
import schema from '../lib/secret-scanning-schema.js'
const data = yaml.load(fs.readFileSync('data/secret-scanning.yml', 'utf8'))
const ajv = new Ajv({ allErrors: true, allowUnionTypes: true })

Просмотреть файл

@ -3,14 +3,15 @@ import fs from 'fs/promises'
import Ajv from 'ajv'
import addErrors from 'ajv-errors'
import semver from 'semver'
import { allVersions, allVersionShortnames } from '../../lib/all-versions.js'
import { supported, next, nextNext, deprecated } from '../../lib/enterprise-server-releases.js'
import { getLiquidConditionals } from '../../script/helpers/get-liquid-conditionals.js'
import allowedVersionOperators from '../../lib/liquid-tags/ifversion-supported-operators.js'
import featureVersionsSchema from '../helpers/schemas/feature-versions-schema.js'
import walkFiles from '../../script/helpers/walk-files'
import { getDeepDataByLanguage } from '../../lib/get-data.js'
import { formatAjvErrors } from '../helpers/schemas.js'
import { allVersions, allVersionShortnames } from '../../../lib/all-versions.js'
import { supported, next, nextNext, deprecated } from '../../../lib/enterprise-server-releases.js'
import { getLiquidConditionals } from '../../../script/helpers/get-liquid-conditionals.js'
import allowedVersionOperators from '../../../lib/liquid-tags/ifversion-supported-operators.js'
import featureVersionsSchema from '../lib/feature-versions-schema.js'
import walkFiles from '../../../script/helpers/walk-files.js'
import { getDeepDataByLanguage } from '../../../lib/get-data.js'
import { formatAjvErrors } from '../../../tests/helpers/schemas.js'
/*
NOTE: This test suite does NOT validate the `versions` frontmatter in content files.

Просмотреть файл

@ -1,13 +1,14 @@
import { fileURLToPath } from 'url'
import path from 'path'
import walk from 'walk-sync'
import matter from '../../lib/read-frontmatter.js'
import { zip } from 'lodash-es'
import yaml from 'js-yaml'
import fs from 'fs/promises'
import matter from '../../../lib/read-frontmatter.js'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const rootDir = path.join(__dirname, '../..')
const rootDir = path.join(__dirname, '../../..')
const contentDir = path.join(rootDir, 'content')
const reusablesDir = path.join(rootDir, 'data/reusables')
const variablesDir = path.join(rootDir, 'data/variables')

Просмотреть файл

@ -1,14 +1,13 @@
import fs from 'fs/promises'
import { fileURLToPath } from 'url'
import path from 'path'
import { isEqual, uniqWith } from 'lodash-es'
import { jest } from '@jest/globals'
import { loadPages } from '../../lib/page-data.js'
import patterns from '../../lib/patterns.js'
import frontmatter from '../../lib/read-frontmatter.js'
import { getDataByLanguage, getDeepDataByLanguage } from '../../lib/get-data.js'
import { loadPages } from '../../../lib/page-data.js'
import patterns from '../../../lib/patterns.js'
import frontmatter from '../../../lib/read-frontmatter.js'
import { getDataByLanguage, getDeepDataByLanguage } from '../../../lib/get-data.js'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
@ -56,7 +55,7 @@ describe('data references', () => {
await Promise.all(
pages.map(async (page) => {
const metadataFile = path.join('content', page.relativePath)
const fileContents = await fs.readFile(path.join(__dirname, '../..', metadataFile))
const fileContents = await fs.readFile(path.join(__dirname, '../../..', metadataFile))
const { data: metadata } = frontmatter(fileContents, { filepath: page.fullPath })
const metadataRefs = getDataReferences(JSON.stringify(metadata))
metadataRefs.forEach((key) => {
@ -80,7 +79,7 @@ describe('data references', () => {
reusables.map(async (reusablesPerFile) => {
let reusableFile = path.join(
__dirname,
'../../data/reusables/',
'../../../data/reusables/',
getFilenameByValue(allReusables, reusablesPerFile)
)
reusableFile = await getFilepath(reusableFile)
@ -108,7 +107,7 @@ describe('data references', () => {
variables.map(async (variablesPerFile) => {
let variableFile = path.join(
__dirname,
'../../data/variables/',
'../../../data/variables/',
getFilenameByValue(allVariables, variablesPerFile)
)
variableFile = await getFilepath(variableFile)
@ -141,5 +140,5 @@ async function getFilepath(filepath) {
}
// we only need the relative path
return filepath.replace(path.join(__dirname, '../../'), '')
return filepath.replace(path.join(__dirname, '../../../'), '')
}