diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 719ef5afd86..f366ef8b185 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -118,6 +118,15 @@ jobs: - name: Checkout uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + # Uninstall man-db to prevent man page updates taking a long time after package installations + # on Ubuntu 24.04. + # https://github.com/actions/runner/issues/4030 + # https://github.com/actions/runner-images/issues/10977 + - name: Uninstall man-db + run: | + sudo apt-get update + sudo apt-get remove man-db + - name: Setup PNPM uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 diff --git a/docs/.pa11yci b/docs/.pa11yci deleted file mode 100644 index db117e4e3d1..00000000000 --- a/docs/.pa11yci +++ /dev/null @@ -1,10 +0,0 @@ -{ - "defaults": { - "runners": [ - "axe" - ], - "ignore": [ - "color-contrast" - ] - } -} diff --git a/docs/__a11y__/test-utils.ts b/docs/__a11y__/test-utils.ts index b2a9e9d7caa..bb3200c1573 100644 --- a/docs/__a11y__/test-utils.ts +++ b/docs/__a11y__/test-utils.ts @@ -7,6 +7,10 @@ import { } from 'axe-playwright'; import Sitemapper from 'sitemapper'; +// We use the Lunaria config to get the list of languages rather than the Astro config as importing +// the latter does not play well with Playwright. +import lunariaConfig from '../lunaria.config.json' assert { type: 'json' }; + export { expect, type Locator } from '@playwright/test'; const config: Config = { @@ -17,29 +21,35 @@ const config: Config = { values: ['wcag2a', 'wcag21a', 'wcag2aa', 'wcag21aa', 'wcag22aa', 'best-practice'], }, }, + // i18n specific configuration. + i18n: { + // A list of slugs to exclude from the sitemap for the default locale. + // By default, all slugs for the default locale are included. + exclude: [ + 'components/using-components', + 'getting-started', + 'guides/customization', + 'guides/i18n', + 'guides/overriding-components', + 'guides/pages', + 'guides/project-structure', + 'guides/route-data', + 'guides/site-search', + 'manual-setup', + 'reference/frontmatter', + 'reference/overrides', + 'reference/plugins', + 'reference/route-data', + ], + // Locale-specific included slugs (non-default locale slugs are excluded by default). + locales: { + ja: ['guides/route-data', 'reference/frontmatter'], + }, + }, // A list of violation to ignore. ignore: [{ id: 'landmark-unique', nodeMatcher: landmarkUniqueNodeMatcher }], sitemap: { url: 'http://localhost:4321/sitemap-index.xml', - exclude: { - // A pattern to exclude URLs from the sitemap. - pattern: /\/(de|zh-cn|fr|es|pt-br|pt-pt|it|id|ko|ru|tr|hi|da|uk)\/.*/, - // A list of slugs to exclude from the sitemap after processing the pattern. - slugs: [ - 'components/using-components', - 'getting-started', - 'guides/customization', - 'guides/i18n', - 'guides/overriding-components', - 'guides/pages', - 'guides/project-structure', - 'guides/site-search', - 'manual-setup', - 'reference/frontmatter', - 'reference/overrides', - 'reference/plugins', - ], - }, replace: { query: 'https://starlight.astro.build', value: 'http://localhost:4321', @@ -50,6 +60,8 @@ const config: Config = { process.env.ASTRO_TELEMETRY_DISABLED = 'true'; process.env.ASTRO_DISABLE_UPDATE_CHECK = 'true'; +const locales = lunariaConfig.locales.map((locale) => locale.lang); + export const test = baseTest.extend<{ docsSite: DocsSite; }>({ @@ -71,9 +83,24 @@ class DocsSite { const urls: string[] = []; for (const site of sites) { - const url = site.replace(config.sitemap.replace.query, config.sitemap.replace.value); - if (config.sitemap.exclude.pattern.test(url)) continue; - if (config.sitemap.exclude.slugs.some((slug) => url.endsWith(`/${slug}/`))) continue; + const slug = site.replace(config.sitemap.replace.query, ''); + const url = config.sitemap.replace.value + slug; + + // Default locale + if (!locales.some((locale) => slug.startsWith(`/${locale}/`))) { + // Skip default locale excluded slugs + if (config.i18n.exclude.some((excludedSlug) => slug.endsWith(`/${excludedSlug}/`))) + continue; + } else { + // Get locale-specific config + const locale = slug.split('/')[1]!; + const localeConfig = config.i18n.locales[locale]; + // Skip non-configured locales + if (!localeConfig) continue; + // Skip locale-specific non-included slugs + if (!localeConfig.some((includedSlug) => slug.endsWith(`/${includedSlug}/`))) continue; + } + urls.push(url); } @@ -129,6 +156,7 @@ function landmarkUniqueNodeMatcher(node: ViolationNode) { interface Config { axe: Parameters[2]; + i18n: { exclude: string[]; locales: Record }; ignore: Array< | string | { @@ -140,10 +168,6 @@ interface Config { >; sitemap: { url: string; - exclude: { - pattern: RegExp; - slugs: string[]; - }; replace: { query: string; value: string;