0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-30 22:03:56 -05:00

Run astro check on all examples in CI (#5022)

* Run astro check on all examples in CI

* Output stderr

* Build Astro before running checks

* Making things faster + colors

* Fix errors inside examples

* Add congrats message

* Revert unentional change to tsconfigs

* Remove more unneeded changes
This commit is contained in:
Erika 2022-10-12 09:48:29 -03:00 committed by GitHub
parent 640ce72d33
commit f604ef6c69
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 200 additions and 19 deletions

47
.github/workflows/check.yml vendored Normal file
View file

@ -0,0 +1,47 @@
name: Examples astro check
on:
push:
branches:
- main
pull_request:
paths:
- 'examples/**'
- '.github/workflows/check.yml'
- 'scripts/smoke/check.js'
- 'packages/astro/src/@types/astro.ts'
env:
ASTRO_TELEMETRY_DISABLED: true
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
FORCE_COLOR: true
jobs:
check:
name: astro check
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v3
- name: Setup PNPM
uses: pnpm/action-setup@v2.2.1
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 16
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm run build
- name: Status
run: git status
- name: astro check
run: pnpm run test:check-examples

View file

@ -19,6 +19,11 @@ import { MyCounter } from '../components/my-counter.js';
<h1>Test app</h1> <h1>Test app</h1>
<MyCounter client:load /> <MyCounter client:load />
<Lorem /> <Lorem />
<CalcAdd num={33} />
{/**
* Our VS Code extension does not currently properly typecheck attributes on Lit components
* As such, the following code will result in a TypeScript error inside the editor, nonetheless, it works in Astro!
* @ts-expect-error */}
<CalcAdd num={0} />
</body> </body>
</html> </html>

View file

@ -12,9 +12,11 @@
// can fetch them directly in the browser. // can fetch them directly in the browser.
const response = await fetch(`/about.json`); const response = await fetch(`/about.json`);
const data = await response.json(); const data = await response.json();
document.getElementById( const resultHeader = document.getElementById('result');
'result'
).innerHTML = `Load complete!<br/>Built with: <a href="${data.url}">${data.name}!</a>`; if (resultHeader) {
resultHeader.innerHTML = `Load complete!<br/>Built with: <a href="${data.url}">${data.name}!</a>`;
}
</script> </script>
</body> </body>
</html> </html>

View file

@ -1,4 +1,11 @@
--- ---
import type { MarkdownInstance } from 'astro';
import type { Project } from '../types';
interface Props {
project: MarkdownInstance<Project>
}
const { frontmatter, url } = Astro.props.project; const { frontmatter, url } = Astro.props.project;
--- ---

View file

@ -2,11 +2,16 @@
import MainHead from '../components/MainHead.astro'; import MainHead from '../components/MainHead.astro';
import Footer from '../components/Footer.astro'; import Footer from '../components/Footer.astro';
import Nav from '../components/Nav.astro'; import Nav from '../components/Nav.astro';
import type { Project } from '../types';
interface Props {
content: Project;
}
const { content } = Astro.props; const { content } = Astro.props;
--- ---
<html lang={content.lang || 'en'}> <html lang="en">
<head> <head>
<MainHead title={content.title} description={content.description} /> <MainHead title={content.title} description={content.description} />
<style> <style>

View file

@ -4,10 +4,11 @@ import MainHead from '../components/MainHead.astro';
import Nav from '../components/Nav.astro'; import Nav from '../components/Nav.astro';
import Footer from '../components/Footer.astro'; import Footer from '../components/Footer.astro';
import PortfolioPreview from '../components/PortfolioPreview.astro'; import PortfolioPreview from '../components/PortfolioPreview.astro';
import type { Project } from '../types';
// Data Fetching: List all Markdown posts in the repo. // Data Fetching: List all Markdown posts in the repo.
const projects = await Astro.glob('./project/**/*.md'); const projects = await Astro.glob<Project>('./project/**/*.md');
const featuredProject = projects[0]; const featuredProject = projects[0]!;
// Full Astro Component Syntax: // Full Astro Component Syntax:
// https://docs.astro.build/core-concepts/astro-components/ // https://docs.astro.build/core-concepts/astro-components/

View file

@ -3,8 +3,9 @@ import MainHead from '../components/MainHead.astro';
import Footer from '../components/Footer.astro'; import Footer from '../components/Footer.astro';
import Nav from '../components/Nav.astro'; import Nav from '../components/Nav.astro';
import PortfolioPreview from '../components/PortfolioPreview.astro'; import PortfolioPreview from '../components/PortfolioPreview.astro';
import type { Project } from '../types';
const projects = (await Astro.glob('./project/**/*.md')) const projects = (await Astro.glob<Project>('./project/**/*.md'))
.filter(({ frontmatter }) => !!frontmatter.publishDate) .filter(({ frontmatter }) => !!frontmatter.publishDate)
.sort( .sort(
(a, b) => (a, b) =>

View file

@ -0,0 +1,8 @@
export interface Project {
title: string;
client: string;
description: string;
publishDate: string;
tags: string[];
img: string;
}

View file

@ -1,4 +1,4 @@
interface Product { export interface Product {
id: number; id: number;
name: string; name: string;
price: number; price: number;

View file

@ -1,4 +1,10 @@
--- ---
import type { Product } from '../api';
interface Props {
products: Product[];
}
const { products } = Astro.props; const { products } = Astro.props;
--- ---

View file

@ -1,4 +1,8 @@
--- ---
interface Props {
text: string;
}
const { text } = Astro.props; const { text } = Astro.props;
const words = text.split(' '); const words = text.split(' ');
const last = words.length - 1; const last = words.length - 1;

View file

@ -19,16 +19,13 @@ const products = await getProducts(Astro.request);
.product-listing-title { .product-listing-title {
text-align: center; text-align: center;
} }
.product-listing {
}
</style> </style>
</head> </head>
<body> <body>
<Header /> <Header />
<Container tag="main"> <Container tag="main">
<ProductListing products={products} class="product-listing"> <ProductListing products={products}>
<h2 class="product-listing-title" slot="title">Product Listing</h2> <h2 class="product-listing-title" slot="title">Product Listing</h2>
</ProductListing> </ProductListing>
</Container> </Container>

View file

@ -11,8 +11,9 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"astro": "^1.4.7",
"@astrojs/tailwind": "^2.0.2", "@astrojs/tailwind": "^2.0.2",
"@types/canvas-confetti": "^1.4.3",
"astro": "^1.4.7",
"autoprefixer": "^10.4.7", "autoprefixer": "^10.4.7",
"canvas-confetti": "^1.5.1", "canvas-confetti": "^1.5.1",
"postcss": "^8.4.14", "postcss": "^8.4.14",

View file

@ -11,5 +11,9 @@
<script> <script>
import confetti from 'canvas-confetti'; import confetti from 'canvas-confetti';
document.body.querySelector('button').addEventListener('click', () => confetti()); const button = document.body.querySelector('button');
if (button) {
button.addEventListener('click', () => confetti());
}
</script> </script>

View file

@ -19,6 +19,7 @@
"test": "turbo run test --output-logs=new-only --concurrency=1 --filter=astro --filter=create-astro --filter=\"@astrojs/*\"", "test": "turbo run test --output-logs=new-only --concurrency=1 --filter=astro --filter=create-astro --filter=\"@astrojs/*\"",
"test:match": "cd packages/astro && pnpm run test:match", "test:match": "cd packages/astro && pnpm run test:match",
"test:smoke": "turbo run build --filter=\"@example/*\" --filter=\"astro.build\" --filter=\"docs\" --output-logs=new-only --concurrency=1", "test:smoke": "turbo run build --filter=\"@example/*\" --filter=\"astro.build\" --filter=\"docs\" --output-logs=new-only --concurrency=1",
"test:check-examples": "node ./scripts/smoke/check.js",
"test:vite-ci": "turbo run test --filter=astro --output-logs=new-only --no-deps --concurrency=1", "test:vite-ci": "turbo run test --filter=astro --output-logs=new-only --no-deps --concurrency=1",
"test:e2e": "cd packages/astro && pnpm playwright install && pnpm run test:e2e", "test:e2e": "cd packages/astro && pnpm playwright install && pnpm run test:e2e",
"test:e2e:match": "cd packages/astro && pnpm playwright install && pnpm run test:e2e:match", "test:e2e:match": "cd packages/astro && pnpm playwright install && pnpm run test:e2e:match",

View file

@ -324,6 +324,7 @@ importers:
examples/with-tailwindcss: examples/with-tailwindcss:
specifiers: specifiers:
'@astrojs/tailwind': ^2.0.2 '@astrojs/tailwind': ^2.0.2
'@types/canvas-confetti': ^1.4.3
astro: ^1.4.7 astro: ^1.4.7
autoprefixer: ^10.4.7 autoprefixer: ^10.4.7
canvas-confetti: ^1.5.1 canvas-confetti: ^1.5.1
@ -331,6 +332,7 @@ importers:
tailwindcss: ^3.0.24 tailwindcss: ^3.0.24
dependencies: dependencies:
'@astrojs/tailwind': link:../../packages/integrations/tailwind '@astrojs/tailwind': link:../../packages/integrations/tailwind
'@types/canvas-confetti': 1.4.3
astro: link:../../packages/astro astro: link:../../packages/astro
autoprefixer: 10.4.12_postcss@8.4.17 autoprefixer: 10.4.12_postcss@8.4.17
canvas-confetti: 1.5.1 canvas-confetti: 1.5.1
@ -3435,6 +3437,7 @@ importers:
kleur: ^4.1.4 kleur: ^4.1.4
svelte: ^3.48.0 svelte: ^3.48.0
tar: ^6.1.11 tar: ^6.1.11
tsconfig-resolver: ^3.0.1
dependencies: dependencies:
'@astrojs/webapi': link:../packages/webapi '@astrojs/webapi': link:../packages/webapi
adm-zip: 0.5.9 adm-zip: 0.5.9
@ -3444,6 +3447,8 @@ importers:
kleur: 4.1.5 kleur: 4.1.5
svelte: 3.50.1 svelte: 3.50.1
tar: 6.1.11 tar: 6.1.11
devDependencies:
tsconfig-resolver: 3.0.1
packages: packages:
@ -9397,6 +9402,10 @@ packages:
'@types/node': 18.8.2 '@types/node': 18.8.2
dev: true dev: true
/@types/canvas-confetti/1.4.3:
resolution: {integrity: sha512-UwFPTsW1ZwVyo/ETp4hPSikSD7yl2V42E3VWBF5P/0+DHO4iajyceWv7hfNdZ2AX5tkZnuViiBWOqyCPohU2FQ==}
dev: false
/@types/chai-as-promised/7.1.5: /@types/chai-as-promised/7.1.5:
resolution: {integrity: sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==} resolution: {integrity: sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==}
dependencies: dependencies:
@ -9521,7 +9530,6 @@ packages:
/@types/json5/0.0.30: /@types/json5/0.0.30:
resolution: {integrity: sha512-sqm9g7mHlPY/43fcSNrCYfOeX9zkTTK+euO5E6+CVijSMm5tTjkVdwdqRkY3ljjIAf8679vps5jKUoJBCLsMDA==} resolution: {integrity: sha512-sqm9g7mHlPY/43fcSNrCYfOeX9zkTTK+euO5E6+CVijSMm5tTjkVdwdqRkY3ljjIAf8679vps5jKUoJBCLsMDA==}
dev: false
/@types/mdast/3.0.10: /@types/mdast/3.0.10:
resolution: {integrity: sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==} resolution: {integrity: sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==}
@ -13620,7 +13628,6 @@ packages:
resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==} resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==}
engines: {node: '>=6'} engines: {node: '>=6'}
hasBin: true hasBin: true
dev: false
/jsonc-parser/2.3.1: /jsonc-parser/2.3.1:
resolution: {integrity: sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==} resolution: {integrity: sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==}
@ -16803,7 +16810,6 @@ packages:
/strip-bom/4.0.0: /strip-bom/4.0.0:
resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==}
engines: {node: '>=8'} engines: {node: '>=8'}
dev: false
/strip-comments/2.0.1: /strip-comments/2.0.1:
resolution: {integrity: sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==} resolution: {integrity: sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==}
@ -17157,7 +17163,6 @@ packages:
resolve: 1.22.1 resolve: 1.22.1
strip-bom: 4.0.0 strip-bom: 4.0.0
type-fest: 0.13.1 type-fest: 0.13.1
dev: false
/tsconfig/7.0.0: /tsconfig/7.0.0:
resolution: {integrity: sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==} resolution: {integrity: sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==}

View file

@ -16,5 +16,8 @@
"kleur": "^4.1.4", "kleur": "^4.1.4",
"svelte": "^3.48.0", "svelte": "^3.48.0",
"tar": "^6.1.11" "tar": "^6.1.11"
},
"devDependencies": {
"tsconfig-resolver": "^3.0.1"
} }
} }

