@@ -4,23 +4,16 @@ import slash from 'slash'
44import walk from 'walk-sync'
55import { zip } from 'lodash-es'
66import yaml from 'js-yaml'
7- import Ajv from 'ajv'
8- import addErrors from 'ajv-errors'
9- import addFormats from 'ajv-formats'
107import { fromMarkdown } from 'mdast-util-from-markdown'
118import { visit } from 'unist-util-visit'
129import fs from 'fs/promises'
1310import { existsSync } from 'fs'
14- import semver from 'semver'
1511import { jest } from '@jest/globals'
1612
1713import { frontmatter , deprecatedProperties } from '../../../lib/frontmatter.js'
1814import languages from '#src/languages/lib/languages.js'
19- import releaseNotesSchema from '../lib/release-notes-schema.js'
20- import learningTracksSchema from '../lib/learning-tracks-schema.js'
2115import { liquid } from '#src/content-render/index.js'
2216import { getDiffFiles } from '../lib/diff-files.js'
23- import { formatAjvErrors } from '../../../tests/helpers/schemas.js'
2417
2518jest . useFakeTimers ( { legacyFakeTimers : true } )
2619
@@ -31,9 +24,6 @@ const contentDir = path.join(rootDir, 'content')
3124const reusablesDir = path . join ( rootDir , 'data/reusables' )
3225const variablesDir = path . join ( rootDir , 'data/variables' )
3326const glossariesDir = path . join ( rootDir , 'data/glossaries' )
34- const ghesReleaseNotesDir = path . join ( rootDir , 'data/release-notes/enterprise-server' )
35- const ghaeReleaseNotesDir = path . join ( rootDir , 'data/release-notes/github-ae' )
36- const learningTracks = path . join ( rootDir , 'data/learning-tracks' )
3727const fbvDir = path . join ( rootDir , 'data/features' )
3828
3929const languageCodes = Object . keys ( languages )
@@ -217,7 +207,7 @@ const yamlWalkOptions = {
217207}
218208
219209// different lint rules apply to different content types
220- let mdToLint , ymlToLint , ghesReleaseNotesToLint , ghaeReleaseNotesToLint , learningTracksToLint
210+ let mdToLint , ymlToLint
221211
222212// compile lists of all the files we want to lint
223213
@@ -294,35 +284,11 @@ const FbvYamlAbsPaths = walk(fbvDir, yamlWalkOptions).sort()
294284const FbvYamlRelPaths = FbvYamlAbsPaths . map ( ( p ) => slash ( path . relative ( rootDir , p ) ) )
295285const fbvTuples = zip ( FbvYamlRelPaths , FbvYamlAbsPaths )
296286
297- // GHES release notes
298- const ghesReleaseNotesYamlAbsPaths = walk ( ghesReleaseNotesDir , yamlWalkOptions ) . sort ( )
299- const ghesReleaseNotesYamlRelPaths = ghesReleaseNotesYamlAbsPaths . map ( ( p ) =>
300- slash ( path . relative ( rootDir , p ) ) ,
301- )
302- ghesReleaseNotesToLint = zip ( ghesReleaseNotesYamlRelPaths , ghesReleaseNotesYamlAbsPaths )
303-
304- // GHAE release notes
305- const ghaeReleaseNotesYamlAbsPaths = walk ( ghaeReleaseNotesDir , yamlWalkOptions ) . sort ( )
306- const ghaeReleaseNotesYamlRelPaths = ghaeReleaseNotesYamlAbsPaths . map ( ( p ) =>
307- slash ( path . relative ( rootDir , p ) ) ,
308- )
309- ghaeReleaseNotesToLint = zip ( ghaeReleaseNotesYamlRelPaths , ghaeReleaseNotesYamlAbsPaths )
310-
311- // Learning tracks
312- const learningTracksYamlAbsPaths = walk ( learningTracks , yamlWalkOptions ) . sort ( )
313- const learningTracksYamlRelPaths = learningTracksYamlAbsPaths . map ( ( p ) =>
314- slash ( path . relative ( rootDir , p ) ) ,
315- )
316- learningTracksToLint = zip ( learningTracksYamlRelPaths , learningTracksYamlAbsPaths )
317-
318287// Put all the yaml files together
319288ymlToLint = [ ] . concat (
320289 variableYamlTuples , // These "tuples" not tested independently; they are only tested as part of ymlToLint.
321290 glossariesYamlTuples ,
322291 fbvTuples ,
323- ghesReleaseNotesToLint ,
324- ghaeReleaseNotesToLint ,
325- learningTracksToLint ,
326292)
327293
328294function formatLinkError ( message , links ) {
@@ -361,19 +327,9 @@ if (diffFiles.length > 0) {
361327 )
362328 mdToLint = filterFiles ( mdToLint )
363329 ymlToLint = filterFiles ( ymlToLint )
364- ghesReleaseNotesToLint = filterFiles ( ghesReleaseNotesToLint )
365- ghaeReleaseNotesToLint = filterFiles ( ghaeReleaseNotesToLint )
366- learningTracksToLint = filterFiles ( learningTracksToLint )
367330}
368331
369- if (
370- mdToLint . length +
371- ymlToLint . length +
372- ghesReleaseNotesToLint . length +
373- ghaeReleaseNotesToLint . length +
374- learningTracksToLint . length <
375- 1
376- ) {
332+ if ( mdToLint . length + ymlToLint . length < 1 ) {
377333 // With this in place, at least one `test()` is called and you don't
378334 // get the `Your test suite must contain at least one test.` error
379335 // from `jest`.
@@ -382,18 +338,6 @@ if (
382338 } )
383339}
384340
385- // ajv for schema validation tests
386- const ajv = new Ajv ( { allErrors : true , allowUnionTypes : true } )
387- addFormats ( ajv )
388- addErrors ( ajv )
389- // *** TODO: We can drop this override once the frontmatter schema has been updated to work with AJV. ***
390- ajv . addFormat ( 'semver' , {
391- validate : ( x ) => semver . validRange ( x ) ,
392- } )
393- // *** End TODO ***
394- const ghesValidate = ajv . compile ( releaseNotesSchema )
395- const learningTracksValidate = ajv . compile ( learningTracksSchema )
396-
397341describe ( 'lint markdown content' , ( ) => {
398342 if ( mdToLint . length < 1 ) return
399343
@@ -881,167 +825,3 @@ describe('lint yaml content', () => {
881825 } )
882826 } )
883827} )
884-
885- describe ( 'lint GHES release notes' , ( ) => {
886- if ( ghesReleaseNotesToLint . length < 1 ) return
887- describe . each ( ghesReleaseNotesToLint ) ( '%s' , ( yamlRelPath , yamlAbsPath ) => {
888- let dictionary
889- let dictionaryError = false
890-
891- beforeAll ( async ( ) => {
892- const fileContents = await fs . readFile ( yamlAbsPath , 'utf8' )
893- try {
894- dictionary = yaml . load ( fileContents , { filename : yamlRelPath } )
895- } catch ( error ) {
896- dictionaryError = error
897- }
898- } )
899-
900- it ( 'can be parsed as a single yaml document' , ( ) => {
901- expect ( dictionaryError ) . toBe ( false )
902- } )
903-
904- it ( 'matches the schema' , ( ) => {
905- const valid = ghesValidate ( dictionary )
906- let errors
907-
908- if ( ! valid ) {
909- errors = formatAjvErrors ( ghesValidate . errors )
910- }
911-
912- expect ( valid , errors ) . toBe ( true )
913- } )
914-
915- it ( 'contains valid liquid' , ( ) => {
916- const { intro, sections } = dictionary
917- let toLint = { intro }
918- for ( const key in sections ) {
919- const section = sections [ key ]
920- const label = `sections.${ key } `
921- section . forEach ( ( part ) => {
922- if ( Array . isArray ( part ) ) {
923- toLint = { ...toLint , ...{ [ label ] : section . join ( '\n' ) } }
924- } else {
925- for ( const prop in section ) {
926- toLint = { ...toLint , ...{ [ `${ label } .${ prop } ` ] : section [ prop ] } }
927- }
928- }
929- } )
930- }
931-
932- for ( const key in toLint ) {
933- if ( ! toLint [ key ] ) continue
934- expect ( ( ) => liquid . parse ( toLint [ key ] ) , `${ key } contains invalid liquid` ) . not . toThrow ( )
935- }
936- } )
937- } )
938- } )
939-
940- describe ( 'lint GHAE release notes' , ( ) => {
941- if ( ghaeReleaseNotesToLint . length < 1 ) return
942- const currentWeeksFound = [ ]
943- describe . each ( ghaeReleaseNotesToLint ) ( '%s' , ( yamlRelPath , yamlAbsPath ) => {
944- let dictionary
945- let dictionaryError = false
946-
947- beforeAll ( async ( ) => {
948- const fileContents = await fs . readFile ( yamlAbsPath , 'utf8' )
949- try {
950- dictionary = yaml . load ( fileContents , { filename : yamlRelPath } )
951- } catch ( error ) {
952- dictionaryError = error
953- }
954- } )
955-
956- it ( 'can be parsed as a single yaml document' , ( ) => {
957- expect ( dictionaryError ) . toBe ( false )
958- } )
959-
960- it ( 'matches the schema' , ( ) => {
961- const valid = ghesValidate ( dictionary )
962- let errors
963-
964- if ( ! valid ) {
965- errors = formatAjvErrors ( ghesValidate . errors )
966- }
967-
968- expect ( valid , errors ) . toBe ( true )
969- } )
970-
971- it ( 'does not have more than one yaml file with currentWeek set to true' , ( ) => {
972- if ( dictionary . currentWeek ) currentWeeksFound . push ( yamlRelPath )
973- const errorMessage = `Found more than one file with currentWeek set to true: ${ currentWeeksFound . join (
974- '\n' ,
975- ) } `
976- expect ( currentWeeksFound . length , errorMessage ) . not . toBeGreaterThan ( 1 )
977- } )
978-
979- it ( 'contains valid liquid' , ( ) => {
980- const { intro, sections } = dictionary
981- let toLint = { intro }
982- for ( const key in sections ) {
983- const section = sections [ key ]
984- const label = `sections.${ key } `
985- section . forEach ( ( part ) => {
986- if ( Array . isArray ( part ) ) {
987- toLint = { ...toLint , ...{ [ label ] : section . join ( '\n' ) } }
988- } else {
989- for ( const prop in section ) {
990- toLint = { ...toLint , ...{ [ `${ label } .${ prop } ` ] : section [ prop ] } }
991- }
992- }
993- } )
994- }
995-
996- for ( const key in toLint ) {
997- if ( ! toLint [ key ] ) continue
998- expect ( ( ) => liquid . parse ( toLint [ key ] ) , `${ key } contains invalid liquid` ) . not . toThrow ( )
999- }
1000- } )
1001- } )
1002- } )
1003-
1004- describe ( 'lint learning tracks' , ( ) => {
1005- if ( learningTracksToLint . length < 1 ) return
1006-
1007- describe . each ( learningTracksToLint ) ( '%s' , ( yamlRelPath , yamlAbsPath ) => {
1008- let dictionary
1009- let dictionaryError = false
1010-
1011- beforeAll ( async ( ) => {
1012- const fileContents = await fs . readFile ( yamlAbsPath , 'utf8' )
1013- try {
1014- dictionary = yaml . load ( fileContents , { filename : yamlRelPath } )
1015- } catch ( error ) {
1016- dictionaryError = error
1017- }
1018- } )
1019-
1020- it ( 'can be parsed as a single yaml document' , ( ) => {
1021- expect ( dictionaryError ) . toBe ( false )
1022- } )
1023-
1024- it ( 'matches the schema' , ( ) => {
1025- const valid = learningTracksValidate ( dictionary )
1026- let errors
1027-
1028- if ( ! valid ) {
1029- errors = formatAjvErrors ( learningTracksValidate . errors )
1030- }
1031-
1032- expect ( valid , errors ) . toBe ( true )
1033- } )
1034-
1035- it ( 'contains valid liquid' , ( ) => {
1036- const toLint = [ ]
1037- Object . values ( dictionary ) . forEach ( ( { title, description } ) => {
1038- toLint . push ( title )
1039- toLint . push ( description )
1040- } )
1041-
1042- toLint . forEach ( ( element ) => {
1043- expect ( ( ) => liquid . parse ( element ) , `${ element } contains invalid liquid` ) . not . toThrow ( )
1044- } )
1045- } )
1046- } )
1047- } )
0 commit comments