From eba2d71676e808750946630fe14ba198e09d7d87 Mon Sep 17 00:00:00 2001 From: Jonny Harris Date: Wed, 22 Jan 2025 09:15:20 -0500 Subject: [PATCH 1/6] Add WP_ENV_MULTISITE envoriment variable. (#68792) * Add WP_ENV_MULTISITE envoriment variable. Introduce a new `multisite` option in `wp-env` to enable multisite setups. This can be specified via the `WP_ENV_MULTISITE` environment variable or in the configuration file. Updated documentation to include usage instructions. * Apply suggestions from code review * Apply suggestions from code review * Update packages/env/README.md Co-authored-by: Pascal Birchler * Add `WP_ENV_MULTISITE` environment variable to override multisite This enhancement allows overriding the `multisite` option using the `WP_ENV_MULTISITE` variable. It provides greater flexibility for customizing environment configurations. * Fix type annotation and format multisite environment logic Corrected the JSDoc type annotation for the multisite property from `bool` to `boolean` for consistency. Added a minor formatting adjustment to the multisite environment variable processing logic. --------- Co-authored-by: Pascal Birchler --- packages/env/CHANGELOG.md | 4 ++++ packages/env/README.md | 11 +++++++++++ .../lib/config/get-config-from-environment-vars.js | 5 +++++ 3 files changed, 20 insertions(+) diff --git a/packages/env/CHANGELOG.md b/packages/env/CHANGELOG.md index f972ba1355755..396e0167f1e92 100644 --- a/packages/env/CHANGELOG.md +++ b/packages/env/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Enhancements + +- Add a `WP_ENV_MULTISITE` environment variable to override the `multisite` option ([#68792](https://github.com/WordPress/gutenberg/pull/68792)). + ## 10.16.0 (2025-01-15) ## 10.15.0 (2025-01-02) diff --git a/packages/env/README.md b/packages/env/README.md index 467e8d44e7135..16bba5cba20c0 100644 --- a/packages/env/README.md +++ b/packages/env/README.md @@ -709,6 +709,17 @@ You can tell `wp-env` to use a specific PHP version for compatibility and testin } ``` +### Multisite support + +You can tell `wp-env` if the site should be multisite enabled. This can also be set via the environment variable `WP_ENV_MULTISITE`. + +```json +{ + "multisite": true, + "plugins": [ "." ] +} +``` + ### Node Lifecycle Script This is useful for performing some actions after setting up the environment, such as bootstrapping an E2E test environment. diff --git a/packages/env/lib/config/get-config-from-environment-vars.js b/packages/env/lib/config/get-config-from-environment-vars.js index 618b5fff25792..30c7b3e58eece 100644 --- a/packages/env/lib/config/get-config-from-environment-vars.js +++ b/packages/env/lib/config/get-config-from-environment-vars.js @@ -23,6 +23,7 @@ const { checkPort, checkVersion, checkString } = require( './validate-config' ); * @property {?number} phpmyadminPort An override for the development environment's phpMyAdmin port. * @property {?WPSource} coreSource An override for all environment's coreSource. * @property {?string} phpVersion An override for all environment's PHP version. + * @property {?boolean} multisite An override for if environmen should be multisite. * @property {?Object.} lifecycleScripts An override for various lifecycle scripts. */ @@ -68,6 +69,10 @@ module.exports = function getConfigFromEnvironmentVars( cacheDirectoryPath ) { environmentConfig.phpVersion = process.env.WP_ENV_PHP_VERSION; } + if ( process.env.WP_ENV_MULTISITE ) { + environmentConfig.multisite = !! process.env.WP_ENV_MULTISITE; + } + return environmentConfig; }; From 35e99d41b6182c44f2e074bf29ad8e5b80d25ac5 Mon Sep 17 00:00:00 2001 From: Mitchell Austin Date: Wed, 22 Jan 2025 06:46:07 -0800 Subject: [PATCH 2/6] Clean up unused utils of spacing sizes control (#68794) * Remove `getAllRawValue` and unit tests * Remove `isValuesMixed` and unit tests * Remove `isValuesDefined` and unit tests * Remove `getSupportedMenuItems` and unit tests Co-authored-by: stokesman Co-authored-by: tyxla Co-authored-by: Mamaduka --- .../spacing-sizes-control/test/utils.js | 151 ------------------ .../components/spacing-sizes-control/utils.js | 106 ------------ 2 files changed, 257 deletions(-) diff --git a/packages/block-editor/src/components/spacing-sizes-control/test/utils.js b/packages/block-editor/src/components/spacing-sizes-control/test/utils.js index a8440bb5be8ca..3692a1ea4c445 100644 --- a/packages/block-editor/src/components/spacing-sizes-control/test/utils.js +++ b/packages/block-editor/src/components/spacing-sizes-control/test/utils.js @@ -3,20 +3,15 @@ */ import { ALL_SIDES, - getAllRawValue, getCustomValueFromPreset, getInitialView, getPresetValueFromCustomValue, getSliderValueFromPreset, getSpacingPresetCssVar, getSpacingPresetSlug, - getSupportedMenuItems, hasAxisSupport, hasBalancedSidesSupport, - isValuesDefined, - isValuesMixed, isValueSpacingPreset, - LABELS, VIEWS, } from '../utils'; @@ -114,88 +109,6 @@ describe( 'getSliderValueFromPreset', () => { } ); } ); -describe( 'getAllRawValue', () => { - const customValues = { - top: '5px', - bottom: '5px', - left: '6px', - right: '2px', - }; - it( 'should return the most common custom value from the values object', () => { - expect( getAllRawValue( customValues ) ).toBe( '5px' ); - } ); - const presetValues = { - top: 'var:preset|spacing|30', - bottom: 'var:preset|spacing|20', - left: 'var:preset|spacing|10', - right: 'var:preset|spacing|30', - }; - it( 'should return the most common preset value from the values object', () => { - expect( getAllRawValue( presetValues ) ).toBe( - 'var:preset|spacing|30' - ); - } ); -} ); - -describe( 'isValuesMixed', () => { - const unmixedValues = { - top: '5px', - bottom: '5px', - left: '5px', - right: '5px', - }; - it( 'should return false if all values are the same', () => { - expect( isValuesMixed( unmixedValues ) ).toBe( false ); - } ); - const mixedValues = { - top: 'var:preset|spacing|30', - bottom: 'var:preset|spacing|20', - left: 'var:preset|spacing|10', - right: 'var:preset|spacing|30', - }; - it( 'should return true if all the values are not the same', () => { - expect( isValuesMixed( mixedValues ) ).toBe( true ); - } ); - const singleValue = { - top: 'var:preset|spacing|30', - }; - it( 'should return true if only one side set', () => { - expect( isValuesMixed( singleValue ) ).toBe( true ); - } ); - const incompleteValues = { - top: 'var:preset|spacing|30', - bottom: 'var:preset|spacing|30', - left: 'var:preset|spacing|30', - }; - it( 'should return true if all sides not set', () => { - expect( isValuesMixed( incompleteValues ) ).toBe( true ); - } ); -} ); - -describe( 'isValuesDefined', () => { - const undefinedValues = { - top: undefined, - bottom: undefined, - left: undefined, - right: undefined, - }; - it( 'should return false if values are not defined', () => { - expect( isValuesDefined( undefinedValues ) ).toBe( false ); - } ); - it( 'should return false if values is passed in as null', () => { - expect( isValuesDefined( null ) ).toBe( false ); - } ); - const definedValues = { - top: 'var:preset|spacing|30', - bottom: 'var:preset|spacing|20', - left: 'var:preset|spacing|10', - right: 'var:preset|spacing|30', - }; - it( 'should return true if all the values are not the same', () => { - expect( isValuesDefined( definedValues ) ).toBe( true ); - } ); -} ); - describe( 'hasAxisSupport', () => { it( 'should return true for horizontal support if it is in sides', () => { expect( hasAxisSupport( [ 'horizontal' ], 'horizontal' ) ).toBe( true ); @@ -228,70 +141,6 @@ describe( 'hasAxisSupport', () => { } ); } ); -describe( 'getSupportedMenuItems', () => { - it( 'returns no items when sides are not configured', () => { - expect( getSupportedMenuItems( [] ) ).toEqual( {} ); - expect( getSupportedMenuItems() ).toEqual( {} ); - } ); - - const sideConfigs = [ - [ LABELS.axial, [ 'horizontal', 'vertical' ] ], - [ LABELS.axial, [ 'top', 'right', 'bottom', 'left' ] ], - [ LABELS.horizontal, [ 'horizontal' ] ], - [ LABELS.horizontal, [ 'left', 'right' ] ], - [ LABELS.vertical, [ 'vertical' ] ], - [ LABELS.vertical, [ 'top', 'bottom' ] ], - [ LABELS.horizontal, [ 'horizontal' ] ], - ]; - - test.each( sideConfigs )( - 'should include %s axial menu with %s sides', - ( label, sides ) => { - expect( getSupportedMenuItems( sides ) ).toHaveProperty( - 'axial.label', - label - ); - } - ); - - it( 'returns no axial item when not not supported', () => { - expect( getSupportedMenuItems( [ 'left', 'top' ] ) ).not.toHaveProperty( - 'axial' - ); - } ); - - it( 'should include the correct individual side options', () => { - expect( getSupportedMenuItems( [ 'top' ] ) ).toHaveProperty( - 'top.label', - LABELS.top - ); - expect( getSupportedMenuItems( [ 'right' ] ) ).toHaveProperty( - 'right.label', - LABELS.right - ); - expect( getSupportedMenuItems( [ 'bottom' ] ) ).toHaveProperty( - 'bottom.label', - LABELS.bottom - ); - expect( getSupportedMenuItems( [ 'left' ] ) ).toHaveProperty( - 'left.label', - LABELS.left - ); - } ); - it( 'should include the custom option only when applicable', () => { - expect( getSupportedMenuItems( [ 'top', 'left' ] ) ).toHaveProperty( - 'custom.label', - LABELS.custom - ); - expect( getSupportedMenuItems( [ 'top' ] ) ).not.toHaveProperty( - 'custom' - ); - expect( - getSupportedMenuItems( [ 'horizontal', 'vertical' ] ) - ).not.toHaveProperty( 'custom.label' ); - } ); -} ); - describe( 'hasBalancedSidesSupport', () => { it( 'should determine balanced sides', () => { expect( hasBalancedSidesSupport( ALL_SIDES ) ).toBe( true ); diff --git a/packages/block-editor/src/components/spacing-sizes-control/utils.js b/packages/block-editor/src/components/spacing-sizes-control/utils.js index 046bee98761bf..9c803c0bef1ab 100644 --- a/packages/block-editor/src/components/spacing-sizes-control/utils.js +++ b/packages/block-editor/src/components/spacing-sizes-control/utils.js @@ -184,64 +184,6 @@ export function getSliderValueFromPreset( presetValue, spacingSizes ) { return sliderValue !== -1 ? sliderValue : NaN; } -/** - * Gets an items with the most occurrence within an array - * https://stackoverflow.com/a/20762713 - * - * @param {Array} arr Array of items to check. - * @return {any} The item with the most occurrences. - */ -function mode( arr ) { - return arr - .sort( - ( a, b ) => - arr.filter( ( v ) => v === a ).length - - arr.filter( ( v ) => v === b ).length - ) - .pop(); -} - -/** - * Gets the 'all' input value from values data. - * - * @param {Object} values Box spacing values - * - * @return {string} The most common value from all sides of box. - */ -export function getAllRawValue( values = {} ) { - return mode( Object.values( values ) ); -} - -/** - * Checks to determine if values are mixed. - * - * @param {Object} values Box values. - * @param {Array} sides Sides that values relate to. - * - * @return {boolean} Whether values are mixed. - */ -export function isValuesMixed( values = {}, sides = ALL_SIDES ) { - return ( - ( Object.values( values ).length >= 1 && - Object.values( values ).length < sides.length ) || - new Set( Object.values( values ) ).size > 1 - ); -} - -/** - * Checks to determine if values are defined. - * - * @param {Object} values Box values. - * - * @return {boolean} Whether values are defined. - */ -export function isValuesDefined( values ) { - if ( values === undefined || values === null ) { - return false; - } - return Object.values( values ).filter( ( value ) => !! value ).length > 0; -} - /** * Determines whether a particular axis has support. If no axis is * specified, this function checks if either axis is supported. @@ -275,54 +217,6 @@ export function hasAxisSupport( sides, axis ) { return hasHorizontalSupport || hasVerticalSupport; } -/** - * Determines which menu options should be included in the SidePicker. - * - * @param {Array} sides Supported sides. - * - * @return {Object} Menu options with each option containing label & icon. - */ -export function getSupportedMenuItems( sides ) { - if ( ! sides || ! sides.length ) { - return {}; - } - - const menuItems = {}; - - // Determine the primary "side" menu options. - const hasHorizontalSupport = hasAxisSupport( sides, 'horizontal' ); - const hasVerticalSupport = hasAxisSupport( sides, 'vertical' ); - - if ( hasHorizontalSupport && hasVerticalSupport ) { - menuItems.axial = { label: LABELS.axial, icon: ICONS.axial }; - } else if ( hasHorizontalSupport ) { - menuItems.axial = { label: LABELS.horizontal, icon: ICONS.horizontal }; - } else if ( hasVerticalSupport ) { - menuItems.axial = { label: LABELS.vertical, icon: ICONS.vertical }; - } - - // Track whether we have any individual sides so we can omit the custom - // option if required. - let numberOfIndividualSides = 0; - - ALL_SIDES.forEach( ( side ) => { - if ( sides.includes( side ) ) { - numberOfIndividualSides += 1; - menuItems[ side ] = { - label: LABELS[ side ], - icon: ICONS[ side ], - }; - } - } ); - - // Add custom item if there are enough sides to warrant a separated view. - if ( numberOfIndividualSides > 1 ) { - menuItems.custom = { label: LABELS.custom, icon: ICONS.custom }; - } - - return menuItems; -} - /** * Checks if the supported sides are balanced for each axis. * - Horizontal - both left and right sides are supported. From abe10cfa869cbec58f82a6421f5ad27e3988dbe1 Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Wed, 22 Jan 2025 16:04:43 +0000 Subject: [PATCH 3/6] Bump plugin version to 20.1.0 --- gutenberg.php | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gutenberg.php b/gutenberg.php index e3f4c81ef808f..12a7c54cb1e4b 100644 --- a/gutenberg.php +++ b/gutenberg.php @@ -5,7 +5,7 @@ * Description: Printing since 1440. This is the development plugin for the block editor, site editor, and other future WordPress core functionality. * Requires at least: 6.6 * Requires PHP: 7.2 - * Version: 20.1.0-rc.1 + * Version: 20.1.0 * Author: Gutenberg Team * Text Domain: gutenberg * diff --git a/package-lock.json b/package-lock.json index 56fc08877bfa0..ea578eb67ca0d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gutenberg", - "version": "20.1.0-rc.1", + "version": "20.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "gutenberg", - "version": "20.1.0-rc.1", + "version": "20.1.0", "hasInstallScript": true, "license": "GPL-2.0-or-later", "workspaces": [ diff --git a/package.json b/package.json index 1dbf7d44df405..7816ecb721572 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gutenberg", - "version": "20.1.0-rc.1", + "version": "20.1.0", "private": true, "description": "A new WordPress editor experience.", "author": "The WordPress Contributors", From d7593aee403b90d63cbb383aef608076cd6fab69 Mon Sep 17 00:00:00 2001 From: Gutenberg Repository Automation Date: Wed, 22 Jan 2025 16:19:12 +0000 Subject: [PATCH 4/6] Update Changelog for 20.1.0 --- changelog.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/changelog.txt b/changelog.txt index fa1e1cdcb6a0c..97dcf757a1ef8 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,7 +1,6 @@ == Changelog == -= 20.1.0-rc.1 = - += 20.1.0 = ## Changelog @@ -205,6 +204,8 @@ The following contributors merged PRs in this release: @afercia @AhmarZaidi @atachibana @benazeer-ben @carolinan @ciampo @dhananjaykuber @ellatrix @geriux @himanipanchal @himanshupathak95 @im3dabasia @Infinite-Null @jeryj @jorgefilipecosta @juanfra @justlevine @karthick-murugan @luisherranz @Mamaduka @manzoorwanijk @mirka @ramonjd @SainathPoojary @shail-mehta @shimotmk @sirreal @stokesman @Sukhendu2002 @szepeviktor @t-hamano @vipul0425 @Vrishabhsk @yogeshbhutkar + + = 20.0.0 = ## Changelog From b771bddb91ad74a7a03ee21b1ef311117efd815c Mon Sep 17 00:00:00 2001 From: Eshaan Dabasiya <76681468+im3dabasia@users.noreply.github.com> Date: Wed, 22 Jan 2025 22:13:11 +0530 Subject: [PATCH 5/6] Box Control: Add Runtime Check & Conditional Types for `presets` and `presetKey` Props (#68385) * feat: Improve developer experience for presets * fix: change Warning error message * fix: Enforce runtime check for presets, and presetKey * doc: Add log for runtime check * doc: Add in unreleased section --- Co-authored-by: im3dabasia Co-authored-by: ciampo --- packages/components/CHANGELOG.md | 4 ++ packages/components/src/box-control/index.tsx | 9 +++++ .../components/src/box-control/test/index.tsx | 11 +++++- packages/components/src/box-control/types.ts | 37 +++++++++++++------ 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index db1778ee625b1..6adec34a18b78 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Internal + +- `BoxControl`: Add runtime check for presets and presetKey ([#68385](https://github.com/WordPress/gutenberg/pull/68385)). + ## 29.2.0 (2025-01-15) ### Internal diff --git a/packages/components/src/box-control/index.tsx b/packages/components/src/box-control/index.tsx index d4d4b03f89303..c5bf28a13de3a 100644 --- a/packages/components/src/box-control/index.tsx +++ b/packages/components/src/box-control/index.tsx @@ -4,6 +4,7 @@ import { useInstanceId } from '@wordpress/compose'; import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; +import warning from '@wordpress/warning'; /** * Internal dependencies @@ -166,6 +167,14 @@ function BoxControl( { } ); const sidesToRender = getAllowedSides( sides ); + if ( ( presets && ! presetKey ) || ( ! presets && presetKey ) ) { + const definedProp = presets ? 'presets' : 'presetKey'; + const missingProp = presets ? 'presetKey' : 'presets'; + warning( + `wp.components.BoxControl: the '${ missingProp }' prop is required when the '${ definedProp }' prop is defined.` + ); + } + return ( = T extends any + ? Omit< T, K > + : never; + const ControlledBoxControl = ( - extraProps: Omit< BoxControlProps, 'onChange' > + extraProps: DistributiveOmit< BoxControlProps, 'onChange' > ) => { const [ state, setState ] = useState< BoxControlValue >(); @@ -33,7 +40,7 @@ const ControlledBoxControl = ( const UncontrolledBoxControl = ( { onChange = () => {}, ...props -}: Omit< BoxControlProps, 'onChange' > & { +}: DistributiveOmit< BoxControlProps, 'onChange' > & { onChange?: BoxControlProps[ 'onChange' ]; } ) => ; diff --git a/packages/components/src/box-control/types.ts b/packages/components/src/box-control/types.ts index 43629e09258a5..8c763f6ccb4d7 100644 --- a/packages/components/src/box-control/types.ts +++ b/packages/components/src/box-control/types.ts @@ -100,17 +100,32 @@ export type BoxControlProps = Pick< UnitControlProps, 'units' > & * @default false */ __next40pxDefaultSize?: boolean; - /** - * Available presets to pick from. - */ - presets?: Preset[]; - /** - * The key of the preset to apply. - * If you provide a list of presets, you must provide a preset key to use. - * The format of preset selected values is going to be `var:preset|${ presetKey }|${ presetSlug }` - */ - presetKey?: string; - }; + } & ( + | { + /** + * Available presets to pick from. + */ + presets?: never; + /** + * The key of the preset to apply. + * If you provide a list of presets, you must provide a preset key to use. + * The format of preset selected values is going to be `var:preset|${ presetKey }|${ presetSlug }` + */ + presetKey?: never; + } + | { + /** + * Available presets to pick from. + */ + presets: Preset[]; + /** + * The key of the preset to apply. + * If you provide a list of presets, you must provide a preset key to use. + * The format of preset selected values is going to be `var:preset|${ presetKey }|${ presetSlug }` + */ + presetKey: string; + } + ); export type BoxControlInputControlProps = UnitControlPassthroughProps & { onChange?: ( nextValues: BoxControlValue ) => void; From 0d35e9f7009cb3e5dc4ff573d7a444e9ec3871f8 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Thu, 23 Jan 2025 09:02:42 +0400 Subject: [PATCH 6/6] Release Workflow: Install Subversion (#68837) Co-authored-by: Mamaduka Co-authored-by: joemcgill Co-authored-by: desrosj --- .github/workflows/upload-release-to-plugin-repo.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/upload-release-to-plugin-repo.yml b/.github/workflows/upload-release-to-plugin-repo.yml index 4d2b0a66a7e7d..8f823a543b826 100644 --- a/.github/workflows/upload-release-to-plugin-repo.yml +++ b/.github/workflows/upload-release-to-plugin-repo.yml @@ -167,6 +167,10 @@ jobs: VERSION: ${{ github.event.release.name }} steps: + - name: Install Subversion + run: | + apt-get update -y && apt-get install -y subversion + - name: Check out Gutenberg trunk from WP.org plugin repo run: | svn checkout "$PLUGIN_REPO_URL/trunk" --username "$SVN_USERNAME" --password "$SVN_PASSWORD" @@ -222,6 +226,10 @@ jobs: VERSION: ${{ github.event.release.name }} steps: + - name: Install Subversion + run: | + apt-get update -y && apt-get install -y subversion + - name: Download and unzip Gutenberg plugin asset into tags folder env: PLUGIN_URL: ${{ github.event.release.assets[0].browser_download_url }}