refactor: use pre-built curriculum when starting client (#65878)

This commit is contained in:
Oliver Eyton-Williams
2026-02-19 08:55:33 +01:00
committed by GitHub
parent 052416e5bf
commit 990b64d229
10 changed files with 41 additions and 32 deletions
+9 -6
View File
@@ -2,10 +2,6 @@ const path = require('path');
const _ = require('lodash');
const {
getChallengesForLang
} = require('@freecodecamp/curriculum/get-challenges');
const {
getBlockCreator,
getSuperblocks,
@@ -14,12 +10,14 @@ const {
const {
getContentDir,
getBlockStructure,
getSuperblockStructure
getSuperblockStructure,
CURRICULUM_DIR
} = require('@freecodecamp/curriculum/file-handler');
const {
transformSuperBlock
} = require('@freecodecamp/curriculum/build-superblock');
const { getSuperOrder } = require('@freecodecamp/curriculum/super-order');
const { readFile } = require('fs/promises');
const curriculumLocale = process.env.CURRICULUM_LOCALE || 'english';
@@ -72,7 +70,12 @@ exports.replaceChallengeNodes = () => {
};
exports.buildChallenges = async function buildChallenges() {
const curriculum = await getChallengesForLang(curriculumLocale);
const curriculum = JSON.parse(
await readFile(
path.resolve(CURRICULUM_DIR, 'generated', 'curriculum.json'),
'utf-8'
)
);
const superBlocks = Object.keys(curriculum);
const blocks = superBlocks
.map(superBlock => curriculum[superBlock].blocks)
+9 -13
View File
@@ -1,4 +1,5 @@
import { resolve } from 'path';
import { resolve } from 'node:path';
import assert from 'node:assert';
import { config } from 'dotenv';
import { availableLangs } from '@freecodecamp/shared/config/i18n';
@@ -7,20 +8,15 @@ config({ path: resolve(__dirname, '../../.env') });
const curriculumLangs = availableLangs.curriculum;
// checks that the CURRICULUM_LOCALE exists and is an available language
export function testedLang() {
if (process.env.CURRICULUM_LOCALE) {
if (curriculumLangs.includes(process.env.CURRICULUM_LOCALE)) {
return process.env.CURRICULUM_LOCALE;
} else {
throw Error(`${process.env.CURRICULUM_LOCALE} is not a supported language.
Before the site can be built, this language needs to be manually approved`);
}
} else {
throw Error('CURRICULUM_LOCALE must be set for testing');
}
function isAllowedLang(lang: string): lang is (typeof curriculumLangs)[number] {
return curriculumLangs.includes(lang as (typeof curriculumLangs)[number]);
}
assert.ok(process.env.CURRICULUM_LOCALE);
assert.ok(isAllowedLang(process.env.CURRICULUM_LOCALE));
export const CURRICULUM_LOCALE = process.env.CURRICULUM_LOCALE;
export const SHOW_UPCOMING_CHANGES =
process.env.SHOW_UPCOMING_CHANGES === 'true';
+1 -1
View File
@@ -26,7 +26,7 @@ if (typeof __dirname !== 'undefined') {
__dirnameCompat = dirname(fileURLToPath(metaUrl));
}
const CURRICULUM_DIR = resolve(__dirnameCompat, '..');
export const CURRICULUM_DIR = resolve(__dirnameCompat, '..');
const I18N_CURRICULUM_DIR = resolve(
CURRICULUM_DIR,
'i18n-curriculum',
+2 -1
View File
@@ -2,10 +2,11 @@ import fs from 'fs';
import path from 'path';
import { getChallengesForLang } from '../get-challenges';
import { CURRICULUM_LOCALE } from '../config';
const globalConfigPath = path.resolve(__dirname, '../../generated/');
void getChallengesForLang('english')
void getChallengesForLang(CURRICULUM_LOCALE)
.then(JSON.stringify)
.then(json => {
fs.mkdirSync(globalConfigPath, { recursive: true });
+2 -2
View File
@@ -1,8 +1,8 @@
import path from 'node:path';
import { configure } from '@freecodecamp/challenge-linter';
import { testedLang } from './config';
import { CURRICULUM_LOCALE } from './config';
const CONFIG_PATH = path.resolve(__dirname, '../challenges/.markdownlint.yaml');
const { lintAll } = configure(CONFIG_PATH);
lintAll(`challenges/${testedLang()}/**/*.md`);
lintAll(`challenges/${CURRICULUM_LOCALE}/**/*.md`);
+3 -4
View File
@@ -4,12 +4,11 @@ vi.stubEnv('SHOW_UPCOMING_CHANGES', 'true');
// We need to use dynamic imports here to ensure the environment variable is set
// before the module is loaded.
const { testedLang } = await import('../config.js');
const { CURRICULUM_LOCALE } = await import('../config.js');
const { getChallenges } = await import('./test-challenges.js');
describe('Daily Coding Challenges', async () => {
const lang = testedLang();
const challenges = await getChallenges(lang, {
const challenges = await getChallenges(CURRICULUM_LOCALE, {
superBlock: 'dev-playground'
});
@@ -57,7 +56,7 @@ describe('Daily Coding Challenges', async () => {
}
// skip these for non-English for now.
if (lang !== 'english') continue;
if (CURRICULUM_LOCALE !== 'english') continue;
if (jsChallenge.title !== pyChallenge.title) {
errors.push(
+3 -4
View File
@@ -16,7 +16,7 @@ import { challengeSchemaValidator } from '../../schema/challenge-schema.js';
import { curriculumSchemaValidator } from '../../schema/curriculum-schema.js';
import { validateMetaSchema } from '../../schema/meta-schema.js';
import { getBlockStructure } from '../file-handler.js';
import { FCC_CHALLENGE_ID, testedLang } from '../config.js';
import { FCC_CHALLENGE_ID, CURRICULUM_LOCALE } from '../config.js';
import ChallengeTitles from './utils/challenge-titles.js';
import MongoIds from './utils/mongo-ids.js';
import createPseudoWorker from './utils/pseudo-worker.js';
@@ -79,8 +79,7 @@ async function newPageContext() {
}
export async function defineTestsForBlock(testFilter) {
const lang = testedLang();
const challenges = await getChallenges(lang, testFilter);
const challenges = await getChallenges(CURRICULUM_LOCALE, testFilter);
const nonCertificationChallenges = challenges.filter(
({ challengeType }) => challengeType !== 7
);
@@ -107,7 +106,7 @@ export async function defineTestsForBlock(testFilter) {
}
}
const challengeData = { meta, challenges, lang };
const challengeData = { meta, challenges, lang: CURRICULUM_LOCALE };
describe('Check challenges', async () => {
beforeAll(async () => {
+1 -1
View File
@@ -4,7 +4,7 @@
"tasks": {
"build": {
"outputs": ["dist/**", "generated/**"],
"env": ["FCC_*", "SHOW_UPCOMING_CHANGES"]
"env": ["FCC_*", "SHOW_UPCOMING_CHANGES", "CURRICULUM_LOCALE"]
},
"test": {
"passThroughEnv": ["VITEST_POOL_ID", "PUPPETEER_WS_ENDPOINT"],
+2
View File
@@ -26,6 +26,8 @@ RUN cd api && pnpm prisma generate
# following env vars.
ARG SHOW_UPCOMING_CHANGES=false
ENV SHOW_UPCOMING_CHANGES=$SHOW_UPCOMING_CHANGES
ARG CURRICULUM_LOCALE=english
ENV CURRICULUM_LOCALE=$CURRICULUM_LOCALE
RUN pnpm turbo -F=@freecodecamp/api build
@@ -0,0 +1,9 @@
{
"$schema": "https://v2-8-7.turborepo.dev/schema.json",
"extends": ["//"],
"tasks": {
"test": {
"env": ["CURRICULUM_LOCALE", "SHOW_UPCOMING_CHANGES"]
}
}
}