Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,33 @@ steps:
- label: ':react: Build React App'
key: build-react
command: |
make build REFRESH_L10N=1 REFRESH_JS_BUILD=1 STRICT_L10N=1
# Fail fast if any step (including the backgrounded
# `prep-translations`, surfaced via `wait`) returns non-zero,
# rather than continuing into `make build` with partial inputs.
set -euo pipefail
# `prep-translations` is pure network I/O and no longer depends
# on `node_modules` (uses Node's built-in `fetch`), so it can run
# in parallel with `npm ci`. Vite reads `src/translations/` when
# it emits locale bundles, so we wait for the fetch to complete
# before invoking `make build`.
#
# Background output is redirected to a logfile and replayed
# after `wait` returns so its `--- :section:` markers don't
# interleave with `npm ci`'s and confuse Buildkite log folding.
# The replay happens unconditionally so a failed fetch surfaces
# its log before `set -e` aborts the script.
make prep-translations STRICT_L10N=1 > prep-translations.log 2>&1 &
PREP_PID=$$!
make npm-dependencies
PREP_STATUS=0
wait $$PREP_PID || PREP_STATUS=$$?
echo "--- :earth_americas: prep-translations (ran in parallel with npm ci)"
cat prep-translations.log
rm -f prep-translations.log
if [ "$$PREP_STATUS" -ne 0 ]; then
exit "$$PREP_STATUS"
fi
make build REFRESH_JS_BUILD=1
tar -czf dist.tar.gz dist/
buildkite-agent artifact upload dist.tar.gz
plugins: &plugins
Expand Down Expand Up @@ -54,7 +80,11 @@ steps:
plugins: *plugins

- label: ':android: Test Android Library'
command: make test-android
depends_on: build-react
command: |
buildkite-agent artifact download dist.tar.gz .
tar -xzf dist.tar.gz
make test-android
agents:
queue: android
plugins: *plugins
Expand Down Expand Up @@ -142,7 +172,10 @@ steps:
- 'android/app/build/outputs/connected_android_test_additional_output/**/*'

- label: ':android: Test Android Library Instrumented'
depends_on: build-react
command: |
buildkite-agent artifact download dist.tar.gz .
tar -xzf dist.tar.gz
echo "--- :robot_face: Starting Android emulator"
start-android-emulator \
--system-image "system-images;android-34;google_apis;arm64-v8a" \
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ out
# Nuxt.js build / generate output
.nuxt
dist
dist.tar.gz

# Gatsby files
.cache/
Expand Down
65 changes: 56 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,14 @@ npm-dependencies: ## Install npm dependencies
# Skip unless...
# - node_modules doesn't exist
# - REFRESH_DEPS is set to true or 1
# - npm-dependencies was invoked directly
@if [ ! -d "node_modules" ] || [ "$(REFRESH_DEPS)" = "true" ] || [ "$(REFRESH_DEPS)" = "1" ] || echo "$(MAKECMDGOALS)" | grep -q "^npm-dependencies$$"; then \
# - npm-dependencies was invoked directly (not from a recursive `$(MAKE)`)
#
# `build`'s rebuild branch invokes this as `$(MAKE) _RECURSIVE_INVOKE=1
# npm-dependencies`, which sets MAKECMDGOALS=npm-dependencies in the
# child make. Without the sentinel, that recursive call would treat
# itself as a "direct invocation" and re-run `npm ci` every time `build`
# rebuilds — even when node_modules is already populated.
@if [ ! -d "node_modules" ] || [ "$(REFRESH_DEPS)" = "true" ] || [ "$(REFRESH_DEPS)" = "1" ] || { [ -z "$(_RECURSIVE_INVOKE)" ] && echo "$(MAKECMDGOALS)" | grep -q "^npm-dependencies$$"; }; then \
echo "--- :npm: Installing NPM Dependencies"; \
npm ci; \
else \
Expand All @@ -41,11 +47,26 @@ npm-dependencies: ## Install npm dependencies

.PHONY: prep-translations
prep-translations: ## Fetch and cache locale string files
# Skip unless...
# Skip when `dist/` already exists *and* `src/translations/` is
# populated — translations are baked into the bundle at JS build time,
# so there is nothing for a downstream consumer to refresh until the
# bundle itself is rebuilt. This matters on CI agents that download
# `dist.tar.gz` from an upstream job: without it, every downstream
# `make` target that depends on `build` would re-fetch all ~50 locales
# from translate.wordpress.org.
#
# We also require `src/translations/` to be populated so that a stale
# `dist/` paired with an empty `src/translations/` doesn't silently
# produce a no-translations rebuild when `REFRESH_JS_BUILD=1` or a
# direct `make build` triggers JS rebuilding against empty inputs.
#
# Otherwise, skip unless...
# - src/translations doesn't contain any fetched bundles (only `.gitkeep` is committed)
# - REFRESH_L10N is set to true or 1
# - prep-translations was invoked directly
@if [ -z "$$(find src/translations -maxdepth 1 -name '*.json' -print -quit 2>/dev/null)" ] || [ "$(REFRESH_L10N)" = "true" ] || [ "$(REFRESH_L10N)" = "1" ] || echo "$(MAKECMDGOALS)" | grep -q "^prep-translations$$"; then \
@if [ -d "dist" ] && [ -n "$$(find src/translations -maxdepth 1 -name '*.json' -print -quit 2>/dev/null)" ] && [ "$(REFRESH_L10N)" != "true" ] && [ "$(REFRESH_L10N)" != "1" ] && ! echo "$(MAKECMDGOALS)" | grep -q "^prep-translations$$"; then \
echo "--- :white_check_mark: Skipping translations fetch (dist/ already built, translations baked in). Use REFRESH_L10N=1 to force refresh."; \
elif [ -z "$$(find src/translations -maxdepth 1 -name '*.json' -print -quit 2>/dev/null)" ] || [ "$(REFRESH_L10N)" = "true" ] || [ "$(REFRESH_L10N)" = "1" ] || echo "$(MAKECMDGOALS)" | grep -q "^prep-translations$$"; then \
echo "--- :npm: Preparing Translations"; \
if ! npm run prep-translations -- --force; then \
if [ "$(STRICT_L10N)" = "true" ] || [ "$(STRICT_L10N)" = "1" ]; then \
Expand Down Expand Up @@ -91,16 +112,28 @@ clean: ## Remove build artifacts and translation string files
################################################################################

