Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Comment on lines +121 to +129
Copy link
Member Author

@HiDeoo HiDeoo Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is something I discovered and investigated recently, but when Playwright installs browsers, on Ubuntu 24.04, it can randomly take a very long time to update the manual page index caches.

For example, in this run on this PR before this change, it took more than 1m30s (you need to scroll to the top, click on the settings icon, select Show timestamps and then go back to the Processing triggers for man-db line).

Considering we definitely don't need man pages, we uninstall the command ahead of the package installations.

If we agree to keep this workaround until this is fixed (I personally think we should), I'll backport it to our Linux e2e tests too that also installs some packages and can suffer from the same issue.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also spotted this just now: https://stevefenton.co.uk/blog/2025/09/playwright-insteall-github-actions/#fewer-dependencies

Seems a bit fragile but could be another optimization to test.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, definitely fragile (I would guess mostly around majors), but interesting nonetheless. With the current setup of this PR, dependencies takes 5 seconds, so I'm tempted to say it may not be worth it right now but something to keep in mind if it ever becomes more of a bottleneck?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah, could be that your fix has the same end result as theirs but with a much nicer (and I’d guess more stable) approach.

- name: Setup PNPM
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0

Expand Down
10 changes: 0 additions & 10 deletions docs/.pa11yci
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A leftover from when we removed Pa11y CI.

This file was deleted.

76 changes: 50 additions & 26 deletions docs/__a11y__/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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',
Expand All @@ -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;
}>({
Expand All @@ -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);
}

Expand Down Expand Up @@ -129,6 +156,7 @@ function landmarkUniqueNodeMatcher(node: ViolationNode) {

interface Config {
axe: Parameters<typeof getViolations>[2];
i18n: { exclude: string[]; locales: Record<string, string[]> };
ignore: Array<
| string
| {
Expand All @@ -140,10 +168,6 @@ interface Config {
>;
sitemap: {
url: string;
exclude: {
pattern: RegExp;
slugs: string[];
};
replace: {
query: string;
value: string;
Expand Down
Loading