Skip to content

Commit 518c1bd

Browse files
authored
Merge pull request #40948 from github/repo-sync
Repo sync
2 parents 9aa793d + b61005d commit 518c1bd

File tree

23 files changed

+404
-169
lines changed

23 files changed

+404
-169
lines changed

.github/workflows/package-lock-lint.yml

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ jobs:
3737
run: |
3838
npm --version
3939
40+
# Save the current top-level dependencies from package-lock.json
41+
node -e "console.log(JSON.stringify(require('./package-lock.json').packages['']))" > /tmp/before.json
42+
4043
# From https://docs.npmjs.com/cli/v7/commands/npm-install
4144
#
4245
# The --package-lock-only argument will only update the
@@ -45,9 +48,16 @@ jobs:
4548
#
4649
npm install --package-lock-only --ignore-scripts --include=optional
4750
48-
# If the package.json (dependencies and devDependencies) is
49-
# in correct sync with package-lock.json running the above command
50-
# should *not* make an edit to the package-lock.json. I.e.
51-
# running `git status` should
52-
# say "nothing to commit, working tree clean".
53-
git diff --exit-code
51+
# Extract the top-level dependencies after regeneration
52+
node -e "console.log(JSON.stringify(require('./package-lock.json').packages['']))" > /tmp/after.json
53+
54+
# Compare only the top-level package dependencies
55+
# This ignores platform-specific differences in nested dependency resolution
56+
# (like "peer" flags) that don't affect actual installed versions
57+
if ! diff /tmp/before.json /tmp/after.json; then
58+
echo "ERROR: Top-level dependencies in package-lock.json are out of sync with package.json"
59+
echo "Please run 'npm install' locally and commit the updated package-lock.json"
60+
exit 1
61+
fi
62+
63+
echo "✓ Top-level dependencies are in sync"
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
> [!NOTE]
2-
> {% data variables.copilot.copilot_code-review_short %} may use models that are not enabled on your organization's "Models" settings page. See [AUTOTITLE](/copilot/how-tos/administer-copilot/manage-for-organization/manage-policies).
2+
> {% data variables.copilot.copilot_code-review_short %} may use models that are not enabled on your organization's "Models" settings page. The "Models" settings page only controls {% data variables.copilot.copilot_chat_short %}.
3+
>
4+
> Since {% data variables.copilot.copilot_code-review_short %} is generally available, all model usage will be subject to the generally available terms. See [AUTOTITLE](/copilot/how-tos/administer-copilot/manage-for-organization/manage-policies).

eslint-plugins.d.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Type declarations for ESLint plugins without official TypeScript definitions
2+
3+
declare module 'eslint-plugin-github' {
4+
import type { ESLint, Linter } from 'eslint'
5+
6+
const plugin: ESLint.Plugin & {
7+
configs: {
8+
recommended: Linter.FlatConfig
9+
}
10+
}
11+
12+
export default plugin
13+
}
14+
15+
declare module 'eslint-plugin-primer-react' {
16+
import type { ESLint, Linter } from 'eslint'
17+
18+
const plugin: ESLint.Plugin & {
19+
configs: {
20+
recommended: Linter.FlatConfig
21+
}
22+
}
23+
24+
export default plugin
25+
}
26+
27+
declare module 'eslint-plugin-eslint-comments' {
28+
import type { ESLint } from 'eslint'
29+
30+
const plugin: ESLint.Plugin
31+
32+
export default plugin
33+
}
34+
35+
declare module 'eslint-plugin-i18n-text' {
36+
import type { ESLint } from 'eslint'
37+
38+
const plugin: ESLint.Plugin
39+
40+
export default plugin
41+
}
42+
43+
declare module 'eslint-plugin-filenames' {
44+
import type { ESLint } from 'eslint'
45+
46+
const plugin: ESLint.Plugin
47+
48+
export default plugin
49+
}
50+
51+
declare module 'eslint-plugin-no-only-tests' {
52+
import type { ESLint } from 'eslint'
53+
54+
const plugin: ESLint.Plugin
55+
56+
export default plugin
57+
}

eslint.config.js renamed to eslint.config.ts

Lines changed: 0 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -14,89 +14,6 @@ import prettier from 'eslint-config-prettier'
1414
import globals from 'globals'
1515

