Merge pull request #9675 from RaspberryPiFoundation/merger

chore: Merge `main` into `v13`
This commit is contained in:
Aaron Dodson
2026-04-01 12:51:32 -07:00
committed by GitHub
14 changed files with 428 additions and 513 deletions
+3 -1
View File
@@ -3,7 +3,9 @@
name: Node.js CI
on: [pull_request]
on:
pull_request:
workflow_call:
permissions:
contents: read
@@ -1,66 +0,0 @@
# Workflow for running the keyboard navigation plugin's automated tests.
name: Keyboard Navigation Automated Tests
on:
workflow_dispatch:
pull_request:
push:
branches:
- main
permissions:
contents: read
jobs:
webdriverio_tests:
name: WebdriverIO tests
timeout-minutes: 10
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
steps:
- name: Checkout core Blockly
uses: actions/checkout@v5
with:
path: core-blockly
- name: Checkout keyboard navigation plugin
uses: actions/checkout@v5
with:
repository: 'google/blockly-keyboard-experimentation'
ref: 'main'
path: blockly-keyboard-experimentation
- name: Use Node.js 20.x
uses: actions/setup-node@v5
with:
node-version: 20.x
- name: NPM install
run: |
cd core-blockly
npm install
cd ..
cd blockly-keyboard-experimentation
npm install
cd ..
- name: Link latest core main with plugin
run: |
cd core-blockly/packages/blockly
npm run package
cd dist
npm link
cd ../../../../blockly-keyboard-experimentation
npm link blockly
cd ..
- name: Run keyboard navigation plugin tests
run: |
cd blockly-keyboard-experimentation
npm run test
+137
View File
@@ -0,0 +1,137 @@
name: Publish to npm
on:
workflow_dispatch:
inputs:
dry_run:
description: 'Dry run - print the version that would be published, but do not commit or publish anything.'
required: false
default: false
type: boolean
skip_versioning:
description: >
Skip version bump - use the version already in the repo
(e.g. retry after npm publish failed but the release commit is already pushed).
required: false
default: false
type: boolean
permissions:
contents: write
id-token: write
jobs:
ci:
uses: ./.github/workflows/build.yml
version:
needs: ci
runs-on: ubuntu-latest
timeout-minutes: 30
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: 24.x
registry-url: 'https://registry.npmjs.org'
- name: Install dependencies
if: ${{ !inputs.skip_versioning }}
run: npm ci
- name: Determine version bump
id: bump
if: ${{ !inputs.skip_versioning }}
working-directory: packages/blockly
run: |
RELEASE_TYPE=$(npx conventional-recommended-bump --preset conventionalcommits -t blockly-)
echo "release_type=$RELEASE_TYPE" >> "$GITHUB_OUTPUT"
echo "Recommended bump: $RELEASE_TYPE"
- name: Apply version bump
if: ${{ !inputs.skip_versioning }}
working-directory: packages/blockly
run: npm version ${{ steps.bump.outputs.release_type }} --no-git-tag-version
- name: Read package version
id: version
working-directory: packages/blockly
run: |
VERSION=$(node -p "require('./package.json').version")
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Version: $VERSION"
- name: Upload versioned files
if: ${{ !inputs.skip_versioning }}
uses: actions/upload-artifact@v4
with:
name: versioned-files
path: |
packages/blockly/package.json
package-lock.json
publish:
needs: version
runs-on: ubuntu-latest
if: ${{ !inputs.dry_run }}
environment: release
steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
ssh-key: ${{ secrets.DEPLOY_PRIVATE_KEY }}
- name: Download versioned files
if: ${{ !inputs.skip_versioning }}
uses: actions/download-artifact@v4
with:
name: versioned-files
- name: Commit and push version bump
if: ${{ !inputs.skip_versioning }}
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add packages/blockly/package.json package-lock.json
git commit -m "release: v${{ needs.version.outputs.version }}"
git push
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: 24.x
registry-url: 'https://registry.npmjs.org'
- name: Install dependencies
run: npm ci
- name: Build package
working-directory: packages/blockly
run: npm run package
- name: Publish to npm
working-directory: packages/blockly/dist
run: npm publish --verbose
- name: Create tarball
working-directory: packages/blockly
run: npm pack ./dist
- name: Create GitHub release
working-directory: packages/blockly
env:
GH_TOKEN: ${{ github.token }}
run: |
TARBALL="blockly-${{ needs.version.outputs.version }}.tgz"
gh release create "blockly-v${{ needs.version.outputs.version }}" "$TARBALL" \
--repo "$GITHUB_REPOSITORY" \
--title "blockly-v${{ needs.version.outputs.version }}" \
--generate-notes
+36
View File
@@ -0,0 +1,36 @@
# Manual workflow to update GitHub Pages from a chosen source branch.
# The gulp updateGithubPages task builds the repo and force-pushes to gh-pages.
name: Update GitHub Pages
on:
workflow_dispatch:
inputs:
source_branch:
description: 'Source branch to build and deploy to GitHub Pages'
required: true
type: string
default: main
permissions:
contents: write
jobs:
update-gh-pages:
timeout-minutes: 15
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
ref: ${{ inputs.source_branch }}
fetch-depth: 0
- name: Use Node.js
uses: actions/setup-node@v5
with:
node-version: 24.x
- name: Update GitHub Pages
working-directory: ./packages/blockly
run: npm run updateGithubPages:staging
+100 -198
View File
@@ -18,15 +18,11 @@
},
"node_modules/@acemir/cssom": {
"version": "0.9.31",
"resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.31.tgz",
"integrity": "sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==",
"dev": true,
"license": "MIT"
},
"node_modules/@asamuzakjp/css-color": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.2.tgz",
"integrity": "sha512-NfBUvBaYgKIuq6E/RBLY1m0IohzNHAYyaJGuTK79Z23uNwmz2jl1mPsC5ZxCCxylinKhT1Amn5oNTlx1wN8cQg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -39,8 +35,6 @@
},
"node_modules/@asamuzakjp/css-color/node_modules/lru-cache": {
"version": "11.2.7",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz",
"integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==",
"dev": true,
"license": "BlueOak-1.0.0",
"engines": {
@@ -49,8 +43,6 @@
},
"node_modules/@asamuzakjp/dom-selector": {
"version": "6.8.1",
"resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.8.1.tgz",
"integrity": "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -63,8 +55,6 @@
},
"node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": {
"version": "11.2.7",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz",
"integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==",
"dev": true,
"license": "BlueOak-1.0.0",
"engines": {
@@ -73,8 +63,6 @@
},
"node_modules/@asamuzakjp/nwsapi": {
"version": "2.3.9",
"resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz",
"integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==",
"dev": true,
"license": "MIT"
},
@@ -458,8 +446,6 @@
},
"node_modules/@csstools/color-helpers": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.2.tgz",
"integrity": "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==",
"dev": true,
"funding": [
{
@@ -478,8 +464,6 @@
},
"node_modules/@csstools/css-calc": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.1.1.tgz",
"integrity": "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==",
"dev": true,
"funding": [
{
@@ -502,8 +486,6 @@
},
"node_modules/@csstools/css-color-parser": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.0.2.tgz",
"integrity": "sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw==",
"dev": true,
"funding": [
{
@@ -530,8 +512,6 @@
},
"node_modules/@csstools/css-parser-algorithms": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz",
"integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==",
"dev": true,
"funding": [
{
@@ -553,8 +533,6 @@
},
"node_modules/@csstools/css-syntax-patches-for-csstree": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.1.tgz",
"integrity": "sha512-BvqN0AMWNAnLk9G8jnUT77D+mUbY/H2b3uDTvg2isJkHaOufUE2R3AOwxWo7VBQKT1lOdwdvorddo2B/lk64+w==",
"dev": true,
"funding": [
{
@@ -578,8 +556,6 @@
},
"node_modules/@csstools/css-tokenizer": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz",
"integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==",
"dev": true,
"funding": [
{
@@ -598,8 +574,6 @@
},
"node_modules/@exodus/bytes": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.0.tgz",
"integrity": "sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -732,8 +706,6 @@
},
"node_modules/bidi-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz",
"integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -891,8 +863,6 @@
},
"node_modules/css-tree": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz",
"integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -905,8 +875,6 @@
},
"node_modules/cssstyle": {
"version": "5.3.7",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz",
"integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -932,8 +900,6 @@
},
"node_modules/data-urls": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/data-urls/-/data-urls-6.0.1.tgz",
"integrity": "sha512-euIQENZg6x8mj3fO6o9+fOW8MimUI4PpD/fZBhJfeioZVy9TUpM4UY7KjQNVZFlqwJ0UdzRDzkycB997HEq1BQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -946,8 +912,6 @@
},
"node_modules/data-urls/node_modules/whatwg-mimetype": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz",
"integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -972,8 +936,6 @@
},
"node_modules/decimal.js": {
"version": "10.6.0",
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
"integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
"dev": true,
"license": "MIT"
},
@@ -1074,6 +1036,24 @@
"node": ">=16"
}
},
"node_modules/git-semver-tags": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-7.0.1.tgz",
"integrity": "sha512-NY0ZHjJzyyNXHTDZmj+GG7PyuAKtMsyWSwh07CR2hOZFa+/yoTsXci/nF2obzL8UDhakFNkD9gNdt/Ed+cxh2Q==",
"deprecated": "This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead.",
"dev": true,
"license": "MIT",
"dependencies": {
"meow": "^12.0.1",
"semver": "^7.5.2"
},
"bin": {
"git-semver-tags": "cli.mjs"
},
"engines": {
"node": ">=16"
}
},
"node_modules/glob": {
"version": "13.0.0",
"dev": true,
@@ -1113,14 +1093,14 @@
}
},
"node_modules/google-closure-compiler": {
"version": "20260315.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler/-/google-closure-compiler-20260315.0.0.tgz",
"integrity": "sha512-z+Zdkth5+bdt+bSy3HuYRgjSAgx4WncBZ0Rd+/1Hf3wFemkkTxXGXpG7A5Y8n5WrTsPd1n/fxVuD5xfFL6s5Dw==",
"version": "20260330.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler/-/google-closure-compiler-20260330.0.0.tgz",
"integrity": "sha512-USY3fekBavIfAkzHEooo6FcuTT/+z6FbfMRK3l3nsgsKB2oJ4baPPz2XYGSivHNstB8l10CcPvWh5FwlWZpzvQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"chalk": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 <5.6.1 || ^5.6.2 >5.6.1",
"google-closure-compiler-java": "^20260315.0.0",
"google-closure-compiler-java": "^20260330.0.0",
"minimist": "^1.0.0",
"vinyl": "^3.0.1",
"vinyl-sourcemaps-apply": "^0.2.0"
@@ -1132,23 +1112,23 @@
"node": ">=18"
},
"optionalDependencies": {
"google-closure-compiler-linux": "^20260315.0.0",
"google-closure-compiler-linux-arm64": "^20260315.0.0",
"google-closure-compiler-macos": "^20260315.0.0",
"google-closure-compiler-windows": "^20260315.0.0"
"google-closure-compiler-linux": "^20260330.0.0",
"google-closure-compiler-linux-arm64": "^20260330.0.0",
"google-closure-compiler-macos": "^20260330.0.0",
"google-closure-compiler-windows": "^20260330.0.0"
}
},
"node_modules/google-closure-compiler-java": {
"version": "20260315.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-java/-/google-closure-compiler-java-20260315.0.0.tgz",
"integrity": "sha512-3CYSN3x7S7xCc/7Yx9vmH4pOc/8tkJdPjftUV1tUt2/tYKYEeH9mGv5dtrs22Uf6qXdIqlEBGg+ZQXX13xVpww==",
"version": "20260330.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-java/-/google-closure-compiler-java-20260330.0.0.tgz",
"integrity": "sha512-wc+HpQlNvS5mquzVjpOjhVlgYgvxnOyqPDCJJN2k7+5dVE7mbzZya7mIEfsPaRZ39KbPVvNrDpMEAahKiuNtjA==",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/google-closure-compiler-linux": {
"version": "20260315.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-linux/-/google-closure-compiler-linux-20260315.0.0.tgz",
"integrity": "sha512-jXUnyY3Cr5kmBDmGuxw3HULjzX69AeXVRcIpI+YuFGfo8qX1dIbkOpNK7JHWtJ7qE01foGmCwjnx5WOSrplYyg==",
"version": "20260330.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-linux/-/google-closure-compiler-linux-20260330.0.0.tgz",
"integrity": "sha512-BWEknhsCj/zero4Zk0/FtbAM1eO3QQA34xGQa4HeREV36trs/zmVCSVRqYCYcEAAEBiMjj97wMPdhFSkm72k8g==",
"cpu": [
"x32",
"x64"
@@ -1161,9 +1141,9 @@
]
},
"node_modules/google-closure-compiler-linux-arm64": {
"version": "20260315.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-linux-arm64/-/google-closure-compiler-linux-arm64-20260315.0.0.tgz",
"integrity": "sha512-e0dSgFEg/bE9gscw+u2Roy/FkJOQ/6MvG3nBCPR8IqAkJ+ibBAQKnYOSK1sAUp1bXJROiUJy6a+GTJ312FKS+A==",
"version": "20260330.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-linux-arm64/-/google-closure-compiler-linux-arm64-20260330.0.0.tgz",
"integrity": "sha512-7C9khLgtZEUfZ/xCkjLVTC5vRJt5CmfWwiAk/u3+pPzsDubngHwKE1e0UTPqNwJEXo8VVXM4OdvrY7hzwR4MZg==",
"cpu": [
"arm64"
],
@@ -1175,9 +1155,9 @@
]
},
"node_modules/google-closure-compiler-macos": {
"version": "20260315.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-macos/-/google-closure-compiler-macos-20260315.0.0.tgz",
"integrity": "sha512-yhY46Mdbqs7HAPsYAhXlt9Q2rROLZfaZrTFZZqyVo/uufEmGH3vOyxshTbBQWhaJQHkELWsc/XKSVfvX4rcoYA==",
"version": "20260330.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-macos/-/google-closure-compiler-macos-20260330.0.0.tgz",
"integrity": "sha512-3mGI7eYwIZYAZFdMwpS4wXB5+q/kKbl936FtvRIIgRtFhSX7m6kwsyXqGP62ZvuOCcPcW14dC6k7g6l7eS2Fgw==",
"cpu": [
"arm64"
],
@@ -1189,9 +1169,9 @@
]
},
"node_modules/google-closure-compiler-windows": {
"version": "20260315.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-windows/-/google-closure-compiler-windows-20260315.0.0.tgz",
"integrity": "sha512-EpIPPU6vQ5EzuzKQMe3vhEWLqqXY4SKNoLjXrr4GWXoses9h7xT6nkHDuDe/7x5MWZOMRv4qmlW3PzLCsx98qg==",
"version": "20260330.0.0",
"resolved": "https://registry.npmjs.org/google-closure-compiler-windows/-/google-closure-compiler-windows-20260330.0.0.tgz",
"integrity": "sha512-dqMKvjzdAlgERhHKHG12dKrOcL2ASNeKP1c3doCQn3vwZizz1xV2Ns6m711tb6pfNXFstfR6VJAoMuv/BjmdYQ==",
"cpu": [
"x32",
"x64"
@@ -1333,8 +1313,6 @@
},
"node_modules/jsdom": {
"version": "27.4.0",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.4.0.tgz",
"integrity": "sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1373,8 +1351,6 @@
},
"node_modules/jsdom/node_modules/entities": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
"integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
@@ -1386,8 +1362,6 @@
},
"node_modules/jsdom/node_modules/html-encoding-sniffer": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz",
"integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1399,8 +1373,6 @@
},
"node_modules/jsdom/node_modules/parse5": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz",
"integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1503,8 +1475,6 @@
},
"node_modules/mdn-data": {
"version": "2.27.1",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz",
"integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==",
"dev": true,
"license": "CC0-1.0"
},
@@ -1668,6 +1638,20 @@
"node": ">=v12.22.7"
}
},
"node_modules/semver": {
"version": "7.5.4",
"dev": true,
"license": "ISC",
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/source-map": {
"version": "0.5.7",
"dev": true,
@@ -1678,8 +1662,6 @@
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
@@ -1772,8 +1754,6 @@
},
"node_modules/tldts": {
"version": "7.0.26",
"resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.26.tgz",
"integrity": "sha512-WiGwQjr0qYdNNG8KpMKlSvpxz652lqa3Rd+/hSaDcY4Uo6SKWZq2LAF+hsAhUewTtYhXlorBKgNF3Kk8hnjGoQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1785,15 +1765,11 @@
},
"node_modules/tldts-core": {
"version": "7.0.26",
"resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.26.tgz",
"integrity": "sha512-5WJ2SqFsv4G2Dwi7ZFVRnz6b2H1od39QME1lc2y5Ew3eWiZMAeqOAfWpRP9jHvhUl881406QtZTODvjttJs+ew==",
"dev": true,
"license": "MIT"
},
"node_modules/tough-cookie": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz",
"integrity": "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -1805,8 +1781,6 @@
},
"node_modules/tr46": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz",
"integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1867,8 +1841,6 @@
},
"node_modules/webidl-conversions": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz",
"integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
@@ -1885,8 +1857,6 @@
},
"node_modules/whatwg-url": {
"version": "15.1.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-15.1.0.tgz",
"integrity": "sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -1980,7 +1950,7 @@
}
},
"packages/blockly": {
"version": "12.4.1",
"version": "12.5.1",
"hasInstallScript": true,
"license": "Apache-2.0",
"devDependencies": {
@@ -1995,6 +1965,8 @@
"async-done": "^2.0.0",
"chai": "^6.0.1",
"concurrently": "^9.0.1",
"conventional-changelog-conventionalcommits": "^7.0.2",
"conventional-recommended-bump": "^9.0.0",
"eslint": "^9.15.0",
"eslint-config-google": "^0.14.0",
"eslint-config-prettier": "^10.1.1",
@@ -2003,16 +1975,13 @@
"eslint-plugin-prettier": "^5.2.1",
"glob": "^11.0.1",
"globals": "^16.0.0",
"google-closure-compiler": "^20260315.0.0",
"google-closure-compiler": "^20260330.0.0",
"gulp": "^5.0.0",
"gulp-concat": "^2.6.1",
"gulp-gzip": "^1.4.2",
"gulp-header": "^2.0.9",
"gulp-insert": "^0.5.0",
"gulp-rename": "^2.0.0",
"gulp-replace": "^1.0.0",
"gulp-series": "^1.0.2",
"gulp-shell": "^0.8.0",
"gulp-sourcemaps": "^3.0.0",
"gulp-umd": "^2.0.0",
"http-server": "^14.0.0",
@@ -4698,6 +4667,47 @@
"node": ">= 0.6"
}
},
"packages/blockly/node_modules/conventional-changelog-preset-loader": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-4.1.0.tgz",
"integrity": "sha512-HozQjJicZTuRhCRTq4rZbefaiCzRM2pr6u2NL3XhrmQm4RMnDXfESU6JKu/pnKwx5xtdkYfNCsbhN5exhiKGJA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=16"
}
},
"packages/blockly/node_modules/conventional-commits-filter": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-4.0.0.tgz",
"integrity": "sha512-rnpnibcSOdFcdclpFwWa+pPlZJhXE7l+XK04zxhbWrhgpR96h33QLz8hITTXbcYICxVr3HZFtbtUAQ+4LdBo9A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=16"
}
},
"packages/blockly/node_modules/conventional-recommended-bump": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-9.0.0.tgz",
"integrity": "sha512-HR1yD0G5HgYAu6K0wJjLd7QGRK8MQDqqj6Tn1n/ja1dFwBCE6QmV+iSgQ5F7hkx7OUR/8bHpxJqYtXj2f/opPQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"conventional-changelog-preset-loader": "^4.1.0",
"conventional-commits-filter": "^4.0.0",
"conventional-commits-parser": "^5.0.0",
"git-raw-commits": "^4.0.0",
"git-semver-tags": "^7.0.0",
"meow": "^12.0.1"
},
"bin": {
"conventional-recommended-bump": "cli.mjs"
},
"engines": {
"node": ">=16"
}
},
"packages/blockly/node_modules/convert-source-map": {
"version": "1.8.0",
"dev": true,
@@ -6525,36 +6535,6 @@
"xtend": "~4.0.1"
}
},
"packages/blockly/node_modules/gulp-insert": {
"version": "0.5.0",
"dev": true,
"license": "MIT",
"dependencies": {
"readable-stream": "^1.0.26-4",
"streamqueue": "0.0.6"
}
},
"packages/blockly/node_modules/gulp-insert/node_modules/isarray": {
"version": "0.0.1",
"dev": true,
"license": "MIT"
},
"packages/blockly/node_modules/gulp-insert/node_modules/readable-stream": {
"version": "1.1.14",
"dev": true,
"license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.1",
"isarray": "0.0.1",
"string_decoder": "~0.10.x"
}
},
"packages/blockly/node_modules/gulp-insert/node_modules/string_decoder": {
"version": "0.10.31",
"dev": true,
"license": "MIT"
},
"packages/blockly/node_modules/gulp-rename": {
"version": "2.1.0",
"dev": true,
@@ -6578,48 +6558,6 @@
"node": ">=10"
}
},
"packages/blockly/node_modules/gulp-series": {
"version": "1.0.2",
"dev": true,
"license": "MIT"
},
"packages/blockly/node_modules/gulp-shell": {
"version": "0.8.0",
"dev": true,
"license": "MIT",
"dependencies": {
"chalk": "^3.0.0",
"fancy-log": "^1.3.3",
"lodash.template": "^4.5.0",
"plugin-error": "^1.0.1",
"through2": "^3.0.1",
"tslib": "^1.10.0"
},
"engines": {
"node": ">=10.0.0"
}
},
"packages/blockly/node_modules/gulp-shell/node_modules/chalk": {
"version": "3.0.0",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=8"
}
},
"packages/blockly/node_modules/gulp-shell/node_modules/through2": {
"version": "3.0.2",
"dev": true,
"license": "MIT",
"dependencies": {
"inherits": "^2.0.4",
"readable-stream": "2 || 3"
}
},
"packages/blockly/node_modules/gulp-sourcemaps": {
"version": "3.0.0",
"dev": true,
@@ -9075,37 +9013,6 @@
"any-promise": "^1.1.0"
}
},
"packages/blockly/node_modules/streamqueue": {
"version": "0.0.6",
"dev": true,
"dependencies": {
"readable-stream": "^1.0.26-2"
},
"engines": {
"node": ">= 0.10.0"
}
},
"packages/blockly/node_modules/streamqueue/node_modules/isarray": {
"version": "0.0.1",
"dev": true,
"license": "MIT"
},
"packages/blockly/node_modules/streamqueue/node_modules/readable-stream": {
"version": "1.1.14",
"dev": true,
"license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.1",
"isarray": "0.0.1",
"string_decoder": "~0.10.x"
}
},
"packages/blockly/node_modules/streamqueue/node_modules/string_decoder": {
"version": "0.10.31",
"dev": true,
"license": "MIT"
},
"packages/blockly/node_modules/string_decoder": {
"version": "1.1.1",
"dev": true,
@@ -9339,11 +9246,6 @@
"typescript": ">=4.8.4"
}
},
"packages/blockly/node_modules/tslib": {
"version": "1.14.1",
"dev": true,
"license": "0BSD"
},
"packages/blockly/node_modules/type": {
"version": "1.2.0",
"dev": true,
+1 -4
View File
@@ -291,10 +291,7 @@ export class Connection {
}
let event;
if (
eventUtils.isEnabled() &&
!childConnection.getSourceBlock().isDeadOrDying()
) {
if (eventUtils.isEnabled()) {
event = new (eventUtils.get(EventType.BLOCK_MOVE))(
childConnection.getSourceBlock(),
) as BlockMove;
+4 -14
View File
@@ -98,14 +98,7 @@ const content = `
.blocklyBlockCanvas.blocklyCanvasTransitioning,
.blocklyBubbleCanvas.blocklyCanvasTransitioning {
transition: transform .15s;
}
@media (prefers-reduced-motion) {
.blocklyBlockCanvas.blocklyCanvasTransitioning,
.blocklyBubbleCanvas.blocklyCanvasTransitioning {
transition: none;
}
transition: transform .5s;
}
.blocklyEmboss {
@@ -466,17 +459,14 @@ input[type=number] {
}
/* State: selected/checked. */
.blocklyMenuItemCheckbox {
height: 16px;
position: absolute;
width: 16px;
}
.blocklyMenuItemSelected .blocklyMenuItemCheckbox {
background: url(<<<PATH>>>/sprites.svg) no-repeat -48px -16px;
float: left;
margin-left: -24px;
width: 16px;
height: 16px;
position: static; /* Scroll with the menu. */
display: block;
}
.blocklyMenuItemRtl .blocklyMenuItemCheckbox {
+6 -8
View File
@@ -73,11 +73,11 @@ export class LayerManager {
* @internal
*/
appendToAnimationLayer(elem: IRenderedElement) {
const currentTransform = this.dragLayer?.style.transform;
const currentTransform = this.dragLayer?.getAttribute('transform');
// Only update the current transform when appending, so animations don't
// move if the workspace moves.
if (currentTransform && this.animationLayer) {
this.animationLayer.style.transform = currentTransform;
if (currentTransform) {
this.animationLayer?.setAttribute('transform', currentTransform);
}
this.animationLayer?.appendChild(elem.getSvgRoot());
}
@@ -88,12 +88,10 @@ export class LayerManager {
* @internal
*/
translateLayers(newCoord: Coordinate, newScale: number) {
const translation = `translate(${newCoord.x}px, ${newCoord.y}px) scale(${newScale})`;
if (this.dragLayer) {
this.dragLayer.style.transform = translation;
}
const translation = `translate(${newCoord.x}, ${newCoord.y}) scale(${newScale})`;
this.dragLayer?.setAttribute('transform', translation);
for (const [_, layer] of this.layers) {
layer.style.transform = translation;
layer.setAttribute('transform', translation);
}
}
+17 -17
View File
@@ -11,7 +11,6 @@
*/
// Former goog.module ID: Blockly.Toolbox
// Unused import preserved for side-effects. Remove if unneeded.
import {BlockSvg} from '../block_svg.js';
import * as browserEvents from '../browser_events.js';
import * as common from '../common.js';
@@ -199,7 +198,7 @@ export class Toolbox
aria.setRole(this.contentsDiv_, aria.Role.TREE);
container.appendChild(this.contentsDiv_);
svg.parentNode!.insertBefore(container, svg);
svg.parentNode?.insertBefore(container, svg);
this.attachEvents_(container, this.contentsDiv_);
return container;
@@ -288,7 +287,7 @@ export class Toolbox
const itemId = (targetElement as Element).getAttribute('id');
if (itemId) {
const item = this.getToolboxItemById(itemId);
if (item!.isSelectable()) {
if (item?.isSelectable()) {
this.setSelectedItem(item);
(item as ISelectableToolboxItem).onClick(e);
}
@@ -380,7 +379,7 @@ export class Toolbox
const toolboxItemDef = toolboxDef[i];
this.createToolboxItem(toolboxItemDef, fragment);
}
this.contentsDiv_!.appendChild(fragment);
this.contentsDiv_?.appendChild(fragment);
}
/**
@@ -419,9 +418,7 @@ export class Toolbox
}
// Adds the ID to the HTML element that can receive a click.
// This is used in onClick_ to find the toolboxItem that was clicked.
if (toolboxItem.getClickTarget()) {
toolboxItem.getClickTarget()!.setAttribute('id', toolboxItem.getId());
}
toolboxItem.getClickTarget()?.setAttribute('id', toolboxItem.getId());
}
}
@@ -706,7 +703,7 @@ export class Toolbox
this.width_ = toolboxDiv.offsetWidth;
this.height_ = workspaceMetrics.viewHeight;
}
this.flyout!.position();
this.flyout?.position();
}
/**
@@ -715,10 +712,11 @@ export class Toolbox
* @internal
*/
handleToolboxItemResize() {
if (!this.HtmlDiv) return;
// Reposition the workspace so that (0,0) is in the correct position
// relative to the new absolute edge (ie toolbox edge).
const workspace = this.workspace_;
const rect = this.HtmlDiv!.getBoundingClientRect();
const rect = this.HtmlDiv.getBoundingClientRect();
const flyout = this.getFlyout();
const newX =
this.toolboxPosition === toolbox.Position.LEFT
@@ -770,7 +768,7 @@ export class Toolbox
this.selectedItem_.isSelectable() &&
this.selectedItem_.getContents().length
) {
this.flyout!.show(this.selectedItem_.getContents());
this.flyout?.show(this.selectedItem_.getContents());
}
}
@@ -784,7 +782,9 @@ export class Toolbox
return;
}
this.HtmlDiv!.style.display = isVisible ? 'block' : 'none';
if (this.HtmlDiv) {
this.HtmlDiv.style.display = isVisible ? 'block' : 'none';
}
this.isVisible_ = isVisible;
// Invisible toolbox is ignored as drag targets and must have the drag
// target updated.
@@ -928,10 +928,10 @@ export class Toolbox
(oldItem === newItem && !newItem.isCollapsible()) ||
!newItem.getContents().length
) {
this.flyout!.hide();
this.flyout?.hide();
} else {
this.flyout!.show(newItem.getContents());
this.flyout!.scrollToStart();
this.flyout?.show(newItem.getContents());
this.flyout?.scrollToStart();
}
}
@@ -968,8 +968,8 @@ export class Toolbox
private toggleSelectedItem(expanded: boolean): boolean {
if (
isCollapsibleToolboxItem(this.selectedItem_) &&
this.selectedItem_.isCollapsible() &&
this.selectedItem_.isExpanded() !== expanded
this.selectedItem_?.isCollapsible() &&
this.selectedItem_?.isExpanded() !== expanded
) {
this.selectedItem_.toggleExpanded();
return true;
@@ -981,7 +981,7 @@ export class Toolbox
/** Disposes of this toolbox. */
dispose() {
this.workspace_.getComponentManager().removeComponent('toolbox');
this.flyout!.dispose();
this.flyout?.dispose();
this.contents.forEach((item) => item.dispose());
for (let j = 0; j < this.boundEvents_.length; j++) {
+1 -3
View File
@@ -373,10 +373,8 @@ export class ZoomControls implements IPositionable {
* @param e A mouse down event.
*/
private zoom(amount: number, e: PointerEvent) {
this.workspace.beginCanvasTransition();
this.workspace.markFocused();
this.workspace.zoomCenter(amount);
setTimeout(this.workspace.endCanvasTransition.bind(this.workspace), 150);
this.fireZoomEvent();
Touch.clearTouchIdentifier(); // Don't block future drags.
e.stopPropagation(); // Don't start a workspace scroll.
@@ -461,7 +459,7 @@ export class ZoomControls implements IPositionable {
this.workspace.zoomCenter(amount);
this.workspace.scrollCenter();
setTimeout(this.workspace.endCanvasTransition.bind(this.workspace), 150);
setTimeout(this.workspace.endCanvasTransition.bind(this.workspace), 500);
this.fireZoomEvent();
Touch.clearTouchIdentifier(); // Don't block future drags.
e.stopPropagation(); // Don't start a workspace scroll.
+3 -22
View File
@@ -33,18 +33,9 @@ import {
tsc,
} from './scripts/gulpfiles/build_tasks.mjs';
import {docs} from './scripts/gulpfiles/docs_tasks.mjs';
import {
createRC,
syncDevelop,
syncMaster,
updateGithubPages,
} from './scripts/gulpfiles/git_tasks.mjs';
import {updateGithubPages} from './scripts/gulpfiles/git_tasks.mjs';
import {cleanReleaseDir, pack} from './scripts/gulpfiles/package_tasks.mjs';
import {
publish,
publishBeta,
recompile,
} from './scripts/gulpfiles/release_tasks.mjs';
import {publish, publishBeta} from './scripts/gulpfiles/release_tasks.mjs';
import {
generators,
interactiveMocha,
@@ -72,7 +63,7 @@ export {
prepareDemos,
deployDemosBeta,
deployDemos,
updateGithubPages as gitUpdateGithubPages,
updateGithubPages,
}
// Manually-invokable targets that also invoke prerequisites where
@@ -86,15 +77,5 @@ export {
generators as testGenerators,
interactiveMocha,
buildAdvancedCompilationTest,
createRC as gitCreateRC,
docs,
}
// Legacy targets, to be deleted.
//
// prettier-ignore
export {
recompile,
syncDevelop as gitSyncDevelop,
syncMaster as gitSyncMaster,
}
+8 -10
View File
@@ -1,16 +1,16 @@
{
"name": "blockly",
"version": "12.4.1",
"version": "12.5.1",
"description": "Blockly is a library for building visual programming editors.",
"keywords": [
"blockly"
],
"repository": {
"type": "git",
"url": "git+https://github.com/google/blockly.git"
"url": "git+https://github.com/RaspberryPiFoundation/blockly.git"
},
"bugs": {
"url": "https://github.com/google/blockly/issues"
"url": "https://github.com/RaspberryPiFoundation/blockly/issues"
},
"homepage": "https://developers.google.com/blockly/",
"author": {
@@ -41,8 +41,6 @@
"prepareDemos": "gulp prepareDemos",
"publish": "npm ci && gulp publish",
"publish:beta": "npm ci && gulp publishBeta",
"recompile": "gulp recompile",
"release": "gulp gitCreateRC",
"start": "npm run build && concurrently -n tsc,server \"tsc --watch --preserveWatchOutput --outDir \"build/src\" --declarationDir \"build/declarations\"\" \"http-server ./ -s -o /tests/playground.html -c-1\"",
"tsc": "gulp tsc",
"test": "gulp test",
@@ -50,7 +48,8 @@
"test:generators": "gulp testGenerators",
"test:mocha:interactive": "npm run build && concurrently -n tsc,server \"tsc --watch --preserveWatchOutput --outDir \"build/src\" --declarationDir \"build/declarations\"\" \"gulp interactiveMocha\"",
"test:compile:advanced": "gulp buildAdvancedCompilationTest --debug",
"updateGithubPages": "npm ci && gulp gitUpdateGithubPages"
"updateGithubPages": "npm ci && gulp updateGithubPages --upstream",
"updateGithubPages:staging": "npm ci && gulp updateGithubPages --use-local"
},
"exports": {
".": {
@@ -114,6 +113,8 @@
"async-done": "^2.0.0",
"chai": "^6.0.1",
"concurrently": "^9.0.1",
"conventional-changelog-conventionalcommits": "^7.0.2",
"conventional-recommended-bump": "^9.0.0",
"eslint": "^9.15.0",
"eslint-config-google": "^0.14.0",
"eslint-config-prettier": "^10.1.1",
@@ -122,16 +123,13 @@
"eslint-plugin-prettier": "^5.2.1",
"glob": "^11.0.1",
"globals": "^16.0.0",
"google-closure-compiler": "^20260315.0.0",
"google-closure-compiler": "^20260330.0.0",
"gulp": "^5.0.0",
"gulp-concat": "^2.6.1",
"gulp-gzip": "^1.4.2",
"gulp-header": "^2.0.9",
"gulp-insert": "^0.5.0",
"gulp-rename": "^2.0.0",
"gulp-replace": "^1.0.0",
"gulp-series": "^1.0.2",
"gulp-shell": "^0.8.0",
"gulp-sourcemaps": "^3.0.0",
"gulp-umd": "^2.0.0",
"http-server": "^14.0.0",
+112 -111
View File
@@ -8,17 +8,36 @@
* @fileoverview Git-related gulp tasks for Blockly.
*/
import * as gulp from 'gulp';
import {execSync} from 'child_process';
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import * as buildTasks from './build_tasks.mjs';
import * as packageTasks from './package_tasks.mjs';
const UPSTREAM_URL = 'https://github.com/google/blockly.git';
const UPSTREAM_URL = 'git@github.com:RaspberryPiFoundation/blockly.git';
// Use yargs to parse --remote argument
const argv = yargs(hideBin(process.argv)).option('remote', {
type: 'string',
describe: 'Remote to push gh-pages to',
demandOption: false
}).option('upstream', {
type: 'boolean',
describe: 'Push to RaspberryPiFoundation/blockly instead of origin',
demandOption: false
}).option('use-local', {
type: 'boolean',
describe: 'Build and push from current branch instead of syncing with main',
demandOption: false
}).help().argv;
const remoteToUse = argv.upstream ? UPSTREAM_URL : resolveRemote(argv.remote);
/**
* Extra paths to include in the gh_pages branch (beyond the normal
* contents of master / develop). Passed to shell unquoted, so can
* contents of main). Passed to shell unquoted, so can
* include globs.
*/
const EXTRAS = [
@@ -28,140 +47,122 @@ const EXTRAS = [
'build/*.loader.mjs',
];
let upstream = null;
/**
* Get name of git remote for upstream (typically 'upstream', but this
* is just convention and can be changed.)
*/
function getUpstream() {
if (upstream) return upstream;
for (const line of String(execSync('git remote -v')).split('\n')) {
if (line.includes('google/blockly')) {
upstream = line.split('\t')[0];
return upstream;
}
}
throw new Error('Unable to determine upstream URL');
}
/**
* Stash current state, check out the named branch, and sync with
* google/blockly.
* Stash current state, check out the named branch, and pull
* changes from RaspberryPiFoundation/blockly.
*/
function syncBranch(branchName) {
return function(done) {
execSync('git stash save -m "Stash for sync"', { stdio: 'inherit' });
checkoutBranch(branchName);
execSync(`git pull ${UPSTREAM_URL} ${branchName}`, { stdio: 'inherit' });
execSync(`git push origin ${branchName}`, { stdio: 'inherit' });
done();
};
}
/**
* Stash current state, check out develop, and sync with
* google/blockly.
* Stash current state, check out main, and sync with
* RaspberryPiFoundation/blockly.
*/
export function syncDevelop() {
return syncBranch('develop');
export function syncMain() {
return syncBranch('main');
};
/**
* Stash current state, check out master, and sync with
* google/blockly.
*/
export function syncMaster() {
return syncBranch('master');
};
/**
* Helper function: get a name for a rebuild branch. Format:
* rebuild_mm_dd_yyyy.
*/
function getRebuildBranchName() {
const date = new Date();
const mm = date.getMonth() + 1; // Month, 0-11
const dd = date.getDate(); // Day of the month, 1-31
const yyyy = date.getFullYear();
return `rebuild_${mm}_${dd}_${yyyy}`;
};
/**
* Helper function: get a name for a rebuild branch. Format:
* rebuild_yyyy_mm.
*/
function getRCBranchName() {
const date = new Date();
const mm = date.getMonth() + 1; // Month, 0-11
const yyyy = date.getFullYear();
return `rc_${yyyy}_${mm}`;
};
/**
* If branch does not exist then create the branch.
* If branch exists switch to branch.
* If branch does not exist then create the branch.
*/
function checkoutBranch(branchName) {
execSync(`git switch -c ${branchName}`,
execSync(`git switch ${branchName} || git switch -c ${branchName}`,
{ stdio: 'inherit' });
}
/**
* Create and push an RC branch.
* Note that this pushes to google/blockly.
*/
export const createRC = gulp.series(
syncDevelop(),
function(done) {
const branchName = getRCBranchName();
execSync(`git switch -C ${branchName}`, { stdio: 'inherit' });
execSync(`git push ${UPSTREAM_URL} ${branchName}`, { stdio: 'inherit' });
done();
}
);
/** Create the rebuild branch. */
export function createRebuildBranch(done) {
const branchName = getRebuildBranchName();
console.log(`make-rebuild-branch: creating branch ${branchName}`);
execSync(`git switch -C ${branchName}`, { stdio: 'inherit' });
done();
}
/** Push the rebuild branch to origin. */
export function pushRebuildBranch(done) {
console.log('push-rebuild-branch: committing rebuild');
execSync('git commit -am "Rebuild"', { stdio: 'inherit' });
const branchName = getRebuildBranchName();
execSync(`git push origin ${branchName}`, { stdio: 'inherit' });
console.log(`Branch ${branchName} pushed to GitHub.`);
console.log('Next step: create a pull request against develop.');
done();
}
/**
* Update github pages with what is currently in develop.
* Update github pages with what is currently in main (or current branch if --use-local).
*
* Prerequisites (invoked): clean, build.
*
* Usage:
* gulp updateGithubPages # sync main, then use origin if exists
* gulp updateGithubPages --upstream # uses hardcoded upstream
* gulp updateGithubPages --remote <remote> # uses named remote
* gulp updateGithubPages --use-local # build from current branch, skip syncing main
*
*/
export const updateGithubPages = gulp.series(
function(done) {
execSync('git stash save -m "Stash for sync"', { stdio: 'inherit' });
execSync('git switch -C gh-pages', { stdio: 'inherit' });
execSync(`git fetch ${getUpstream()}`, { stdio: 'inherit' });
execSync(`git reset --hard ${getUpstream()}/develop`, { stdio: 'inherit' });
done();
},
buildTasks.cleanBuildDir,
packageTasks.cleanReleaseDir,
buildTasks.build,
function(done) {
// Extra paths (e.g. build/, dist/ etc.) are normally gitignored,
// so we have to force add.
execSync(`git add -f ${EXTRAS.join(' ')}`, {stdio: 'inherit'});
execSync('git commit -am "Rebuild"', {stdio: 'inherit'});
execSync(`git push ${UPSTREAM_URL} gh-pages --force`, {stdio: 'inherit'});
done();
function (done) {
if (!remoteToUse) {
const attemptedRemote = argv.remote || 'origin';
const remoteLabel = argv.remote
? `Remote '${attemptedRemote}'`
: "Remote 'origin' (default)";
const errMsg = `${remoteLabel} not found in git remotes. ` +
'Please add that remote or use --upstream.\n' +
'Usage: gulp updateGithubPages [--remote <remote> | --upstream]';
console.error(errMsg);
done(new Error(errMsg));
return;
}
done();
},
function (done) {
if (!argv.useLocal) {
done();
return;
}
const status = execSync('git status --porcelain', { encoding: 'utf8' });
if (status.trim()) {
const errMsg =
'You cannot push the local branch with uncommitted changes. ' +
'Please commit or stash your changes first.';
console.error(errMsg);
done(new Error(errMsg));
return;
}
done();
},
function (done) {
if (argv.useLocal) {
done();
return;
}
syncMain()(done);
},
function(done) {
const sourceRef = argv.useLocal
? execSync('git rev-parse HEAD', { encoding: 'utf8' }).trim()
: 'main';
execSync('git switch -C gh-pages', { stdio: 'inherit' });
execSync(`git reset --hard ${sourceRef}`, { stdio: 'inherit' });
done();
},
buildTasks.cleanBuildDir,
packageTasks.cleanReleaseDir,
buildTasks.build,
function(done) {
// Extra paths (e.g. build/, dist/ etc.) are normally gitignored,
// so we have to force add.
execSync(`git add -f ${EXTRAS.join(' ')}`, {stdio: 'inherit'});
execSync('git commit -am "Rebuild"', {stdio: 'inherit'});
execSync(`git push ${remoteToUse} gh-pages --force`, {stdio: 'inherit'});
done();
}
);
/**
* Resolves which remote to use for pushing gh-pages.
* @param {string} remoteArg
* @returns {string|undefined} The remote name, or undefined if not found.
*/
function resolveRemote(remoteArg) {
const remoteName = remoteArg || 'origin';
try {
const remotes = execSync('git remote', {encoding: 'utf8'}).split(/\r?\n/).map(r => r.trim()).filter(Boolean);
if (remotes.includes(remoteName)) {
return remoteName;
}
return undefined;
} catch (e) {
return undefined;
}
);
}
@@ -18,55 +18,6 @@ import * as packageTasks from './package_tasks.mjs';
import {getPackageJson} from './helper_tasks.mjs';
import {RELEASE_DIR} from './config.mjs';
// Gets the current major version.
function getMajorVersion() {
const { version } = getPackageJson();
const re = new RegExp(/^(\d)./);
const match = re.exec(version);
if (!match[0]) {
return null;
}
console.log(match[0]);
return parseInt(match[0]);
}
// Updates the version depending on user input.
function updateVersion(done, updateType) {
const majorVersion = getMajorVersion();
if (!majorVersion) {
done(new Error('Something went wrong when getting the major version number.'));
} else if (!updateType) {
// User selected to cancel.
done(new Error('Cancelling process.'));
}
switch (updateType.toLowerCase()) {
case 'major':
majorVersion++;
execSync(`npm --no-git-tag-version version ${majorVersion}.$(date +'%Y%m%d').0`, {stdio: 'inherit'});
done();
break;
case 'minor':
execSync(`npm --no-git-tag-version version ${majorVersion}.$(date +'%Y%m%d').0`, {stdio: 'inherit'});
done();
break;
case 'patch':
execSync(`npm --no-git-tag-version version patch`, {stdio: 'inherit'});
done();
break;
default:
done(new Error('Unexpected update type was chosen.'))
}
}
// Prompt the user to figure out what kind of version update we should do.
function updateVersionPrompt(done) {
const releaseTypes = ['Major', 'Minor', 'Patch'];
const index = readlineSync.keyInSelect(releaseTypes, 'Which version type?');
updateVersion(done, releaseTypes[index]);
}
// Checks with the user that they are on the correct git branch.
function checkBranch(done) {
const gitBranchName = execSync('git rev-parse --abbrev-ref HEAD').toString();
@@ -162,13 +113,3 @@ export const publishBeta = gulp.series(
checkReleaseDir,
loginAndPublishBeta
);
// Switch to a new branch, update the version number, build Blockly
// and check in the resulting built files.
export const recompile = gulp.series(
gitTasks.syncDevelop(),
gitTasks.createRebuildBranch,
updateVersionPrompt,
packageTasks.pack, // Does clean + build.
gitTasks.pushRebuildBranch
);