Move GitHub URLs linting from JSONSchema to our lint (#11877)

This commit is contained in:
Álvaro Mondéjar Rubio 2024-09-27 18:25:37 +02:00 committed by GitHub
parent f708c4f6a3
commit d7938b6416
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 68 additions and 33 deletions

View File

@ -678,16 +678,7 @@
"sourceUrl": { "sourceUrl": {
"$id": "#sourceUrl", "$id": "#sourceUrl",
"description": "URL for icon source. If is a GitHub URL, is validated to contain a commit hash, to be an issue comment or to be a GitHub organization URL", "description": "URL for icon source. If is a GitHub URL, is validated to contain a commit hash, to be an issue comment or to be a GitHub organization URL",
"type": "string", "$ref": "#/definitions/url"
"if": {
"pattern": "^https://github\\.com/(?!(features/actions)|(sponsors)|(logos)$)"
},
"then": {
"pattern": "^https://github\\.com/[^/]+/[^/]+/(blob/[a-f\\d]{40}/[^\\s]+)|(tree/[a-f\\d]{40}(/[^\\s]+)?)|(((issues)|(pull)|(discussions))/\\d+#((issuecomment)|(discussioncomment))-\\d+)$"
},
"else": {
"$ref": "#/definitions/url"
}
}, },
"url": { "url": {
"$id": "#url", "$id": "#url",

View File

@ -571,7 +571,7 @@
"title": "Alby", "title": "Alby",
"hex": "FFDF6F", "hex": "FFDF6F",
"source": "https://github.com/getAlby/media/blob/c24fee4a3f76d6cd000343a972f10590d3913b25/Alby-logo-icons/Alby-logo-head/alby.svg", "source": "https://github.com/getAlby/media/blob/c24fee4a3f76d6cd000343a972f10590d3913b25/Alby-logo-icons/Alby-logo-head/alby.svg",
"guidelines": "https://github.com/getAlby/lightning-browser-extension/wiki/Open-Design" "guidelines": "https://github.com/getAlby/lightning-browser-extension/wiki/Open-Design/9e8ebe4d3e7707742d227554c4ee27b29983a1b6"
}, },
{ {
"title": "Alchemy", "title": "Alchemy",

View File

@ -105,35 +105,67 @@ const TESTS = {
/** /**
* Check if an URL is raw GitHub asset URL. * Check if an URL is raw GitHub asset URL.
* @param {string} $url URL instance * @param {URL} $url URL instance
* @returns {boolean} Whether the URL is raw GitHub asset URL * @returns {boolean} Whether the URL is raw GitHub asset URL
*/ */
const isRawGithubAssetUrl = ($url) => const isRawGithubAssetUrl = ($url) =>
$url.hostname === 'raw.githubusercontent.com'; $url.hostname === 'raw.githubusercontent.com';
const allUrlFields = [ /**
...new Set( * Check if an URL is a GitHub URL.
data.icons.flatMap((icon) => { * @param {URL} $url URL instance
/** @type {string[]} */ * @returns {boolean} Whether the URL is a GitHub URL
const license = */
icon.license !== undefined && Object.hasOwn(icon.license, 'url') const isGitHubUrl = ($url) => $url.hostname === 'github.com';
? [
// eslint-disable-next-line no-warning-comments /**
// TODO: `hasOwn` is not currently supported by TS. * Regex to match a permalink GitHub URL for a file.
// See https://github.com/microsoft/TypeScript/issues/44253 */
/** @type {string} */ const permalinkGitHubRegex =
// @ts-ignore /^https:\/\/github\.com\/[^/]+\/[^/]+\/(blob\/[a-f\d]{40}\/\S+)|(tree\/[a-f\d]{40}(\/\S+)?)|(((issues)|(pull)|(discussions))\/\d+#((issuecomment)|(discussioncomment))-\d+)|(wiki\/\S+\/[a-f\d]{40})$/;
icon.license.url,
] /**
: []; * URLs excluded from the GitHub URL check as are used by GitHub brands.
const guidelines = icon.guidelines ? [icon.guidelines] : []; */
return [icon.source, ...guidelines, ...license]; const gitHubExcludedUrls = new Set([
}), 'https://github.com/logos',
), 'https://github.com/features/actions',
]; 'https://github.com/sponsors',
]);
/**
* Check if an URL is a permanent GitHub URL for a file.
* @param {string} url URL string
* @returns {boolean} Whether the URL is a GitHub URL for a file
*/
const isPermalinkGitHubFileUrl = (url) => permalinkGitHubRegex.test(url);
/**
* Url fields with a boolean indicating if is an icon source URL.
* @type {[boolean, string][]}
*/
const allUrlFields = [];
for (const icon of data.icons) {
allUrlFields.push([true, icon.source]);
if (icon.guidelines) {
allUrlFields.push([false, icon.guidelines]);
}
if (icon.license !== undefined && Object.hasOwn(icon.license, 'url')) {
allUrlFields.push([
false,
// eslint-disable-next-line no-warning-comments
// TODO: `hasOwn` is not currently supported by TS.
// See https://github.com/microsoft/TypeScript/issues/44253
/** @type {string} */
// @ts-ignore
icon.license.url,
]);
}
}
const invalidUrls = []; const invalidUrls = [];
for (const url of allUrlFields) { for (const [isSourceUrl, url] of allUrlFields) {
const $url = new global.URL(url); const $url = new global.URL(url);
if (hasRedundantTrailingSlash($url, url)) { if (hasRedundantTrailingSlash($url, url)) {
@ -151,6 +183,18 @@ const TESTS = {
const expectedUrl = `https://github.com/${owner}/${repo}/blob/${hash}/${directory.join('/')}`; const expectedUrl = `https://github.com/${owner}/${repo}/blob/${hash}/${directory.join('/')}`;
invalidUrls.push(fakeDiff(url, expectedUrl)); invalidUrls.push(fakeDiff(url, expectedUrl));
} }
if (
isSourceUrl &&
isGitHubUrl($url) &&
!isPermalinkGitHubFileUrl(url) &&
!gitHubExcludedUrls.has(url)
) {
invalidUrls.push(
`'${url}' must be a permalink GitHub URL. Expecting something like` +
" 'https://github.com/<owner>/<repo>/blob/<hash>/<file/path.ext>'.",
);
}
} }
if (invalidUrls.length > 0) { if (invalidUrls.length > 0) {