diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 43716ca235d..7af4a26bb6c 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -106,13 +106,11 @@ jobs: if [[ ${{ contains(github.ref, 'hotfix') }} == 'true' ]]; then sed -e "s|hotfix/REPLACE|${{ github.ref_name }}|" --in-place release.config.js fi - - name: Deploy playground to GitHub Pages - uses: peaceiris/actions-gh-pages@373f7f263a76c20808c831209c920827a82a2847 # v3 + - name: Prepare deployment files if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./build - full_commit_message: "Build for ${{ github.sha }} ${{ github.event.head_commit.message }}" + run: | + touch build/.nojekyll + echo "smalruby.app" > build/CNAME - name: Deploy playground to Smalruby.app GitHub Pages uses: peaceiris/actions-gh-pages@373f7f263a76c20808c831209c920827a82a2847 # v3 if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' @@ -122,9 +120,52 @@ jobs: full_commit_message: "Build for ${{ github.sha }} ${{ github.event.head_commit.message }}" cname: smalruby.app external_repository: smalruby/smalruby.app + - name: Rebuild for smalruby3-gui GitHub Pages + if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' + env: + NODE_OPTIONS: --max-old-space-size=4000 + NODE_ENV: production + PUBLIC_PATH: /smalruby3-gui/ + run: npm run build + - name: Prepare deployment files for smalruby3-gui GitHub Pages + if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' + run: touch build/.nojekyll + - name: Deploy playground to GitHub Pages + uses: peaceiris/actions-gh-pages@373f7f263a76c20808c831209c920827a82a2847 # v3 + if: github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./build + full_commit_message: "Build for ${{ github.sha }} ${{ github.event.head_commit.message }}" - name: Set branch name id: branch run: echo "BRANCH_NAME=${{ github.head_ref || github.ref_name }}" >> $GITHUB_OUTPUT + - name: Rebuild for branch GitHub Pages + if: | + (!( + github.ref == 'refs/heads/develop' || + github.ref == 'refs/heads/master' || + github.ref == 'refs/heads/main' || + startsWith(github.ref, 'refs/heads/hotfix/') || + startsWith(github.ref, 'refs/heads/dependabot/') || + startsWith(github.ref, 'refs/heads/renovate/') + )) + env: + NODE_OPTIONS: --max-old-space-size=4000 + NODE_ENV: production + PUBLIC_PATH: /smalruby3-gui/${{ steps.branch.outputs.BRANCH_NAME }}/ + run: npm run build + - name: Prepare deployment files for branch GitHub Pages + if: | + (!( + github.ref == 'refs/heads/develop' || + github.ref == 'refs/heads/master' || + github.ref == 'refs/heads/main' || + startsWith(github.ref, 'refs/heads/hotfix/') || + startsWith(github.ref, 'refs/heads/dependabot/') || + startsWith(github.ref, 'refs/heads/renovate/') + )) + run: touch build/.nojekyll - name: Deploy playground to GitHub Pages for branch if: | (!( diff --git a/package.json b/package.json index 70b1ec02339..dc50411be38 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "scripts": { "setup-opal": "node ./scripts/make-setup-opal.js", "setup-scratch-vm": "cd node_modules/scratch-vm && npm install && webpack", - "build": "npm run clean && node ./scripts/makePWAAssetsManifest.js && webpack", + "build": "npm run clean && node ./scripts/makePWAAssetsManifest.js && webpack && node ./scripts/postbuild.mjs", "clean": "rimraf ./build && mkdirp build && rimraf ./dist && mkdirp dist", "deploy": "touch build/.nojekyll && gh-pages -t -d build -m \"[skip ci] Build for $(git log --pretty=format:%H -n1)\"", "deploy:smalruby.app": "rimraf node_modules/gh-pages/.cache && echo \"smalruby.app\" > build/CNAME && touch build/.nojekyll && gh-pages -t -d build -m \"build: build for $(git log --pretty=format:%H -n1) [skip ci] \"", diff --git a/scripts/postbuild.mjs b/scripts/postbuild.mjs new file mode 100644 index 00000000000..d8accb5a47d --- /dev/null +++ b/scripts/postbuild.mjs @@ -0,0 +1,71 @@ +// Post-build script to fix fetch-worker paths for GitHub Pages subdirectory deployments +// This script runs after webpack build and modifies the generated JavaScript files +// to ensure correct worker loading when PUBLIC_PATH is set for subdirectory deployments + +import fs from 'fs'; +import path from 'path'; +import {fileURLToPath} from 'url'; + +// these aren't set in ESM mode +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +// base/root path for the project +const basePath = path.join(__dirname, '..'); +const buildPath = path.join(basePath, 'build'); + +/** + * Fix fetch-worker paths in JavaScript files for subdirectory deployments + * @param {string} filePath - Path to the JavaScript file + * @param {string} publicPath - The public path (e.g., '/smalruby3-gui/') + */ +const fixFetchWorkerPaths = (filePath, publicPath) => { + if (!fs.existsSync(filePath)) { + console.warn(`File not found: ${filePath}`); + return; + } + + const content = fs.readFileSync(filePath, 'utf8'); + + // Replace relative "chunks/" paths with absolute paths including publicPath + const fixedContent = content.replace( + /return "chunks\/" \+ "fetch-worker"/g, + `return "${publicPath}chunks/" + "fetch-worker"` + ).replace( + /[=]>"chunks\/fetch-worker\./g, + `=>"${publicPath}chunks/fetch-worker.` + ); + + if (content === fixedContent) { + console.info(`No fetch-worker paths found in ${path.relative(basePath, filePath)}`); + } else { + fs.writeFileSync(filePath, fixedContent); + console.info(`Fixed fetch-worker paths in ${path.relative(basePath, filePath)}`); + } +}; + +const postbuild = () => { + const publicPath = process.env.PUBLIC_PATH; + + if (!publicPath) { + console.info('PUBLIC_PATH not set - skipping fetch-worker path fixes'); + return; + } + + console.info(`PUBLIC_PATH is set to: ${publicPath}`); + console.info('Fixing fetch-worker paths for subdirectory deployment...'); + + // Files that need fetch-worker path fixes + const filesToFix = [ + path.join(buildPath, 'gui.js'), + path.join(buildPath, 'player.js') + ]; + + for (const filePath of filesToFix) { + fixFetchWorkerPaths(filePath, publicPath); + } +}; + +postbuild(); +console.info('Post-build script complete'); +process.exit(0); diff --git a/src/lib/ruby-to-blocks-converter/constants.js b/src/lib/ruby-to-blocks-converter/constants.js index e0fb417575f..474f324d549 100644 --- a/src/lib/ruby-to-blocks-converter/constants.js +++ b/src/lib/ruby-to-blocks-converter/constants.js @@ -43,6 +43,17 @@ const KeyOptions = [ '9' ]; +/** + * scratch-vm/src/engine/variable.jsからコピー + * @const + */ +const Variable = { + SCALAR_TYPE: '', + LIST_TYPE: 'list', + BROADCAST_MESSAGE_TYPE: 'broadcast_msg' +}; + export { - KeyOptions + KeyOptions, + Variable }; diff --git a/src/lib/ruby-to-blocks-converter/event.js b/src/lib/ruby-to-blocks-converter/event.js index 20febbd2e94..0d7bb41da77 100644 --- a/src/lib/ruby-to-blocks-converter/event.js +++ b/src/lib/ruby-to-blocks-converter/event.js @@ -1,6 +1,5 @@ // eslint-disable-next-line import/no-unresolved -import Variable from 'scratch-vm/src/engine/variable'; -import {KeyOptions} from './constants'; +import {KeyOptions, Variable} from './constants'; const GreaterThanMenu = [ 'LOUDNESS', diff --git a/src/lib/ruby-to-blocks-converter/index.js b/src/lib/ruby-to-blocks-converter/index.js index f8180e62281..0cb6023d871 100644 --- a/src/lib/ruby-to-blocks-converter/index.js +++ b/src/lib/ruby-to-blocks-converter/index.js @@ -5,7 +5,7 @@ import log from '../log'; import Blockly from 'scratch-blocks'; import RubyParser from '../ruby-parser'; // eslint-disable-next-line import/no-unresolved -import Variable from 'scratch-vm/src/engine/variable'; +import {Variable} from './constants'; import Primitive from './primitive'; import {RubyToBlocksConverterError} from './errors'; @@ -588,7 +588,7 @@ class RubyToBlocksConverter { SoundConverter, SensingConverter ]; - + for (let i = 0; i < legacyConverters.length; i++) { const converter = legacyConverters[i]; if (Object.prototype.hasOwnProperty.call(converter, handlerName)) { diff --git a/webpack.config.js b/webpack.config.js index 08fa08aff04..0ffb68b6a60 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -101,9 +101,9 @@ const distConfig = baseConfig.clone() }, output: { path: path.resolve(__dirname, 'dist') - } + }, + externals: ['react', 'react-dom'] }) - .addExternals(['react', 'react-dom']) .addPlugin( new CopyWebpackPlugin({ patterns: [