Skip to content
Closed
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
1 change: 1 addition & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jobs:
run: npm run typecheck
- name: 🔤 Spell Check
run: npm run spellcheck
- uses: ./.github/workflows/actions/check-admonitions
- uses: ./.github/workflows/actions/check-translations
# Lint and spell check changes should be pushed
# to the branch before the branch is merge eligible.
Expand Down
92 changes: 92 additions & 0 deletions .github/workflows/actions/check-admonitions/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: 'Check Admonitions'
description: 'Fails on admonition titles using the MDX v1 syntax'
runs:
using: 'composite'
steps:
# `:::note My Title` was MDX v1 syntax that Docusaurus rewrote for us.
# With `future.v4.mdx1CompatDisabledByDefault` that shim is off, and
# the block `:::note My Title` stops being a directive: it renders as
# literal `:::note` text on the page, with no warning and a successful
# build.
#
# The other MDX v1 forms, HTML comments and `{#heading-ids}`, fail the
# build on their own, so this only covers the one that fails silently.
#
# Only the files the pull request touches are checked, so an existing
# page is never anyone else's problem to fix.
#
# The event payload has no file list, so the changed files come from a
# diff. The checkout is shallow and the base commit is fetched here
# rather than through `fetch-depth` on the checkout, which would pull
# the full history for every step in the job just to serve this one.
- name: 🔎 Check Admonitions
shell: bash
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
CHANGED_FILES: ${{ runner.temp }}/changed-files.txt
run: |
git fetch --quiet --no-tags --depth=1 origin "$BASE_SHA"
git diff --name-only --diff-filter=ACMR "$BASE_SHA" HEAD > "$CHANGED_FILES"
node <<'JS'
const { readFileSync } = require('fs');

// Files Docusaurus compiles as MDX. Under `static/usage` that is
// only the `index` files; the rest are raw code samples.
const compiled = (f) =>
!f.endsWith('README.md') &&
((/^(docs|versioned_docs|src\/pages)\//.test(f) && /\.mdx?$/.test(f)) ||
(f.startsWith('static/usage/') && f.endsWith('.mdx')));

// Defaults from `@docusaurus/mdx-loader/lib/remark/admonitions`.
const keywords =
'secondary|info|success|danger|note|tip|warning|important|caution';
const legacyTitle = new RegExp(
`^[ \\t]*:::(?:${keywords})[ \\t]+(?!\\[)\\S[^\\n]*`,
'gm'
);

// A `:::note` in a code sample is an example, not a directive.
// Blank out code samples with spaces, same length so line numbers
// still match.
const blank = (m) => m.replace(/[^\n]/g, ' ');
const mask = (t) =>
t
.replace(/^([ \t]*)(`{3,}|~{3,})[^\n]*\n[\s\S]*?^\1\2[ \t]*$/gm, blank)
.replace(/(`+)(?:(?!\1)[\s\S])+?\1/g, blank);

const files = readFileSync(process.env.CHANGED_FILES, 'utf8')
.split('\n')
.filter(compiled);

if (!files.length) {
console.log('No MDX files changed.');
process.exit(0);
}

const findings = [];
for (const file of files) {
const source = readFileSync(file, 'utf8');
for (const m of mask(source).matchAll(legacyTitle)) {
findings.push({
file,
line: source.slice(0, m.index).split('\n').length,
text: source.slice(m.index, m.index + m[0].length).trim(),
});
}
}

if (!findings.length) {
console.log(`No MDX v1 admonition titles in ${files.length} changed file(s).`);
process.exit(0);
}

// `::error` puts each one on the offending line in the Files changed
// tab and prints it in red in the log, so the failure is not something
// to go hunting for. The message leads with the fix because the found
// text starts with `:::`, which reads badly right after the delimiter.
for (const { file, line, text } of findings) {
const fix = 'Wrap the title in brackets, for example :::note[My Title]';
console.log(`::error file=${file},line=${line},title=MDX v1 admonition title::${fix}%0A%0AFound: ${text}`);
}
process.exit(1);
JS
24 changes: 24 additions & 0 deletions docs/reference/versioning.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,27 @@

For a list of all notable changes to Ionic please refer to the [changelog](https://github.com/ionic-team/ionic/blob/master/CHANGELOG.md). This contains an ordered
list of all bug fixes and new features under each release.

## CI Check Test

Temporary. This branch exists only to prove the Check Admonitions action fires.

:::note Legacy Title

Check failure on line 28 in docs/reference/versioning.mdx

View workflow job for this annotation

GitHub Actions / Test on macOS-latest

MDX v1 admonition title

Wrap the title in brackets, for example :::note[My Title] Found: :::note Legacy Title

Check failure on line 28 in docs/reference/versioning.mdx

View workflow job for this annotation

GitHub Actions / Test on windows-latest

MDX v1 admonition title

Wrap the title in brackets, for example :::note[My Title] Found: :::note Legacy Title
Should be reported: MDX v1 syntax, renders as literal text.
:::

:::tip[Bracketed Title]
Should not be reported: correct syntax.
:::

:::warning
Should not be reported: no title.
:::

```md
:::danger Inside A Fence
Should not be reported: an example in a code block.
:::
```

Inline too: `:::info Inside Code`
25 changes: 17 additions & 8 deletions docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,27 @@ module.exports = {
},
},
onBrokenLinks: 'warn',
/**
* Docusaurus Faster replaces the Webpack/Babel/Terser toolchain with
* Rspack/SWC/Lightning CSS, which cuts build times and memory usage on a
* site with this many versioned pages. It becomes the default in v4.
*
* `removeLegacyPostBuildHeadAttribute` is required by the `ssgWorkerThreads`
* part of `faster`, so it has to be enabled alongside it.
*/
future: {
v4: {
/**
* Turns off the MDX v1 shims for comments, admonition titles and
* heading ids. Every page uses the native syntax, so the shims are
* no-ops, and disabling them means a page that reintroduces the old
* syntax fails the build now rather than on the upgrade. It becomes
* the default in v4.
*/
mdx1CompatDisabledByDefault: true,
/**
* Required by the `ssgWorkerThreads` part of `faster`, so it has to
* be enabled alongside it. It becomes the default in v4.
*/
removeLegacyPostBuildHeadAttribute: true,
},
/**
* Replaces the Webpack/Babel/Terser toolchain with Rspack/SWC/Lightning
* CSS, which cuts build times and memory usage on a site with this many
* versioned pages. It becomes the default in v4.
*/
faster: true,
},
markdown: {
Expand Down
Loading