.PHONY: build
build: npm-dependencies prep-translations ## Build the project for all platforms (iOS, Android, web)
build: prep-translations ## Build the project for all platforms (iOS, Android, web)
# Skip unless...
# - dist doesn't exist
# - REFRESH_JS_BUILD is set to true or 1
# - build was invoked directly
#
# `npm-dependencies` is invoked from inside the rebuild branch rather
# than declared as a Make prereq so that downstream targets which
# depend on `build` (`test-android`, `test-swift-library`, etc.) don't
# trigger an `npm ci` they don't actually need when `dist/` is already
# populated — e.g. on CI agents that just extracted an upstream
# `dist.tar.gz` and only intend to run gradle/xcodebuild/swift.
#
# Targets that legitimately use node_modules (`test-e2e` via
# `e2e-dependencies`, `lint-js`, `test-js`, etc.) declare
# `npm-dependencies` as their own prereq.
@if [ ! -d "dist" ] || [ "$(REFRESH_JS_BUILD)" = "true" ] || [ "$(REFRESH_JS_BUILD)" = "1" ] || echo "$(MAKECMDGOALS)" | grep -q "^build$$"; then \
echo "--- :node: Building Gutenberg"; \
npm run build; \
echo "--- :open_file_folder: Copying Build Products into place"; \
$(MAKE) copy-dist-ios; \
$(MAKE) _RECURSIVE_INVOKE=1 npm-dependencies && \
echo "--- :node: Building Gutenberg" && \
npm run build && \
echo "--- :open_file_folder: Copying Build Products into place" && \
$(MAKE) copy-dist-ios && \
$(MAKE) copy-dist-android; \
else \
echo "--- :white_check_mark: Skipping JS build (dist already exists). Use REFRESH_JS_BUILD=1 to force refresh."; \
Expand Down Expand Up @@ -285,6 +318,13 @@ test-ios-e2e-dev: ## Run iOS E2E tests against the Vite dev server (must be runn

.PHONY: test-android
test-android: build ## Run Android tests
# `build` short-circuits `copy-dist-android` when `dist/` already exists
# (e.g. in CI, after extracting an upstream `dist.tar.gz`), so copy
# explicitly here to guarantee the tests run against the current dist
# rather than whatever was committed at HEAD.
@echo "--- :open_file_folder: Copying build into Android bundle"
@rm -rf ./android/Gutenberg/src/main/assets/
@cp -r ./dist/. ./android/Gutenberg/src/main/assets
@echo "--- :android: Running Android Tests"
./android/gradlew -p ./android :gutenberg:test

Expand Down Expand Up @@ -346,6 +386,13 @@ test-android-e2e-dev: ## Run Android E2E tests against the Vite dev server (must

.PHONY: test-android-library-e2e
test-android-library-e2e: build ## Run instrumented tests for the Gutenberg Android library module
# `build` short-circuits `copy-dist-android` when `dist/` already exists
# (e.g. in CI, after extracting an upstream `dist.tar.gz`), so copy
# explicitly here to guarantee the instrumented tests run against the
# current dist rather than whatever was committed at HEAD.
@echo "--- :open_file_folder: Copying build into Android bundle"
@rm -rf ./android/Gutenberg/src/main/assets/
@cp -r ./dist/. ./android/Gutenberg/src/main/assets
$(ENSURE_ANDROID_DEVICE)
@echo "--- :android: Running Android Library Instrumented Tests"
@mkdir -p android/Gutenberg/build/outputs/buildkite-logs
Expand Down
5 changes: 4 additions & 1 deletion bin/prep-translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
*/
import fs from 'fs';
import path from 'path';
import fetch from 'node-fetch';

/**
* Internal dependencies
*/
import { info, error, debug } from '../src/utils/logger.js';

// Uses Node's built-in `fetch` (Node 20, per .nvmrc) so this script can
// run before `npm ci` has populated `node_modules` — letting CI overlap
// translation fetching with dependency installation on the critical path.

const TRANSLATIONS_DIR = path.join( process.cwd(), 'src/translations' );
const SUPPORTED_LOCALES = [
'ar', // Arabic
Expand Down
98 changes: 0 additions & 98 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,6 @@
"eslint-plugin-react-refresh": "^0.4.26",
"jsdom": "^29.0.2",
"magic-string": "^0.30.21",
"node-fetch": "^3.3.2",
"patch-package": "^8.0.1",
"prettier": "npm:wp-prettier@^3.0.3",
"react-devtools": "^7.0.1",
Expand Down
Loading