Skip to content

Commit 66d2131

Browse files
committed
feat(remark-lint): add
1 parent 8ab9cea commit 66d2131

28 files changed

+1312
-140
lines changed

.github/workflows/publish-packages.yml

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,25 @@ jobs:
7272
# If a specific package is requested via workflow_dispatch, just publish that one
7373
echo "matrix={\"package\":[\"$PACKAGE\"]}" >> $GITHUB_OUTPUT
7474
else
75-
# Otherwise, identify all packages with changes since the last commit
7675
CHANGED_PACKAGES=()
7776
for pkg in $(ls -d packages/*); do
7877
PKG_NAME=$(basename "$pkg")
79-
# For manual runs, include all packages. For automatic runs, only include packages with changes
78+
PKG_JSON="$pkg/package.json"
79+
80+
# Determine if the package has changed (or include all on manual trigger)
8081
if [ "$EVENT_NAME" == "workflow_dispatch" ] || ! git diff --quiet $COMMIT_SHA~1 $COMMIT_SHA -- "$pkg/"; then
81-
CHANGED_PACKAGES+=("$PKG_NAME")
82+
HAS_VERSION=$(jq 'has("version")' "$PKG_JSON")
83+
if [ "$HAS_VERSION" == "false" ]; then
84+
# Include packages without version field
85+
CHANGED_PACKAGES+=("$PKG_NAME")
86+
else
87+
# For packages with version field, include only if version changed
88+
OLD_VERSION=$(git show $COMMIT_SHA~1:$PKG_JSON | jq -r '.version')
89+
NEW_VERSION=$(jq -r '.version' "$PKG_JSON")
90+
if [ "$OLD_VERSION" != "$NEW_VERSION" ]; then
91+
CHANGED_PACKAGES+=("$PKG_NAME")
92+
fi
93+
fi
8294
fi
8395
done
8496
@@ -120,8 +132,12 @@ jobs:
120132
run: |
121133
# Install deps
122134
pnpm install --frozen-lockfile
123-
# Create a unique version using the commit SHA as a prerelease identifier
124-
npm version --no-git-tag-version 1.0.1-$COMMIT_SHA
135+
136+
HAS_VERSION=$(jq 'has("version")' package.json)
137+
if [ "$HAS_VERSION" == "false" ]; then
138+
# Only bump version if package has no version field
139+
npm version --no-git-tag-version 1.0.1-$COMMIT_SHA
140+
fi
125141
126142
# Check if a custom publish script exists in package.json
127143
if jq -e '.scripts.publish' package.json > /dev/null; then

apps/site/.remarkrc.json

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,3 @@
11
{
2-
"settings": {
3-
"bullet": "-",
4-
"resourceLink": true
5-
},
6-
"plugins": [
7-
"remark-frontmatter",
8-
"remark-preset-lint-node",
9-
["remark-gfm", false],
10-
["remark-lint-fenced-code-flag", false],
11-
["remark-lint-first-heading-level", false],
12-
["remark-lint-maximum-line-length", false],
13-
["remark-lint-no-file-name-articles", false],
14-
["remark-lint-no-literal-urls", false],
15-
["remark-lint-no-unused-definitions", false],
16-
["remark-lint-no-undefined-references", false],
17-
["remark-lint-prohibited-strings", false],
18-
["remark-lint-unordered-list-marker-style", "-"],
19-
["remark-preset-lint-node/remark-lint-nodejs-links.js", false]
20-
]
2+
"plugins": ["remark-frontmatter", "@node-core/remark-lint"]
213
}

apps/site/package.json

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
"@eslint/eslintrc": "~3.3.1",
8383
"@flarelabs-net/wrangler-build-time-fs-assets-polyfilling": "^0.0.1",
8484
"@next/eslint-plugin-next": "15.4.4",
85+
"@node-core/remark-lint": "workspace:*",
8586
"@opennextjs/cloudflare": "^1.6.4",
8687
"@playwright/test": "^1.54.1",
8788
"@testing-library/user-event": "~14.6.1",
@@ -95,17 +96,7 @@
9596
"global-jsdom": "^26.0.0",
9697
"handlebars": "4.7.8",
9798
"jsdom": "^26.0.0",
98-
"remark-frontmatter": "5.0.0",
99-
"remark-lint-fenced-code-flag": "^4.2.0",
100-
"remark-lint-first-heading-level": "^4.0.1",
101-
"remark-lint-maximum-line-length": "^4.1.1",
102-
"remark-lint-no-file-name-articles": "^3.0.1",
103-
"remark-lint-no-literal-urls": "^4.0.1",
104-
"remark-lint-no-undefined-references": "^5.0.2",
105-
"remark-lint-no-unused-definitions": "^4.0.2",
106-
"remark-lint-prohibited-strings": "^4.0.0",
107-
"remark-lint-unordered-list-marker-style": "^4.0.1",
108-
"remark-preset-lint-node": "5.1.2",
99+
"remark-frontmatter": "^5.0.0",
109100
"stylelint": "16.23.0",
110101
"stylelint-config-standard": "39.0.0",
111102
"stylelint-order": "7.0.0",
@@ -127,4 +118,4 @@
127118
"./*/index.mjs"
128119
]
129120
}
130-
}
121+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"**/*.{js,mjs,ts,tsx,md,mdx}": ["prettier --check --write", "eslint --fix"],
3+
"**/*.{json,yml}": ["prettier --check --write"]
4+
}

