diff --git a/.github/workflows/check-typescript-projects.yml b/.github/workflows/check-typescript-projects.yml index ebd5c47..a4c0d83 100644 --- a/.github/workflows/check-typescript-projects.yml +++ b/.github/workflows/check-typescript-projects.yml @@ -8,6 +8,7 @@ on: - main paths: - '.github/workflows/check-typescript-projects.yml' + - 'build-all-examples.bash' - 'projects/**/*' - '.nvmrc' - 'package.json' @@ -17,6 +18,7 @@ on: - main paths: - '.github/workflows/check-typescript-projects.yml' + - 'build-all-examples.bash' - 'projects/**/*' - '.nvmrc' - 'package.json' @@ -24,7 +26,7 @@ on: jobs: build_maxgraph_dev_package: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v7 with: @@ -47,20 +49,12 @@ jobs: packages/core/maxgraph-core-*.tgz build_projects: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 needs: [build_maxgraph_dev_package] strategy: # don't cancel running jobs even if one fails fail-fast: false matrix: - project: - - farm-ts - - lit-ts - - parcel-ts - - rollup-ts - - rsbuild-ts - - sveltekit-ts - - vitejs-ts npm-package: ['release', 'development'] steps: - name: Download the maxgraph npm package @@ -83,33 +77,35 @@ jobs: if: ${{ matrix.npm-package == 'development' }} # use wildcard as the file contains the version, and we don't know it run: npm install ${{steps.download.outputs.download-path}}/maxgraph-core*.tgz - - name: Build project - run: npm run build -w projects/_shared -w projects/${{matrix.project}} - - name: Upload project archive + - name: Build projects + run: ./build-all-examples.bash --fail-at-end + - name: Upload projects archive if: ${{ matrix.npm-package == 'release' }} uses: actions/upload-artifact@v7 with: - name: ${{matrix.project}} - path: ${{github.workspace}}/projects/${{matrix.project}}/dist + name: all-projects-dist + # the layout /dist is kept, as the paths are relative to the 'projects' directory + path: ${{github.workspace}}/projects/*/dist # bundle everything in a single bundle + create home page create_all-in-one_artifact: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 needs: 'build_projects' steps: - - name: Download all artifacts + - name: Download projects artifact uses: actions/download-artifact@v8 with: + name: all-projects-dist path: tmp - - name: Display structure of downloaded files after removing maxgraph-npm-package - run: | - rm -rf maxgraph-npm-package - ls -lhR + - name: Display structure of downloaded files + run: ls -lhR working-directory: tmp - name: Build the final directories layout run: | mkdir -p build - cp -R tmp/* build + for project_dist_dir in tmp/*/dist; do + cp -R "$project_dist_dir" "build/$(basename "$(dirname "$project_dist_dir")")" + done - name: List projects that will be referenced in the home page id: list_projects run: | @@ -172,7 +168,7 @@ jobs: environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Deploy to GitHub Pages id: deployment diff --git a/build-all-examples.bash b/build-all-examples.bash index 0bf4d00..762a3f8 100755 --- a/build-all-examples.bash +++ b/build-all-examples.bash @@ -1,57 +1,110 @@ #!/usr/bin/env bash set -euo pipefail -# This script builds all examples in the packages directory. -# From the root of the repository, run " ./build-all-examples.bash" +# This script builds all examples in the projects directory. +# From the root of the repository, run "./build-all-examples.bash" +usage() { + echo "Usage: $0 [OPTIONS]" + echo + echo "Build all examples and display bundle sizes." + echo + echo "Options:" + echo " --fail-at-end Keep building the remaining examples after a failure, and report all the failures at the" + echo " very end, after the size sections. Exit non-zero if any build failed. Without this option," + echo " the script stops at the first failing build. A failure of the shared project always stops" + echo " the script, as all examples depend on it. No effect with --list-size-only, which builds" + echo " nothing." + echo " --list-size-only Skip building, only display bundle sizes from existing dist/ directories" + echo " --help Show this help message" + return 0 +} -# Check for command line arguments LIST_SIZE_ONLY=false -if [[ $# -gt 0 && "$1" == "--list-size-only" ]]; then - LIST_SIZE_ONLY=true -fi +FAIL_AT_END=false +while [[ $# -gt 0 ]]; do + case "$1" in + --help) usage; exit 0 ;; + --fail-at-end) FAIL_AT_END=true ;; + --list-size-only) LIST_SIZE_ONLY=true ;; + *) echo "Unknown option: $1"; usage; exit 1 ;; + esac + shift +done + +SHARED_PROJECT_DIR="projects/_shared" + +EXAMPLE_DIRS=() +for dir in projects/*; do + if [[ -d "$dir" && "$dir" != "$SHARED_PROJECT_DIR" ]]; then + EXAMPLE_DIRS+=("$dir") + fi +done + +print_section_title() { + echo + echo "##################################################" + echo "$1" + echo "##################################################" +} + +FAILED_EXAMPLES=() -if [ "$LIST_SIZE_ONLY" = true ]; then +if [[ "$LIST_SIZE_ONLY" = true ]]; then echo "Skip building examples." else echo "Building all examples..." - npm run build -w projects/_shared - npm run build --workspaces + # Built first and outside the loop: npm does not order workspaces by dependency, and building the examples against + # a stale or missing shared library would give misleading results. + print_section_title "Building $SHARED_PROJECT_DIR" + npm run build -w "$SHARED_PROJECT_DIR" + for dir in "${EXAMPLE_DIRS[@]}"; do + print_section_title "Building $dir" + if [[ "$FAIL_AT_END" = true ]]; then + build_exit_code=0 + npm run build -w "$dir" || build_exit_code=$? + if [[ "$build_exit_code" -ne 0 ]]; then + echo "Build of $dir FAILED with exit code $build_exit_code" + FAILED_EXAMPLES+=("$(basename "$dir") (exit code $build_exit_code)") + fi + else + npm run build -w "$dir" + fi + done -# for dir in packages/ts-example* packages/js-example*; do -# if [ -d "$dir" ]; then -# echo -# echo "##################################################" -# echo "Building $dir" -# echo "##################################################" -# (cd "$dir" && npm run build) -# fi -# done - - echo "All examples built successfully." + if [[ ${#FAILED_EXAMPLES[@]} -eq 0 ]]; then + echo "All examples built successfully." + else + echo "${#FAILED_EXAMPLES[@]} example(s) failed to build, see the summary at the end." + fi fi -for dir in projects/*; do - if [ -d "$dir" ]; then - echo - echo "##################################################" - echo "Files in $dir/dist directory:" - echo "##################################################" - - if [ -d "$dir/dist" ]; then - # Find all JS files and display sizes with 2 decimal places - # Use 1000 to match Vite's size display - find "$dir/dist" -name "*.js" -type f -exec ls -l {} \; | LC_NUMERIC=C awk '{ - # Convert bytes to KB with 2 decimal places - size_kb = $5 / 1000 - printf "%.2f kB %s\n", size_kb, $9 - }' - else - echo "No dist directory found in $dir" - fi +for dir in "${EXAMPLE_DIRS[@]}"; do + print_section_title "Files in $dir/dist directory:" + + if [[ -d "$dir/dist" ]]; then + # Find all JS files and display sizes with 2 decimal places + # Use 1000 to match Vite's size display + find "$dir/dist" -name "*.js" -type f -exec ls -l {} \; | LC_NUMERIC=C awk '{ + # Convert bytes to KB with 2 decimal places + size_kb = $5 / 1000 + printf "%.2f kB %s\n", size_kb, $9 + }' + else + echo "No dist directory found in $dir" fi done +if [[ ${#FAILED_EXAMPLES[@]} -gt 0 ]]; then + print_section_title "Failed builds" + echo + for failed_example in "${FAILED_EXAMPLES[@]}"; do + echo "- $failed_example" + done + echo + echo "${#FAILED_EXAMPLES[@]} example(s) failed to build." + exit 1 +fi