fix(website): resize showcase images, tighten CI check (#6043)

* fix(website): resize images to width 640

* revert changes first...

* resize images

* final changes

* Add to CI

* refactor tests

* Fix script

* fix script

* Final fixes

* Oops

* relax

* fix

* crop

* Optimize

Co-authored-by: Joshua Chen <sidachen2003@gmail.com>
This commit is contained in:
Armano 2022-01-07 07:03:43 +01:00 committed by GitHub
parent 37a84f86a5
commit 4578b8b4c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
201 changed files with 120 additions and 156 deletions

View file

@ -6,7 +6,6 @@ build
coverage
jest.config.js
jest.transform.js
scripts
examples/
packages/lqip-loader/lib/

View file

@ -14,13 +14,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node }}
- name: Set up Node
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node }}
cache: yarn
- name: Installation
run: yarn
- name: Test
run: yarn test website/src/data/__tests__/user.test.ts
# TODO another job to optimize the images, see https://github.com/facebook/docusaurus/issues/5980

View file

@ -0,0 +1,34 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// eslint-disable-next-line import/no-extraneous-dependencies
import sharp from 'sharp';
import fs from 'fs/promises';
import path from 'path';
const images = (
await fs.readdir(new URL('../../website/src/data/showcase', import.meta.url))
).filter((file) => ['.png', 'jpg', '.jpeg'].includes(path.extname(file)));
await Promise.all(
images.map(async (img) => {
const imgPath = new URL(
`../../website/src/data/showcase/${img}`,
import.meta.url,
).pathname;
const data = await sharp(imgPath)
.resize(640, 320, {fit: 'cover', position: 'top'})
.png()
.toBuffer();
await fs.writeFile(imgPath.replace(/jpe?g/, 'png'), data);
}),
);
// You should also run optimizt `find website/src/data/showcase -type f -name '*.png'`.
// This is not included here because @funboxteam/optimizt doesn't seem to play well with M1
// so I had to run this in a Rosetta terminal.
// TODO integrate this as part of the script

View file

@ -114,6 +114,7 @@
"react-test-renderer": "^17.0.2",
"rimraf": "^3.0.2",
"serve": "^12.0.1",
"sharp": "^0.29.1",
"stylelint": "^13.10.0",
"tslib": "^2.3.1",
"typescript": "^4.5.2"

View file