84
scripts/smoke/check.js Normal file
View file

@ -0,0 +1,84 @@
// @ts-check
import { spawn } from 'child_process';
import { readdirSync, readFileSync, writeFileSync } from 'fs';
import * as path from 'path';
import { tsconfigResolverSync } from 'tsconfig-resolver';
function checkExamples() {
let examples = readdirSync('./examples', { withFileTypes: true });
examples = examples.filter((dirent) => dirent.isDirectory());
console.log(`Running astro check on ${examples.length} examples...`);
Promise.all(
examples.map(
(example) =>
new Promise((resolve) => {
const originalConfig = prepareExample(example.name);
let data = '';
const child = spawn('node', ['../../packages/astro/astro.js', 'check'], {
cwd: path.join('./examples', example.name),
env: { ...process.env, FORCE_COLOR: 'true' },
});
child.stdout.on('data', function (buffer) {
data += buffer.toString();
});
child.on('exit', (code) => {
if (code !== 0) {
console.error(data);
}
if (originalConfig) {
resetExample(example.name, originalConfig);
}
resolve(code);
});
})
)
).then((codes) => {
if (codes.some((code) => code !== 0)) {
process.exit(1);
}
console.log("No errors found!");
});
}
/**
* @param {string} examplePath
*/
function prepareExample(examplePath) {
const tsconfigPath = path.join('./examples/', examplePath, 'tsconfig.json');
const tsconfig = tsconfigResolverSync({ filePath: tsconfigPath, cache: false });
let originalConfig = undefined;
if (tsconfig.exists) {
tsconfig.config.extends = 'astro/tsconfigs/strictest';
originalConfig = readFileSync(tsconfigPath).toString();
if (!tsconfig.config.compilerOptions) {
tsconfig.config.compilerOptions = {};
}
tsconfig.config.compilerOptions = Object.assign(tsconfig.config.compilerOptions, {
types: tsconfig.config.compilerOptions.types ?? [], // Speeds up tests
});
}
writeFileSync(tsconfigPath, JSON.stringify(tsconfig.config));
return originalConfig;
}
/**
* @param {string} examplePath
* @param {string} originalConfig
*/
function resetExample(examplePath, originalConfig) {
const tsconfigPath = path.join('./examples/', examplePath, 'tsconfig.json');
writeFileSync(tsconfigPath, originalConfig);
}
checkExamples();