packages/remark-lint/README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# `@node-core/remark-lint`
2+
3+
A [`remark-lint`](https://github.com/remarkjs/remark-lint) plugin with configurations tailored to the documentation and contribution standards of the [Node.js GitHub Organization](https://github.com/nodejs).
4+
5+
## Installation
6+
7+
```bash
8+
npm install --save-dev @node-core/remark-lint
9+
```
10+
11+
## Usage
12+
13+
Add the plugin to your `.remarkrc` or `remark.config.js`:
14+
15+
```json
16+
{
17+
"plugins": ["@node-core/remark-lint"]
18+
}
19+
```
20+
21+
You can then run `remark` over your markdown files:
22+
23+
```bash
24+
npx remark . --frail
25+
```
26+
27+
## Settings
28+
29+
### `NODE_RELEASED_VERSIONS`
30+
31+
Some lint rules (such as `node-core:yaml-comments`) require knowledge of released Node.js versions to validate version references.
32+
33+
You can provide these using the `NODE_RELEASED_VERSIONS` environment variable:
34+
35+
```bash
36+
NODE_RELEASED_VERSIONS=20.12.0,18.19.1,16.20.2 npx remark .
37+
```
38+
39+
If not set, version-related rules will accept any valid SemVer.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import globals from 'globals';
2+
3+
import baseConfig from '../../eslint.config.js';
4+
5+
export default [
6+
...baseConfig,
7+
{
8+
languageOptions: {
9+
globals: globals.nodeBuiltin,
10+
parserOptions: {
11+
// Allow nullish syntax (i.e. "?." or "??"),
12+
// and top-level await
13+
ecmaVersion: 'latest',
14+
},
15+
},
16+
},
17+
];

packages/remark-lint/package.json

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
{
2+
"name": "@node-core/remark-lint",
3+
"type": "module",
4+
"version": "1.0.0",
5+
"exports": {
6+
".": "./src/index.mjs",
7+
"./api": "./src/api.mjs"
8+
},
9+
"scripts": {
10+
"lint": "node --run lint:js",
11+
"lint:fix": "node --run lint:js:fix",
12+
"lint:js": "eslint \"**/*.mjs\"",
13+
"lint:js:fix": "node --run lint:js -- --fix",
14+
"test": "node --run test:unit",
15+
"test:unit": "cross-env NODE_NO_WARNINGS=1 node --experimental-test-coverage --test \"**/*.test.mjs\""
16+
},
17+
"dependencies": {
18+
"remark-gfm": "~4.0.1",
19+
"remark-lint-blockquote-indentation": "^4.0.1",
20+
"remark-lint-checkbox-character-style": "^5.0.1",
21+
"remark-lint-checkbox-content-indent": "^5.0.1",
22+
"remark-lint-code-block-style": "^4.0.1",
23+
"remark-lint-definition-spacing": "^4.0.1",
24+
"remark-lint-fenced-code-flag": "^4.2.0",
25+
"remark-lint-fenced-code-marker": "^4.0.1",
26+
"remark-lint-file-extension": "^3.0.1",
27+
"remark-lint-final-definition": "^4.0.2",
28+
"remark-lint-heading-style": "^4.0.1",
29+
"remark-lint-maximum-line-length": "^4.1.1",
30+
"remark-lint-no-consecutive-blank-lines": "^5.0.1",
31+
"remark-lint-no-file-name-consecutive-dashes": "^3.0.1",
32+
"remark-lint-no-file-name-outer-dashes": "^3.0.1",
33+
"remark-lint-no-heading-indent": "^5.0.1",
34+
"remark-lint-no-literal-urls": "^4.0.1",
35+
"remark-lint-no-multiple-toplevel-headings": "^4.0.1",
36+
"remark-lint-no-shell-dollars": "^4.0.1",
37+
"remark-lint-no-table-indentation": "^5.0.1",
38+
"remark-lint-no-tabs": "^4.0.1",
39+
"remark-lint-no-trailing-spaces": "^3.0.2",
40+
"remark-lint-no-unused-definitions": "^4.0.2",
41+
"remark-lint-prohibited-strings": "^4.0.0",
42+
"remark-lint-rule-style": "^4.0.1",
43+
"remark-lint-strong-marker": "^4.0.1",
44+
"remark-lint-table-cell-padding": "^5.1.1",
45+
"remark-lint-table-pipes": "^5.0.1",
46+
"remark-lint-unordered-list-marker-style": "^4.0.1",
47+
"remark-preset-lint-recommended": "^7.0.1",
48+
"semver": "~7.7.2",
49+
"unified-lint-rule": "^3.0.1",
50+
"unist-util-visit": "^5.0.0",
51+
"yaml": "^2.8.0"
52+
},
53+
"devDependencies": {
54+
"cross-env": "catalog:",
55+
"dedent": "^1.6.0",
56+
"globals": "^16.3.0",
57+
"remark-parse": "^11.0.0",
58+
"unified": "^11.0.5"
59+
}
60+
}

packages/remark-lint/src/api.mjs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import remarkGfm from 'remark-gfm';
2+
import remarkLintFencedCodeFlag from 'remark-lint-fenced-code-flag';
3+
import remarkLintMaximumLineLength from 'remark-lint-maximum-line-length';
4+
import remarkLintNoUnusedDefinitions from 'remark-lint-no-unused-definitions';
5+
import remarkLintProhibitedStrings from 'remark-lint-prohibited-strings';
6+
import remarkLintUnorderedListMarkerStyle from 'remark-lint-unordered-list-marker-style';
7+
8+
import basePreset from './index.mjs';
9+
import duplicateStabilityNodes from './rules/duplicate-stability-nodes.mjs';
10+
import hashedSelfReference from './rules/hashed-self-reference.mjs';
11+
import orderedReferences from './rules/ordered-references.mjs';
12+
import requiredMetadata from './rules/required-metadata.mjs';
13+
import yamlComments from './rules/yaml/index.mjs';
14+
15+
export default {
16+
settings: {
17+
...basePreset.settings,
18+
bullet: '*',
19+
},
20+
plugins: [
21+
remarkGfm,
22+
...basePreset.plugins,
23+
duplicateStabilityNodes,
24+
yamlComments,
25+
hashedSelfReference,
26+
orderedReferences,
27+
requiredMetadata,
28+
remarkLintNoUnusedDefinitions,
29+
[remarkLintFencedCodeFlag, { allowEmpty: false }],
30+
[remarkLintMaximumLineLength, 120],
31+
[remarkLintUnorderedListMarkerStyle, '*'],
32+
[
33+
remarkLintProhibitedStrings,
34+
[
35+
{ yes: 'End-of-Life' },
36+
{ no: 'filesystem', yes: 'file system' },
37+
{ yes: 'GitHub' },
38+
{ no: 'hostname', yes: 'host name' },
39+
{ yes: 'JavaScript' },
40+
{ no: '[Ll]ong[ -][Tt]erm [Ss]upport', yes: 'Long Term Support' },
41+
{ no: 'Node', yes: 'Node.js', ignoreNextTo: '-API' },
42+
{ yes: 'Node.js' },
43+
{ no: 'Node[Jj][Ss]', yes: 'Node.js' },
44+
{ no: "Node\\.js's?", yes: 'the Node.js' },
45+
{ no: '[Nn]ote that', yes: '<nothing>' },
46+
{ yes: 'RFC' },
47+
{ no: '[Rr][Ff][Cc]\\d+', yes: 'RFC <number>' },
48+
{ yes: 'TypeScript' },
49+
{ yes: 'Unix' },
50+
{ yes: 'Valgrind' },
51+
{ yes: 'V8' },
52+
],
53+
],
54+
],
55+
};

packages/remark-lint/src/index.mjs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import remarkLintBlockquoteIndentation from 'remark-lint-blockquote-indentation';
2+
import remarkLintCheckboxCharacterStyle from 'remark-lint-checkbox-character-style';
3+
import remarkLintCheckboxContentIndent from 'remark-lint-checkbox-content-indent';
4+
import remarkLintCodeBlockStyle from 'remark-lint-code-block-style';
5+
import remarkLintDefinitionSpacing from 'remark-lint-definition-spacing';
6+
import remarkLintFencedCodeMarker from 'remark-lint-fenced-code-marker';
7+
import remarkLintFileExtension from 'remark-lint-file-extension';
8+
import remarkLintFinalDefinition from 'remark-lint-final-definition';
9+
import remarkLintHeadingStyle from 'remark-lint-heading-style';
10+
import remarkLintNoConsecutiveBlankLines from 'remark-lint-no-consecutive-blank-lines';
11+
import remarkLintNoFileNameConsecutiveDashes from 'remark-lint-no-file-name-consecutive-dashes';
12+
import remarkLintNofileNameOuterDashes from 'remark-lint-no-file-name-outer-dashes';
13+
import remarkLintNoHeadingIndent from 'remark-lint-no-heading-indent';
14+
import remarkLintNoLiteralURLs from 'remark-lint-no-literal-urls';
15+
import remarkLintNoMultipleToplevelHeadings from 'remark-lint-no-multiple-toplevel-headings';
16+
import remarkLintNoShellDollars from 'remark-lint-no-shell-dollars';
17+
import remarkLintNoTableIndentation from 'remark-lint-no-table-indentation';
18+
import remarkLintNoTabs from 'remark-lint-no-tabs';
19+
import remarkLintNoTrailingSpaces from 'remark-lint-no-trailing-spaces';
20+
import remarkLintNoUnusedDefinitions from 'remark-lint-no-unused-definitions';
21+
import remarkLintRuleStyle from 'remark-lint-rule-style';
22+
import remarkLintStrongMarker from 'remark-lint-strong-marker';
23+
import remarkLintTableCellPadding from 'remark-lint-table-cell-padding';
24+
import remarkLintTablePipes from 'remark-lint-table-pipes';
25+
import remarkPresetLintRecommended from 'remark-preset-lint-recommended';
26+
27+
export default {
28+
settings: {
29+
tightDefinitions: true,
30+
emphasis: '_',
31+
bullet: '-',
32+
rule: '-',
33+
},
34+
plugins: [
35+
// Base plugins
36+
remarkPresetLintRecommended,
37+
38+
// Blockquote and list rules
39+
[remarkLintBlockquoteIndentation, 2],
40+
[remarkLintCheckboxCharacterStyle, { checked: 'x', unchecked: ' ' }],
41+
remarkLintCheckboxContentIndent,
42+
43+
// Code and formatting rules
44+
[remarkLintCodeBlockStyle, 'fenced'],
45+
[remarkLintFencedCodeMarker, '`'],
46+
[remarkLintRuleStyle, '---'],
47+
[remarkLintStrongMarker, '*'],
48+
49+
// File and filename rules
50+
[remarkLintFileExtension, 'md'],
51+
remarkLintNoFileNameConsecutiveDashes,
52+
remarkLintNofileNameOuterDashes,
53+
54+
// Heading and link rules
55+
remarkLintFinalDefinition,
56+
[remarkLintNoUnusedDefinitions, false],
57+
[remarkLintNoLiteralURLs, false],
58+
[remarkLintHeadingStyle, 'atx'],
59+
remarkLintNoHeadingIndent,
60+
remarkLintNoMultipleToplevelHeadings,
61+
62+
// Layout and spacing rules
63+
remarkLintDefinitionSpacing,
64+
remarkLintNoConsecutiveBlankLines,
65+
remarkLintNoTableIndentation,
66+
remarkLintNoTabs,
67+
remarkLintNoTrailingSpaces,
68+
[remarkLintTableCellPadding, 'padded'],
69+
remarkLintTablePipes,
70+
71+
// Shell and console rules
72+
remarkLintNoShellDollars,
73+
],
74+
};

0 commit comments

Comments
 (0)