@ -6,162 +6,93 @@
*/
import {TagList, sortedUsers, type User} from '../users';
import {difference} from '@site/src/utils/jsUtils';
// eslint-disable-next-line import/no-extraneous-dependencies
import {Joi} from '@docusaurus/utils-validation';
import fs from 'fs-extra';
import path from 'path';
import imageSize from 'image-size';
describe('users', () => {
test('are valid', () => {
sortedUsers.forEach(ensureUserValid);
});
test('have valid images', async () => {
const minCardImageWidth = 304;
const minCardImageHeight = 150;
const minCardImageHeightScaled = 140;
const imageDir = path.join(__dirname, '../showcase');
const files = await fs.readdir(imageDir);
// eslint-disable-next-line no-restricted-syntax
for (const file of files) {
const size = imageSize(path.join(imageDir, file));
if (size.width! < minCardImageWidth) {
throw new Error(
`Image width should be >= ${minCardImageWidth}
Image=${file}`,
);
}
if (size.height! < minCardImageHeight) {
throw new Error(
`Image height should be >= ${minCardImageHeight}
Image=${file}`,
);
}
const scaledHeight = size.height! / (size.width! / minCardImageWidth);
if (scaledHeight < minCardImageHeightScaled) {
throw new Error(
`Image height is too small compared to width
After downscaling to width=${minCardImageWidth}, height would be ${scaledHeight} while the minimum is ${minCardImageHeightScaled}
Image=${file}`,
);
}
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace jest {
interface Matchers<R> {
toHaveGoodDimensions: () => R;
}
});
});
// TODO, refactor legacy test code
// Fail-fast on common errors
function ensureUserValid(user: User) {
function checkFields() {
const keys = Object.keys(user);
const validKeys = [
'title',
'description',
'preview',
'website',
'source',
'tags',
];
const unknownKeys = difference(keys, validKeys);
if (unknownKeys.length > 0) {
throw new Error(
`Site contains unknown attribute names=[${unknownKeys.join(',')}]`,
);
}
}
function checkTitle() {
if (!user.title) {
throw new Error('Site title is missing');
}
}
function checkDescription() {
if (!user.description) {
throw new Error('Site description is missing');
}
}
function checkWebsite() {
if (!user.website) {
throw new Error('Site website is missing');
}
const isHttpUrl =
user.website.startsWith('http://') || user.website.startsWith('https://');
if (!isHttpUrl) {
throw new Error(
`Site website does not look like a valid url: ${user.website}`,
);
}
}
function checkPreview() {
if (
!user.preview ||
(user.preview instanceof String &&
(user.preview.startsWith('http') || user.preview.startsWith('//')))
) {
throw new Error(
`Site has bad image preview=[${user.preview}].\nThe image should be hosted on Docusaurus site, and not use remote HTTP or HTTPS URLs`,
);
}
}
function checkTags() {
if (
!user.tags ||
!(user.tags instanceof Array) ||
(user.tags as string[]).includes('')
) {
throw new Error(`Bad showcase tags=[${JSON.stringify(user.tags)}]`);
}
const unknownTags = difference(user.tags, TagList);
if (unknownTags.length > 0) {
throw new Error(
`Unknown tags=[${unknownTags.join(
',',
)}\nThe available tags are ${TagList.join(',')}`,
);
}
}
function checkOpenSource() {
if (typeof user.source === 'undefined') {
throw new Error(
"The source attribute is required.\nIf your Docusaurus site is not open-source, please make it explicit with 'source: null'",
);
} else {
const hasOpenSourceTag = user.tags.includes('opensource');
if (user.source === null && hasOpenSourceTag) {
throw new Error(
"You can't add the opensource tag to a site that does not have a link to source code.",
);
} else if (user.source && !hasOpenSourceTag) {
throw new Error(
"For open-source sites, please add the 'opensource' tag",
);
}
}
}
try {
checkFields();
checkTitle();
checkDescription();
checkWebsite();
checkPreview();
checkTags();
checkOpenSource();
} catch (e) {
throw new Error(
`Showcase site with title=${user.title} contains errors:\n${
(e as Error).message
}`,
);
}
}
expect.extend({
toHaveGoodDimensions({width, height}: {width: number; height: number}) {
// Put this one first because aspect ratio is harder to fix than resizing (need to take another screenshot)
if (width / height < 0.5) {
return {
pass: false,
message: () =>
`The preview image's width is ${width} and height is ${height}. To make sure it takes up the entire container in our showcase card, it needs to have a minimum aspect ratio of 2:1. Please make your image taller.`,
};
} else if (width < 640) {
return {
pass: false,
message: () =>
`The preview image's width is ${width}, but we require a minimum 640. You can either resize it locally, or you can wait for the maintainer to resize it for you.`,
};
}
return {
pass: true,
message: () => "The preview image's dimensions are good",
};
},
});
describe('users', () => {
sortedUsers.forEach((user) => {
test(user.title, () => {
Joi.attempt(
user,
Joi.object<User>({
title: Joi.string().required(),
description: Joi.string().required(),
website: Joi.string()
.pattern(/^https?:\/\//)
.message('')
.required(),
// The preview should be jest/emptyModule
preview: Joi.object({}).unknown(false).required().messages({
'object.base':
'The image should be hosted on Docusaurus site, and not use remote HTTP or HTTPS URLs. It must be imported with require().',
}),
tags: Joi.array()
.items(...TagList)
.required(),
source: Joi.string().allow(null).required().messages({
'any.required':
"The source attribute is required.\nIf your Docusaurus site is not open-source, please make it explicit with 'source: null'.",
}),
}).unknown(false),
);
if (user.tags.includes('opensource') && user.source === null) {
throw new Error(
"You can't add the 'opensource' tag to a site that does not have a link to source code. Please add your source code, or remove this tag.",
);
} else if (user.source !== null && !user.tags.includes('opensource')) {
throw new Error(
"For open-source sites, please add the 'opensource' tag.",
);
}
});
});
const imageDir = path.join(__dirname, '../showcase');
const files = fs
.readdirSync(imageDir)
.filter((file) => ['.png', 'jpg', '.jpeg'].includes(path.extname(file)));
files.forEach((file) => {
test(file, () => {
const size = imageSize(path.join(imageDir, file));
expect(size).toHaveGoodDimensions();
});
});
});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 585 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 500 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 521 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 623 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 159 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 655 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 392 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 384 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 400 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 469 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 343 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 MiB

After

Width:  |  Height:  |  Size: 44 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 809 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 512 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 518 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 850 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 312 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 562 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 525 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 MiB

After

Width:  |  Height:  |  Size: 71 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 521 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 MiB

After

Width:  |  Height:  |  Size: 29 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 484 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 425 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 379 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 643 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 703 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 216 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 377 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 846 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 582 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 MiB

After

Width:  |  Height:  |  Size: 15 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 799 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 754 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 495 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 802 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 715 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 165 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 41 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 349 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 280 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 387 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 427 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 636 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 381 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 191 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Before After
Before After

Some files were not shown because too many files have changed in this diff Show more