Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci[patch]: Adds CI action validating new notebooks #6263

Merged
merged 13 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .github/workflows/validate_new_notebooks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Validate new notebooks

# If another push to the same PR or branch happens while this workflow is still running,
# cancel the earlier run in favor of the next run.
#
# There's no point in testing an outdated version of the code. GitHub only allows
# a limited number of job runners to be active at the same time, so it's better to cancel
# pointless jobs early so that more useful jobs can run sooner.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

on:
push:
branches:
- main
pull_request:
branches:
- main
paths:
- 'docs/core_docs/**'
workflow_dispatch:

jobs:
validate-new-notebooks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: "yarn"
- name: Install dependencies
run: yarn install --immutable
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v44
- name: Validate new notebooks
run: |
new_notebooks=$(echo '${{ steps.changed-files.outputs.added_files }}' | tr ' ' '\n' | grep '\.ipynb$' || true)
echo "New notebooks: $new_notebooks"
if [ -n "$new_notebooks" ]; then
for notebook in $new_notebooks; do
yarn notebook:validate "$notebook"
done
else
echo "No new notebooks to validate."
fi
2 changes: 1 addition & 1 deletion docs/core_docs/scripts/quarto-build.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const fs = require("node:fs");
const { glob } = require("glob");
const { execSync } = require("node:child_process");

const IGNORED_CELL_REGEX = /```\w*?\n\/\/ ?@ls-docs-hide-cell\n[\s\S]*?```/g;
const IGNORED_CELL_REGEX = /```\w*?\n\/\/ ?@lc-docs-hide-cell\n[\s\S]*?```/g;

async function main() {
const allIpynb = await glob("./docs/**/*.ipynb");
Expand Down
39 changes: 23 additions & 16 deletions docs/core_docs/scripts/validate_notebook.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import * as fs from "node:fs/promises";
import * as fs from "node:fs";
import * as ts from "typescript";
import { v4 as uuidv4 } from "uuid";

export async function extract(filepath: string) {
const cells = JSON.parse((await fs.readFile(filepath)).toString()).cells;
export function extract(filepath: string) {
const cells = JSON.parse(fs.readFileSync(filepath).toString()).cells;
const code = cells
.map((cell: Record<string, any>) => {
if (cell.cell_type === "code") {
Expand Down Expand Up @@ -33,13 +32,11 @@ const run = async () => {
[pathname.split("/").length - 1].replace(".ipynb", ".mts");
const tempFilepath = `./tmp/${filename}`;
try {
const typescriptSource = await extract(pathname);
try {
await fs.access("./tmp", fs.constants.F_OK);
} catch (err) {
await fs.mkdir("./tmp");
const typescriptSource = extract(pathname);
if (!fs.existsSync("./tmp")) {
fs.mkdirSync("./tmp");
}
await fs.writeFile(tempFilepath, typescriptSource);
fs.writeFileSync(tempFilepath, typescriptSource);
const program = ts.createProgram([tempFilepath], {
module: ts.ModuleKind.NodeNext,
moduleResolution: ts.ModuleResolutionKind.NodeNext,
Expand All @@ -48,6 +45,7 @@ const run = async () => {
skipLibCheck: true,
});
const diagnostics = ts.getPreEmitDiagnostics(program);
const issueStrings: string[] = [];
if (diagnostics.length === 0) {
console.log("No type errors found.");
} else {
Expand All @@ -59,27 +57,36 @@ const run = async () => {
diagnostic.messageText,
"\n"
);
console.log(
issueStrings.push(
`${diagnostic.file.fileName} (${line + 1},${
character + 1
}): ${message}`
);
} else {
console.log(
issueStrings.push(
ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")
);
}
});
}
} catch (e) {
console.log(e);
if (issueStrings.length) {
const issues = issueStrings.join("\n");
console.error(issues);
const err = new Error("Found type errors in new notebook.");
(err as any).details = issues;
throw err;
}
} finally {
try {
await fs.rm(tempFilepath);
fs.rmSync(tempFilepath);
} catch (e) {
// Do nothing
}
}
};

run();
try {
run();
} catch {
process.exit(1);
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"test:standard:int": "turbo test:standard:int",
"test:standard": "yarn test:standard:unit && yarn test:standard:int",
"example": "yarn workspace examples start",
"notebook:validate": "yarn workspace core_docs validate",
"precommit": "turbo precommit",
"docs": "yarn workspace core_docs start",
"docs:api_refs": "yarn workspace api_refs start",
Expand Down
Loading