1616
export default [
17-
// JavaScript and MJS files configuration
18-
{
19-
files: ['**/*.{js,mjs}'],
20-
languageOptions: {
21-
ecmaVersion: 2022,
22-
sourceType: 'module',
23-
globals: {
24-
...globals.browser,
25-
...globals.node,
26-
...globals.commonjs,
27-
...globals.es2020,
28-
},
29-
parserOptions: {
30-
requireConfigFile: false,
31-
},
32-
},
33-
settings: {
34-
'import/resolver': {
35-
typescript: true,
36-
node: true,
37-
},
38-
},
39-
plugins: {
40-
github,
41-
import: importPlugin,
42-
'eslint-comments': eslintComments,
43-
'i18n-text': i18nText,
44-
filenames,
45-
'no-only-tests': noOnlyTests,
46-
prettier: prettierPlugin,
47-
},
48-
rules: {
49-
// ESLint recommended rules
50-
...js.configs.recommended.rules,
51-
52-
// GitHub plugin recommended rules
53-
...github.configs.recommended.rules,
54-
55-
// Import plugin error rules
56-
...importPlugin.configs.errors.rules,
57-
58-
// JavaScript-specific overrides
59-
'import/no-extraneous-dependencies': [
60-
'error',
61-
{
62-
packageDir: '.',
63-
},
64-
],
65-
'import/extensions': 'off',
66-
'no-console': 'off',
67-
camelcase: 'off',
68-
'no-shadow': 'off',
69-
'prefer-template': 'off',
70-
'no-constant-condition': 'off',
71-
'no-unused-vars': 'off',
72-
'import/no-named-as-default-member': 'off',
73-
'one-var': 'off',
74-
'import/no-namespace': 'off',
75-
'import/no-anonymous-default-export': 'off',
76-
'object-shorthand': 'off',
77-
'no-empty': 'off',
78-
'prefer-const': 'off',
79-
'import/no-named-as-default': 'off',
80-
'no-useless-concat': 'off',
81-
'func-style': 'off',
82-
83-
// Disable GitHub plugin rules that were disabled in original config
84-
'github/array-foreach': 'off',
85-
'github/no-then': 'off',
86-
87-
// Disable rules that might not exist or cause issues initially
88-
'i18n-text/no-en': 'off',
89-
'filenames/match-regex': 'off',
90-
'eslint-comments/no-use': 'off',
91-
'eslint-comments/no-unused-disable': 'off',
92-
'eslint-comments/no-unlimited-disable': 'off',
93-
94-
// Disable new ESLint 9 rules that are causing issues
95-
'no-constant-binary-expression': 'off',
96-
},
97-
},
98-
99-
// TypeScript and TSX files configuration
10017
{
10118
files: ['**/*.{ts,tsx}'],
10219
languageOptions: {

package-lock.json

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@
258258
"@types/connect-timeout": "1.9.0",
259259
"@types/cookie": "0.6.0",
260260
"@types/cookie-parser": "1.4.8",
261+
"@types/eslint-plugin-jsx-a11y": "^6.10.1",
261262
"@types/event-to-promise": "^0.7.5",
262263
"@types/express": "^5.0.3",
263264
"@types/imurmurhash": "^0.1.4",
@@ -298,6 +299,7 @@
298299
"graphql": "^16.9.0",
299300
"http-status-code": "^2.1.0",
300301
"husky": "^9.1.7",
302+
"jiti": "^2.6.1",
301303
"json-schema-merge-allof": "^0.8.1",
302304
"lint-staged": "^16.0.0",
303305
"markdownlint": "^0.34.0",

src/ai-tools/scripts/ai-tools.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#!/usr/bin/env node
2-
31
import { fileURLToPath } from 'url'
42
import { Command } from 'commander'
53
import fs from 'fs'
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import fs from 'fs'
2+
import path from 'path'
3+
// @ts-ignore - markdownlint-rule-helpers doesn't have TypeScript declarations
4+
import { addError } from 'markdownlint-rule-helpers'
5+
6+
import { getFrontmatter } from '../helpers/utils'
7+
import type { RuleParams, RuleErrorCallback, Rule } from '@/content-linter/types'
8+
9+
interface Frontmatter {
10+
heroImage?: string
11+
[key: string]: any
12+
}
13+
14+
// Get the list of valid hero images
15+
function getValidHeroImages(): string[] {
16+
const ROOT = process.env.ROOT || '.'
17+
const heroImageDir = path.join(ROOT, 'assets/images/banner-images')
18+
19+
try {
20+
if (!fs.existsSync(heroImageDir)) {
21+
return []
22+
}
23+
24+
const files = fs.readdirSync(heroImageDir)
25+
// Return absolute paths as they would appear in frontmatter
26+
return files.map((file) => `/assets/images/banner-images/${file}`)
27+
} catch {
28+
return []
29+
}
30+
}
31+
32+
export const frontmatterHeroImage: Rule = {
33+
names: ['GHD061', 'frontmatter-hero-image'],
34+
description:
35+
'Hero image paths must be absolute and point to valid images in /assets/images/banner-images/',
36+
tags: ['frontmatter', 'images'],
37+
function: (params: RuleParams, onError: RuleErrorCallback) => {
38+
// Only check index.md files
39+
if (!params.name.endsWith('index.md')) return
40+
41+
const fm = getFrontmatter(params.lines) as Frontmatter | null
42+
if (!fm || !fm.heroImage) return
43+
44+
const heroImage = fm.heroImage
45+
46+
// Check if heroImage is an absolute path
47+
if (!heroImage.startsWith('/')) {
48+
const line = params.lines.find((line: string) => line.trim().startsWith('heroImage:'))
49+
const lineNumber = line ? params.lines.indexOf(line) + 1 : 1
50+
addError(
51+
onError,
52+
lineNumber,
53+
`Hero image path must be absolute (start with /). Found: ${heroImage}`,
54+
line || '',
55+
null, // No fix possible
56+
)
57+
return
58+
}
59+
60+
// Check if heroImage points to banner-images directory
61+
if (!heroImage.startsWith('/assets/images/banner-images/')) {
62+
const line = params.lines.find((line: string) => line.trim().startsWith('heroImage:'))
63+
const lineNumber = line ? params.lines.indexOf(line) + 1 : 1
64+
addError(
65+
onError,
66+
lineNumber,
67+
`Hero image must point to /assets/images/banner-images/. Found: ${heroImage}`,
68+
line || '',
69+
null, // No fix possible
70+
)
71+
return
72+
}
73+
74+
// Check if the file actually exists
75+
const validHeroImages = getValidHeroImages()
76+
if (validHeroImages.length > 0 && !validHeroImages.includes(heroImage)) {
77+
const line = params.lines.find((line: string) => line.trim().startsWith('heroImage:'))
78+
const lineNumber = line ? params.lines.indexOf(line) + 1 : 1
79+
const availableImages = validHeroImages.join(', ')
80+
addError(
81+
onError,
82+
lineNumber,
83+
`Hero image file does not exist: ${heroImage}. Available images: ${availableImages}`,
84+
line || '',
85+
null, // No fix possible
86+
)
87+
}
88+
},
89+
}

src/content-linter/lib/linting-rules/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import { ctasSchema } from '@/content-linter/lib/linting-rules/ctas-schema'
6161
import { journeyTracksLiquid } from './journey-tracks-liquid'
6262
import { journeyTracksGuidePathExists } from './journey-tracks-guide-path-exists'
6363
import { journeyTracksUniqueIds } from './journey-tracks-unique-ids'
64+
import { frontmatterHeroImage } from './frontmatter-hero-image'
6465

6566
// Using any type because @github/markdownlint-github doesn't provide TypeScript declarations
6667
// The elements in the array have a 'names' property that contains rule identifiers
@@ -130,6 +131,7 @@ export const gitHubDocsMarkdownlint = {
130131
journeyTracksLiquid, // GHD058
131132
journeyTracksGuidePathExists, // GHD059
132133
journeyTracksUniqueIds, // GHD060
134+
frontmatterHeroImage, // GHD061
133135

134136
// Search-replace rules
135137
searchReplace, // Open-source plugin

src/content-linter/style/github-docs.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,12 @@ export const githubDocsFrontmatterConfig = {
348348
'partial-markdown-files': false,
349349
'yml-files': false,
350350
},
351+
'frontmatter-hero-image': {
352+
// GHD061
353+
severity: 'error',
354+
'partial-markdown-files': false,
355+
'yml-files': false,
356+
},
351357
}
352358

353359
// Configures rules from the `github/markdownlint-github` repo

0 commit comments

Comments
 (0)