diff --git a/.github/workflows/build-plugin-zip.yml b/.github/workflows/build-plugin-zip.yml index 8434f835c2514e..dc8e4074c84054 100644 --- a/.github/workflows/build-plugin-zip.yml +++ b/.github/workflows/build-plugin-zip.yml @@ -179,7 +179,7 @@ jobs: fi build: - name: Build Release Artifact + name: ${{ matrix.IS_WORDPRESS_CORE && 'Build assets for wordpress-develop' || 'Build Release Artifact' }} runs-on: 'ubuntu-24.04' permissions: contents: read @@ -190,6 +190,15 @@ jobs: github.event_name == 'workflow_dispatch' || github.repository == 'WordPress/gutenberg' ) + strategy: + matrix: + IS_GUTENBERG_PLUGIN: [true] + IS_WORDPRESS_CORE: [false] + + include: + - IS_GUTENBERG_PLUGIN: false + IS_WORDPRESS_CORE: true + outputs: job_status: ${{ job.status }} @@ -207,15 +216,21 @@ jobs: node-version-file: '.nvmrc' check-latest: true + - name: Configure build for wordpress-develop + if: ${{ matrix.IS_WORDPRESS_CORE }} + run: jq --tab '.wpPlugin.name = "wp"' package.json > package.json.tmp && mv package.json.tmp package.json + - name: Build Gutenberg plugin ZIP file run: ./bin/build-plugin-zip.sh env: NO_CHECKS: 'true' + IS_GUTENBERG_PLUGIN: ${{ matrix.IS_GUTENBERG_PLUGIN }} + IS_WORDPRESS_CORE: ${{ matrix.IS_WORDPRESS_CORE }} - name: Upload artifact uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: - name: gutenberg-plugin + name: gutenberg-${{ matrix.IS_WORDPRESS_CORE && 'wordpress-develop' || 'plugin' }} path: ./gutenberg.zip - name: Build release notes draft @@ -241,6 +256,59 @@ jobs: name: release-notes path: ./release-notes.txt + # Publishes the built plugin zip file to the GitHub Container registry. + publish-to-container-registry: + name: Publish to GitHub Container Registry + runs-on: 'ubuntu-24.04' + needs: ['bump-version', 'build'] + permissions: + contents: read + packages: write + if: | + always() && + needs.build.outputs.job_status == 'success' && + github.repository == 'WordPress/gutenberg' && + github.event_name == 'push' + + steps: + - name: Download build artifact + uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + with: + name: gutenberg-wordpress-develop + + - name: Unzip zip artifact + run: unzip gutenberg.zip && rm gutenberg.zip + + # Noting the hash helps keep track of the commit the zip was built from. + - name: Add a file for tracking the SHA value used. + run: echo "${{ github.sha }}" > .gutenberg-hash + + - name: Recompress as a .gz file + run: tar -czf ${{ runner.temp }}/gutenberg.tar.gz . && mv ${{ runner.temp }}/gutenberg.tar.gz . + + - name: Login to GitHub Container Registry + uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # OCI Registry As Storage (ORAS) provides a way to push and pull non-image, generic artifacts (.gz files, + # for example) to container registries such as GitHub Container Registry. + - name: Setup ORAS + uses: oras-project/setup-oras@22ce207df3b08e061f537244349aac6ae1d214f6 # v1.2.4 + + # The owner/repository is hard-coded because capital letters are not allowed when publishing to GitHub + # Container Registry. The organization name is WordPress, so ${{ github.repository }} causes an error. + # See https://github.com/orgs/community/discussions/27086 for more info. + - name: Push built plugin .tar.gz file to GitHub Container Registry + run: | + oras push "ghcr.io/wordpress/gutenberg/gutenberg-wp-develop-build:${{ github.sha }}" \ + "gutenberg.tar.gz:application/gzip" \ + --annotation "org.opencontainers.image.description=Gutenberg plugin build for commit ${{ github.sha }}" \ + --annotation "org.opencontainers.image.source=https://github.com/${{ github.repository }}" \ + --annotation "org.opencontainers.image.revision=${{ github.sha }}" + revert-version-bump: name: Revert version bump if build failed needs: [bump-version, build] diff --git a/packages/wp-build/.eslintrc.cjs b/packages/wp-build/.eslintrc.cjs index ae9769b2365c13..535eca2c131a6e 100644 --- a/packages/wp-build/.eslintrc.cjs +++ b/packages/wp-build/.eslintrc.cjs @@ -4,5 +4,11 @@ module.exports = { rules: { // Console should be allowed in a build tool 'no-console': 'off', + /* + * These rules are designed for source files processed by esbuild, not for the build script itself, + * which runs directly in Node.js. + */ + '@wordpress/no-wp-process-env': 'off', + '@wordpress/wp-global-usage': 'off', }, }; diff --git a/packages/wp-build/CHANGELOG.md b/packages/wp-build/CHANGELOG.md index 19c3d4c3cfa323..8a8f3f6eb44b8f 100644 --- a/packages/wp-build/CHANGELOG.md +++ b/packages/wp-build/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +### Enhancements + +- Avoid unexpected results when typecasting `IS_GUTENBERG_PLUGIN` and `IS_WORDPRESS_CORE` values to Booleans ([#75844](https://github.com/WordPress/gutenberg/pull/75844)). +- Skip PHP transforms during builds when building for WordPress Core ([#75844](https://github.com/WordPress/gutenberg/pull/75844)). + ## 0.9.0 (2026-03-04) ## 0.8.0 (2026-02-18) diff --git a/packages/wp-build/lib/build.mjs b/packages/wp-build/lib/build.mjs index 17b3f230db2eed..c5ad3cbea9038b 100755 --- a/packages/wp-build/lib/build.mjs +++ b/packages/wp-build/lib/build.mjs @@ -113,12 +113,27 @@ const HANDLE_PREFIX = WP_PLUGIN_CONFIG.handlePrefix || PACKAGE_NAMESPACE; const EXTERNAL_NAMESPACES = WP_PLUGIN_CONFIG.externalNamespaces || {}; const PAGES = WP_PLUGIN_CONFIG.pages || []; +/** + * Interprets a configuration value as a boolean, where `"true"` and `"1"` + * are considered true while all other values are false. + * + * @param {string|undefined} value The configuration value to interpret. + * @return {boolean} Boolean interpretation of the given configuration value. + */ +const boolConfigVal = ( value ) => { + return ( + value !== undefined && [ 'true', '1' ].includes( value.toLowerCase() ) + ); +}; + const baseDefine = { 'globalThis.IS_GUTENBERG_PLUGIN': JSON.stringify( - Boolean( process.env.npm_package_config_IS_GUTENBERG_PLUGIN ) + boolConfigVal( process.env.IS_GUTENBERG_PLUGIN ) || + boolConfigVal( process.env.npm_package_config_IS_GUTENBERG_PLUGIN ) ), 'globalThis.IS_WORDPRESS_CORE': JSON.stringify( - Boolean( process.env.npm_package_config_IS_WORDPRESS_CORE ) + boolConfigVal( process.env.IS_WORDPRESS_CORE ) || + boolConfigVal( process.env.npm_package_config_IS_WORDPRESS_CORE ) ), }; const getDefine = ( scriptDebug ) => ( { @@ -315,6 +330,16 @@ function transformPhpContent( content, transforms ) { content = content.toString(); + /* + * Transforms are used to modify PHP files that are committed to version + * control in their wordpress-develop state (`wp_` function prefixes, `WP_` + * class prefixes, etc.). When building for WordPress Core, it's not + * necessary to perform these steps. + */ + if ( boolConfigVal( process.env.IS_WORDPRESS_CORE ) ) { + return content; + } + if ( prefixFunctions.length ) { content = content.replace( new RegExp( prefixFunctions.join( '|' ), 'g' ), @@ -2142,7 +2167,9 @@ async function main() { }, 'base-url': { type: 'string', - default: 'plugin_dir_url( __FILE__ )', + default: boolConfigVal( process.env.IS_WORDPRESS_CORE ) + ? "includes_url( 'build/' )" + : 'plugin_dir_url( __FILE__ )', }, }, strict: false,