From b1351c4ccd7adc4c0a57c2a85b213fd021b32218 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Thu, 22 Jan 2026 10:43:35 -0300 Subject: [PATCH 01/42] refactor: move to github actions --- .circleci/config.yml | 30 ----- .github/workflows/release.yml | 42 ++++++ .../reusable-build-distributable.yml | 44 ++++++ .github/workflows/reusable-build.yml | 24 ++++ .../workflows/reusable-check-typescript.yml | 27 ++++ .github/workflows/reusable-generate-docs.yml | 39 ++++++ .github/workflows/reusable-i18n.yml | 127 ++++++++++++++++++ .github/workflows/reusable-lint-js-scss.yml | 28 ++++ .github/workflows/reusable-lint-php.yml | 30 +++++ .github/workflows/reusable-post-release.yml | 35 +++++ .github/workflows/reusable-release.yml | 48 +++++++ .github/workflows/reusable-test-js.yml | 27 ++++ .github/workflows/reusable-test-php.yml | 74 ++++++++++ src/@orb.yml | 8 -- src/commands/checkout_with_workspace.yml | 6 - src/commands/set_node_version.yml | 20 --- src/executors/default.yml | 8 -- src/executors/php-81.yml | 8 -- src/jobs/build-distributable.yml | 25 ---- src/jobs/build.yml | 28 ---- src/jobs/check-typescript.yml | 11 -- src/jobs/generate-docs.yml | 30 ----- src/jobs/i18n.yml | 91 ------------- src/jobs/lint-js-scss.yml | 11 -- src/jobs/lint-php.yml | 12 -- src/jobs/post-release.yml | 10 -- src/jobs/release.yml | 21 --- src/jobs/test-js.yml | 11 -- src/jobs/test-php.yml | 49 ------- 29 files changed, 545 insertions(+), 379 deletions(-) delete mode 100644 .circleci/config.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/reusable-build-distributable.yml create mode 100644 .github/workflows/reusable-build.yml create mode 100644 .github/workflows/reusable-check-typescript.yml create mode 100644 .github/workflows/reusable-generate-docs.yml create mode 100644 .github/workflows/reusable-i18n.yml create mode 100644 .github/workflows/reusable-lint-js-scss.yml create mode 100644 .github/workflows/reusable-lint-php.yml create mode 100644 .github/workflows/reusable-post-release.yml create mode 100644 .github/workflows/reusable-release.yml create mode 100644 .github/workflows/reusable-test-js.yml create mode 100644 .github/workflows/reusable-test-php.yml delete mode 100755 src/@orb.yml delete mode 100755 src/commands/checkout_with_workspace.yml delete mode 100755 src/commands/set_node_version.yml delete mode 100755 src/executors/default.yml delete mode 100755 src/executors/php-81.yml delete mode 100644 src/jobs/build-distributable.yml delete mode 100755 src/jobs/build.yml delete mode 100644 src/jobs/check-typescript.yml delete mode 100644 src/jobs/generate-docs.yml delete mode 100644 src/jobs/i18n.yml delete mode 100644 src/jobs/lint-js-scss.yml delete mode 100644 src/jobs/lint-php.yml delete mode 100644 src/jobs/post-release.yml delete mode 100644 src/jobs/release.yml delete mode 100644 src/jobs/test-js.yml delete mode 100644 src/jobs/test-php.yml diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 18648e3..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,30 +0,0 @@ -version: 2 -jobs: - build: - docker: - - image: "circleci/node:latest" - steps: - - checkout - - run: - name: Install nvm and use the node version defined in .nvmrc - command: | - # https://support.circleci.com/hc/en-us/articles/360051656632-Swap-node-version-on-CircleCI-convenience-image - set +e - wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash - export NVM_DIR="$HOME/.nvm" - [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" - [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" - nvm install - nvm use - # https://stackoverflow.com/a/61823737/3772847 - NODE_DIR=$(dirname $(which node)) - echo "export PATH=$NODE_DIR:\$PATH" >> $BASH_ENV - - run: - name: Check node version (should match the version set in project's .nvmrc file) - command: node --version - - run: - name: install - command: npm install --legacy-peer-deps - - run: - name: release - command: npm run semantic-release || true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..82063d1 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,42 @@ +name: Release + +on: + push: + branches: + - trunk + - alpha + - 'hotfix/**' + - 'epic/**' + +jobs: + release: + name: Build and Release + runs-on: ubuntu-latest + permissions: + contents: write + issues: write + pull-requests: write + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Verify Node version + run: node --version + + - name: Install dependencies + run: npm install --legacy-peer-deps + + - name: Release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + run: npm run semantic-release diff --git a/.github/workflows/reusable-build-distributable.yml b/.github/workflows/reusable-build-distributable.yml new file mode 100644 index 0000000..06308e3 --- /dev/null +++ b/.github/workflows/reusable-build-distributable.yml @@ -0,0 +1,44 @@ +name: Build Distributable + +on: + workflow_call: + inputs: + archive-name: + description: 'Name of the ZIP archive distributable' + required: true + type: string + +jobs: + build-distributable: + name: Build distributable files + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Verify Node version + run: node --version + + - name: Install dependencies + run: npm ci --legacy-peer-deps + + - name: Install rsync + run: sudo apt-get update && sudo apt-get install -y rsync + + - name: Install PHP packages + run: composer install --no-dev --no-scripts + + - name: Build plugin files + run: npm run build && npm run release:archive + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ inputs.archive-name }} + path: release/${{ inputs.archive-name }}.zip diff --git a/.github/workflows/reusable-build.yml b/.github/workflows/reusable-build.yml new file mode 100644 index 0000000..97267a2 --- /dev/null +++ b/.github/workflows/reusable-build.yml @@ -0,0 +1,24 @@ +name: Build + +on: + workflow_call: + +jobs: + build: + name: Install node dependencies + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Verify Node version + run: node --version + + - name: Install dependencies + run: npm ci --legacy-peer-deps diff --git a/.github/workflows/reusable-check-typescript.yml b/.github/workflows/reusable-check-typescript.yml new file mode 100644 index 0000000..b754310 --- /dev/null +++ b/.github/workflows/reusable-check-typescript.yml @@ -0,0 +1,27 @@ +name: Check TypeScript + +on: + workflow_call: + +jobs: + check-typescript: + name: Validate TypeScript + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Verify Node version + run: node --version + + - name: Install dependencies + run: npm ci --legacy-peer-deps + + - name: Validate TypeScript + run: npm run typescript:check diff --git a/.github/workflows/reusable-generate-docs.yml b/.github/workflows/reusable-generate-docs.yml new file mode 100644 index 0000000..9ceb1b6 --- /dev/null +++ b/.github/workflows/reusable-generate-docs.yml @@ -0,0 +1,39 @@ +name: Generate Docs + +on: + workflow_call: + secrets: + GITHUB_TOKEN: + required: true + +jobs: + generate-docs: + name: Generate documentation + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install dependencies + run: sudo apt-get update && sudo apt-get install -y graphviz plantuml + + - name: Download PHPDocumentor + run: | + curl -L -o ./phpdocumentor https://phpdoc.org/phpDocumentor.phar + chmod +x ./phpdocumentor + + - name: Generate documentation + run: ./phpdocumentor run -d . -t ./docs + + - name: Switch to docs branch, commit, and push + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GIT_COMMITTER_NAME: ${{ vars.GIT_COMMITTER_NAME || 'github-actions[bot]' }} + GIT_COMMITTER_EMAIL: ${{ vars.GIT_COMMITTER_EMAIL || 'github-actions[bot]@users.noreply.github.com' }} + run: | + git config user.name "$GIT_COMMITTER_NAME" + git config user.email "$GIT_COMMITTER_EMAIL" + git checkout -b docs + git add -f docs + git commit -m "Update the docs" + git push "https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }}.git" docs --force diff --git a/.github/workflows/reusable-i18n.yml b/.github/workflows/reusable-i18n.yml new file mode 100644 index 0000000..d5b5ab6 --- /dev/null +++ b/.github/workflows/reusable-i18n.yml @@ -0,0 +1,127 @@ +name: i18n + +on: + workflow_call: + secrets: + GITHUB_TOKEN: + required: true + +jobs: + i18n: + name: Create translation files + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Check if commit author is bot + id: check-bot + env: + GIT_COMMITTER_EMAIL: ${{ vars.GIT_COMMITTER_EMAIL || 'github-actions[bot]@users.noreply.github.com' }} + run: | + COMMIT_AUTHOR=$(git log -1 --pretty=format:'%ae') + if [ "$COMMIT_AUTHOR" = "$GIT_COMMITTER_EMAIL" ]; then + echo "Commit was made by bot ($(git rev-parse --short HEAD)), skipping translation update" + echo "skip=true" >> $GITHUB_OUTPUT + else + echo "skip=false" >> $GITHUB_OUTPUT + fi + + - name: Install dependencies + if: steps.check-bot.outputs.skip != 'true' + run: npm ci --legacy-peer-deps + + - name: Install WP CLI + if: steps.check-bot.outputs.skip != 'true' + run: | + curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar + chmod +x wp-cli.phar + sudo mv wp-cli.phar /usr/local/bin/wp + + - name: Build plugin files + if: steps.check-bot.outputs.skip != 'true' + run: npm run build || true + + - name: Create POT translation files + if: steps.check-bot.outputs.skip != 'true' + env: + REPO_NAME: ${{ github.event.repository.name }} + run: | + # Theme is excluded, more in https://github.com/Automattic/newspack-theme/pull/2458 + if [ "$REPO_NAME" = "newspack-theme" ]; then + cd ./newspack-theme + wp i18n make-pot . languages/${REPO_NAME}.pot --exclude='src' --domain=${REPO_NAME} + cd - + else + wp i18n make-pot . languages/${REPO_NAME}.pot --domain=${REPO_NAME} + fi + + - name: Create JSON translation files + if: steps.check-bot.outputs.skip != 'true' + env: + REPO_NAME: ${{ github.event.repository.name }} + run: | + if [ "$REPO_NAME" = "newspack-theme" ]; then + cd ./newspack-theme + fi + + sudo apt-get update && sudo apt-get install -y gettext + + cd languages + + # Create PO files from POT if they don't exist + if [ ! -f "${REPO_NAME}-en_US.po" ]; then + echo "Creating ${REPO_NAME}-en_US.po from POT file" + wp i18n update-po ${REPO_NAME}.pot . + else + echo "${REPO_NAME}-en_US.po file already exists, skipping creation" + fi + + for po in *.po; do + if [ -f "$po" ]; then + echo "Processing file $po …" + # Update translations according to the new POT file + msgmerge $po $REPO_NAME.pot -o $po.out + mv $po.out $po + msgfmt $po -o $(basename $po .po).mo + # no-purge since we need the JS translations for the next run + wp i18n make-json --no-purge $po . + fi + done + + - name: Commit translation files + if: steps.check-bot.outputs.skip != 'true' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO_NAME: ${{ github.event.repository.name }} + GIT_COMMITTER_NAME: ${{ vars.GIT_COMMITTER_NAME || 'github-actions[bot]' }} + GIT_COMMITTER_EMAIL: ${{ vars.GIT_COMMITTER_EMAIL || 'github-actions[bot]@users.noreply.github.com' }} + run: | + if [ "$REPO_NAME" = "newspack-theme" ]; then + cd ./newspack-theme + fi + if [ -d "languages" ]; then + LINES_CHANGED=$(git diff --numstat languages/ | awk '{sum += $1 + $2} END {print sum}') + # If no existing files were changed, check for new files + if [ -z "$LINES_CHANGED" ] || [ "$LINES_CHANGED" -eq 0 ]; then + LINES_CHANGED=$(git ls-files --others --exclude-standard languages/ | xargs wc -l 2>/dev/null | tail -1 | awk '{print $1}') + fi + else + LINES_CHANGED=0 + fi + LINES_CHANGED=${LINES_CHANGED:-0} + echo "Lines changed in languages/: $LINES_CHANGED" + if [ "$LINES_CHANGED" -gt 3 ]; then + git config user.email "$GIT_COMMITTER_EMAIL" + git config user.name "$GIT_COMMITTER_NAME" + git remote set-url origin https://x-access-token:$GITHUB_TOKEN@github.com/${{ github.repository }}.git + git add languages/ + git commit -m "chore: update translation files [skip ci]" + git push origin ${{ github.ref_name }} + fi diff --git a/.github/workflows/reusable-lint-js-scss.yml b/.github/workflows/reusable-lint-js-scss.yml new file mode 100644 index 0000000..95f016d --- /dev/null +++ b/.github/workflows/reusable-lint-js-scss.yml @@ -0,0 +1,28 @@ +name: Lint JS & SCSS + +on: + workflow_call: + +jobs: + lint-js-scss: + name: Lint JS & SCSS files + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Verify Node version + run: node --version + + - name: Install dependencies + run: npm ci --legacy-peer-deps + + - name: Run Linter + # Temporarily skip linting SCSS due to stylelint config updates. Remove :js when ready to re-enable linting of SCSS. + run: npm run lint:js diff --git a/.github/workflows/reusable-lint-php.yml b/.github/workflows/reusable-lint-php.yml new file mode 100644 index 0000000..60135c2 --- /dev/null +++ b/.github/workflows/reusable-lint-php.yml @@ -0,0 +1,30 @@ +name: Lint PHP + +on: + workflow_call: + inputs: + php-version: + description: 'PHP version to use' + required: false + type: string + default: '8.3' + +jobs: + lint-php: + name: Lint PHP files + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ inputs.php-version }} + tools: composer + + - name: Install Composer dependencies + run: composer install + + - name: Lint PHP files + run: ./vendor/bin/phpcs diff --git a/.github/workflows/reusable-post-release.yml b/.github/workflows/reusable-post-release.yml new file mode 100644 index 0000000..1fbcdab --- /dev/null +++ b/.github/workflows/reusable-post-release.yml @@ -0,0 +1,35 @@ +name: Post Release + +on: + workflow_call: + secrets: + GITHUB_TOKEN: + required: true + SLACK_CHANNEL_ID: + required: false + SLACK_AUTH_TOKEN: + required: false + +jobs: + post-release: + name: Perform post-release tasks + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Install dependencies + run: npm ci --legacy-peer-deps + + - name: Perform post-release chores + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} + SLACK_AUTH_TOKEN: ${{ secrets.SLACK_AUTH_TOKEN }} + run: ./node_modules/newspack-scripts/post-release.sh diff --git a/.github/workflows/reusable-release.yml b/.github/workflows/reusable-release.yml new file mode 100644 index 0000000..eb9bacd --- /dev/null +++ b/.github/workflows/reusable-release.yml @@ -0,0 +1,48 @@ +name: Release + +on: + workflow_call: + secrets: + GITHUB_TOKEN: + required: true + NPM_TOKEN: + required: false + +jobs: + release: + name: Release new version + runs-on: ubuntu-latest + permissions: + contents: write + issues: write + pull-requests: write + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Verify Node version + run: node --version + + - name: Install dependencies + run: npm ci --legacy-peer-deps + + - name: Install rsync + run: sudo apt-get update && sudo apt-get install -y rsync + + - name: Install PHP packages + run: composer install --no-dev --no-scripts + + - name: Release new version + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + run: npm run release diff --git a/.github/workflows/reusable-test-js.yml b/.github/workflows/reusable-test-js.yml new file mode 100644 index 0000000..e5dd261 --- /dev/null +++ b/.github/workflows/reusable-test-js.yml @@ -0,0 +1,27 @@ +name: Test JS + +on: + workflow_call: + +jobs: + test-js: + name: Run JS tests + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Verify Node version + run: node --version + + - name: Install dependencies + run: npm ci --legacy-peer-deps + + - name: Run JS Tests + run: npm run test diff --git a/.github/workflows/reusable-test-php.yml b/.github/workflows/reusable-test-php.yml new file mode 100644 index 0000000..b7fa635 --- /dev/null +++ b/.github/workflows/reusable-test-php.yml @@ -0,0 +1,74 @@ +name: Test PHP + +on: + workflow_call: + inputs: + php-version: + description: 'PHP version to use' + required: false + type: string + default: '8.3' + wp-version: + description: 'WordPress version to test against' + required: false + type: string + default: 'latest' + secrets: + CODECOV_TOKEN: + required: false + +jobs: + test-php: + name: Run PHP tests + runs-on: ubuntu-latest + services: + mysql: + image: mysql:5.7 + env: + MYSQL_ALLOW_EMPTY_PASSWORD: yes + MYSQL_DATABASE: wordpress_test + ports: + - 3306:3306 + options: >- + --health-cmd="mysqladmin ping" + --health-interval=10s + --health-timeout=5s + --health-retries=3 + env: + WP_TESTS_DIR: /tmp/wordpress-tests-lib + WP_CORE_DIR: /tmp/wordpress/ + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ inputs.php-version }} + tools: composer + extensions: mysqli + coverage: pcov + + - name: Install system dependencies + run: sudo apt-get update && sudo apt-get install -y subversion + + - name: Install Composer dependencies + run: composer update + + - name: Setup WordPress test environment + run: | + rm -rf $WP_TESTS_DIR $WP_CORE_DIR + bash bin/install-wp-tests.sh wordpress_test root '' 127.0.0.1 ${{ inputs.wp-version }} + + - name: Run tests with coverage + run: XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-clover coverage.xml + + - name: Upload coverage to Codecov + if: ${{ env.CODECOV_TOKEN != '' }} + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: coverage.xml + fail_ci_if_error: false + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/src/@orb.yml b/src/@orb.yml deleted file mode 100755 index 5270831..0000000 --- a/src/@orb.yml +++ /dev/null @@ -1,8 +0,0 @@ -version: 2.1 - -description: > - Newspack shared CI config. - -display: - home_url: "https://newspack.com" - source_url: "https://www.github.com/Automattic/newspack-scripts" diff --git a/src/commands/checkout_with_workspace.yml b/src/commands/checkout_with_workspace.yml deleted file mode 100755 index ad3ec5a..0000000 --- a/src/commands/checkout_with_workspace.yml +++ /dev/null @@ -1,6 +0,0 @@ -description: > - Chechout code and attach workspace. -steps: - - checkout - - attach_workspace: - at: ~/ diff --git a/src/commands/set_node_version.yml b/src/commands/set_node_version.yml deleted file mode 100755 index 258ede4..0000000 --- a/src/commands/set_node_version.yml +++ /dev/null @@ -1,20 +0,0 @@ -description: > - Set node version to the one defined in the .nvmrc file. -steps: - - run: - name: Install nvm and use the node version defined in .nvmrc - command: | - # https://support.circleci.com/hc/en-us/articles/360051656632-Swap-node-version-on-CircleCI-convenience-image - set +e - wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash - export NVM_DIR="$HOME/.nvm" - [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" - [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" - nvm install - nvm use - # https://stackoverflow.com/a/61823737/3772847 - NODE_DIR=$(dirname $(which node)) - echo "export PATH=$NODE_DIR:\$PATH" >> $BASH_ENV - - run: - name: Check node version (should match the version set in project's .nvmrc file) - command: node --version diff --git a/src/executors/default.yml b/src/executors/default.yml deleted file mode 100755 index b9c2e06..0000000 --- a/src/executors/default.yml +++ /dev/null @@ -1,8 +0,0 @@ -description: PHP executor -docker: - - image: "cimg/php:<>" -parameters: - tag: - default: 8.3-node - description: PHP image version - type: string diff --git a/src/executors/php-81.yml b/src/executors/php-81.yml deleted file mode 100755 index c7e0dfc..0000000 --- a/src/executors/php-81.yml +++ /dev/null @@ -1,8 +0,0 @@ -description: PHP executor -docker: - - image: "cimg/php:<>" -parameters: - tag: - default: 8.1-node - description: PHP image version - type: string diff --git a/src/jobs/build-distributable.yml b/src/jobs/build-distributable.yml deleted file mode 100644 index 79ceb98..0000000 --- a/src/jobs/build-distributable.yml +++ /dev/null @@ -1,25 +0,0 @@ -description: > - Build the distributable files, so they are available as CI artifacts. - -executor: default - -parameters: - archive-name: - type: string - default: "" - description: "Name of the ZIP archive distributable." - -steps: - - checkout_with_workspace - - set_node_version - - run: - name: Install rsync - command: sudo apt-get update && sudo apt-get install rsync - - run: - name: Install PHP packages - command: composer install --no-dev --no-scripts - - run: - name: Build plugin files - command: npm run build && npm run release:archive - - store_artifacts: - path: release/<>.zip diff --git a/src/jobs/build.yml b/src/jobs/build.yml deleted file mode 100755 index dce2c58..0000000 --- a/src/jobs/build.yml +++ /dev/null @@ -1,28 +0,0 @@ -description: > - Install node dependencies. - -executor: default - -steps: - - checkout_with_workspace - - set_node_version - - restore_cache: - key: v1-npm-{{ checksum "package.json" }}-{{checksum "package-lock.json" }}-{{ checksum ".nvmrc" }} - # https://medium.com/@mdsky1986/caching-node-dependencies-when-using-npm-ci-89fe3f46404a - - run: - name: Install node dependencies - # --legacy-peer-deps flag should be removed once https://github.com/Automattic/newspack-plugin/issues/1218 is resolved - command: | - if test -d "node_modules"; then - echo "package.json and package-lock.json unchanged. Using cache." - else - npm ci --legacy-peer-deps --loglevel warn --yes - fi - - save_cache: - key: v1-npm-{{ checksum "package.json" }}-{{checksum "package-lock.json" }}-{{ checksum ".nvmrc" }} - paths: - - node_modules - - persist_to_workspace: - root: ~/ - paths: - - project diff --git a/src/jobs/check-typescript.yml b/src/jobs/check-typescript.yml deleted file mode 100644 index 3af092a..0000000 --- a/src/jobs/check-typescript.yml +++ /dev/null @@ -1,11 +0,0 @@ -description: > - Validate TypeScript. - -executor: default - -steps: - - checkout_with_workspace - - set_node_version - - run: - name: Validate TypeScript - command: npm run typescript:check diff --git a/src/jobs/generate-docs.yml b/src/jobs/generate-docs.yml deleted file mode 100644 index 6a878d8..0000000 --- a/src/jobs/generate-docs.yml +++ /dev/null @@ -1,30 +0,0 @@ -description: > - Generate documentation. This will create a new branch called docs and push the HTML documentation to it, as /docs directory. - To make this work with GH pages, visit /settings/pages, set branch to "docs", and folder to "/docs". - -executor: php-81 - -steps: - - checkout - - run: - name: Install dependencies - command: | - sudo apt-get update && sudo apt-get install -y graphviz plantuml - - run: - name: Download PHPDocumentor - command: | - curl -L -o ./phpdocumentor https://phpdoc.org/phpDocumentor.phar - chmod +x ./phpdocumentor - - run: - name: Generate documentation - command: | - ./phpdocumentor run -d . -t ./docs - - run: - name: Switch to docs branch, commit, and push - command: | - git config user.name "${GIT_COMMITTER_NAME}" - git config user.email "${GITHUB_COMMITER_EMAIL}" - git checkout -b docs - git add -f docs - git commit -m "Update the docs" - git push "https://${GITHUB_TOKEN}@github.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}.git" --force diff --git a/src/jobs/i18n.yml b/src/jobs/i18n.yml deleted file mode 100644 index 684bff7..0000000 --- a/src/jobs/i18n.yml +++ /dev/null @@ -1,91 +0,0 @@ -description: > - Create translation files. - -executor: default - -steps: - - checkout_with_workspace - - run: - name: Check if commit author is bot - command: | - COMMIT_AUTHOR=$(git log -1 --pretty=format:'%ae') - if [ "$COMMIT_AUTHOR" = "$GITHUB_COMMITER_EMAIL" ]; then - echo "Commit was made by bot ($(git rev-parse --short HEAD)), skipping translation update" - circleci step halt - fi - - run: - name: Install WP CLI - command: | - curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar - chmod +x wp-cli.phar - sudo mv wp-cli.phar /usr/local/bin/wp - - run: - name: Build plugin files, so dist dir is available - command: | - npm run build || true - - run: - name: Create POT translation files - command: | - # Theme is excluded, more in https://github.com/Automattic/newspack-theme/pull/2458 - if [ "$CIRCLE_PROJECT_REPONAME" = "newspack-theme" ]; then - cd ./newspack-theme - wp i18n make-pot . languages/${CIRCLE_PROJECT_REPONAME}.pot --exclude='src' --domain=${CIRCLE_PROJECT_REPONAME} - cd - - else - wp i18n make-pot . languages/${CIRCLE_PROJECT_REPONAME}.pot --domain=${CIRCLE_PROJECT_REPONAME} - fi - - run: - name: Create JSON translation files - command: | - if [ "$CIRCLE_PROJECT_REPONAME" = "newspack-theme" ]; then - cd ./newspack-theme - fi - - sudo apt-get update && sudo apt-get install -y gettext - - cd languages - - # Create PO files from POT if they don't exist - if [ ! -f "${CIRCLE_PROJECT_REPONAME}-en_US.po" ]; then - echo "Creating ${CIRCLE_PROJECT_REPONAME}-en_US.po from POT file" - wp i18n update-po ${CIRCLE_PROJECT_REPONAME}.pot . - else - echo "${CIRCLE_PROJECT_REPONAME}-en_US.po file already exists, skipping creation" - fi - - for po in *.po; do - if [ -f "$po" ]; then - echo "Processing file $po …" - # Update translations according to the new POT file - msgmerge $po $CIRCLE_PROJECT_REPONAME.pot -o $po.out - mv $po.out $po - msgfmt $po -o $(basename $po .po).mo - # no-purge since we need the JS translations for the next run - wp i18n make-json --no-purge $po . - fi - done - - run: - name: Commit translation files - command: | - if [ "$CIRCLE_PROJECT_REPONAME" = "newspack-theme" ]; then - cd ./newspack-theme - fi - if [ -d "languages" ]; then - LINES_CHANGED=$(git diff --numstat languages/ | awk '{sum += $1 + $2} END {print sum}') - # If no existing files were changed, check for new files - if [ -z "$LINES_CHANGED" ] || [ "$LINES_CHANGED" -eq 0 ]; then - LINES_CHANGED=$(git ls-files --others --exclude-standard languages/ | xargs wc -l 2>/dev/null | tail -1 | awk '{print $1}') - fi - else - LINES_CHANGED=0 - fi - LINES_CHANGED=${LINES_CHANGED:-0} - echo "Lines changed in languages/: $LINES_CHANGED" - if [ "$LINES_CHANGED" -gt 3 ]; then - git config user.email "$GITHUB_COMMITER_EMAIL" - git config user.name "$GIT_COMMITTER_NAME" - git remote set-url origin https://$GITHUB_TOKEN@github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME.git - git add languages/ - git commit -m "chore: update translation files [skip ci]" - git push origin $CIRCLE_BRANCH - fi diff --git a/src/jobs/lint-js-scss.yml b/src/jobs/lint-js-scss.yml deleted file mode 100644 index 86873d2..0000000 --- a/src/jobs/lint-js-scss.yml +++ /dev/null @@ -1,11 +0,0 @@ -description: > - Lint the JS & SCSS (temporarily skipped) files. - -executor: default - -steps: - - checkout_with_workspace - - set_node_version - - run: - name: Run Linter - command: npm run lint:js # Temporarily skip linting SCSS due to stylelint config updates. Remove :js when ready to re-enable linting of SCSS. diff --git a/src/jobs/lint-php.yml b/src/jobs/lint-php.yml deleted file mode 100644 index eae5746..0000000 --- a/src/jobs/lint-php.yml +++ /dev/null @@ -1,12 +0,0 @@ -description: > - Lint PHP files. - -executor: default - -steps: - - checkout - - run: - name: Lint Files - command: | - composer install - ./vendor/bin/phpcs diff --git a/src/jobs/post-release.yml b/src/jobs/post-release.yml deleted file mode 100644 index 418d190..0000000 --- a/src/jobs/post-release.yml +++ /dev/null @@ -1,10 +0,0 @@ -description: > - Perform post-release tasks. - -executor: default - -steps: - - checkout_with_workspace - - run: - name: Perform post-release chores - command: ./node_modules/newspack-scripts/post-release.sh diff --git a/src/jobs/release.yml b/src/jobs/release.yml deleted file mode 100644 index 09f977f..0000000 --- a/src/jobs/release.yml +++ /dev/null @@ -1,21 +0,0 @@ -description: > - Release new version. - -executor: default - -steps: - - checkout_with_workspace - - set_node_version - - run: - name: Install rsync - command: sudo apt-get update && sudo apt-get install rsync - - run: - name: Install PHP packages - command: composer install --no-dev --no-scripts - - run: - name: Release new version - command: npm run release - - persist_to_workspace: - root: ~/ - paths: - - project diff --git a/src/jobs/test-js.yml b/src/jobs/test-js.yml deleted file mode 100644 index 5c5ddae..0000000 --- a/src/jobs/test-js.yml +++ /dev/null @@ -1,11 +0,0 @@ -description: > - Run JS tests. - -executor: default - -steps: - - checkout_with_workspace - - set_node_version - - run: - name: Run JS Tests - command: npm run test diff --git a/src/jobs/test-php.yml b/src/jobs/test-php.yml deleted file mode 100644 index c27feff..0000000 --- a/src/jobs/test-php.yml +++ /dev/null @@ -1,49 +0,0 @@ -description: > - Run PHP tests. - -docker: - - image: cimg/php:8.3 - - image: circleci/mysql:5.6.50 - -environment: - - WP_TESTS_DIR: "/tmp/wordpress-tests-lib" - - WP_CORE_DIR: "/tmp/wordpress/" -steps: - - checkout - - run: - name: Setup Environment Variables - command: | - echo "export PATH=$HOME/.composer/vendor/bin:$PATH" >> $BASH_ENV - source /home/circleci/.bashrc - - run: - name: Install Dependencies - command: | - sudo apt-get update && sudo apt-get install -y subversion default-mysql-client - - run: - name: Run Tests with Coverage - command: | - composer update - rm -rf $WP_TESTS_DIR $WP_CORE_DIR - bash bin/install-wp-tests.sh wordpress_test root '' 127.0.0.1 latest - # https://circleci.com/docs/code-coverage/#php - XDEBUG_MODE=coverage phpdbg -qrr vendor/bin/phpunit --coverage-clover coverage.xml - - run: - name: Upload Test Results to Codecov - command: | - if [[ -n $CODECOV_TOKEN ]]; then - # download Codecov CLI - curl -Os https://cli.codecov.io/latest/linux/codecov - - # integrity check - curl https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --no-default-keyring --keyring trustedkeys.gpg --import # One-time step - curl -Os https://cli.codecov.io/latest/linux/codecov - curl -Os https://cli.codecov.io/latest/linux/codecov.SHA256SUM - curl -Os https://cli.codecov.io/latest/linux/codecov.SHA256SUM.sig - gpgv codecov.SHA256SUM.sig codecov.SHA256SUM - - shasum -a 256 -c codecov.SHA256SUM - sudo chmod +x codecov - ./codecov upload-process -t $CODECOV_TOKEN - else - echo "CODECOV_TOKEN is not set. Skipping upload to Codecov." - fi From 558b5a1e72824036cb573ac8f33e12ec0bc28f7e Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Thu, 22 Jan 2026 14:47:28 -0300 Subject: [PATCH 02/42] fix: let the script create the db --- .github/workflows/reusable-test-php.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/reusable-test-php.yml b/.github/workflows/reusable-test-php.yml index b7fa635..d13be96 100644 --- a/.github/workflows/reusable-test-php.yml +++ b/.github/workflows/reusable-test-php.yml @@ -26,7 +26,6 @@ jobs: image: mysql:5.7 env: MYSQL_ALLOW_EMPTY_PASSWORD: yes - MYSQL_DATABASE: wordpress_test ports: - 3306:3306 options: >- From 656cf67d674b5bf2fa377292abb3aeca928a6474 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Thu, 22 Jan 2026 16:25:56 -0300 Subject: [PATCH 03/42] fix: release workflow --- .github/workflows/reusable-release.yml | 2 -- scripts/release.js | 9 ++++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/reusable-release.yml b/.github/workflows/reusable-release.yml index eb9bacd..f35f8b6 100644 --- a/.github/workflows/reusable-release.yml +++ b/.github/workflows/reusable-release.yml @@ -3,8 +3,6 @@ name: Release on: workflow_call: secrets: - GITHUB_TOKEN: - required: true NPM_TOKEN: required: false diff --git a/scripts/release.js b/scripts/release.js index 40c3974..7c14d36 100644 --- a/scripts/release.js +++ b/scripts/release.js @@ -10,15 +10,18 @@ const { files, ...otherArgs } = require( 'yargs/yargs' )( const filesList = files.split( ',' ); -utils.log( `Releasing ${ process.env.CIRCLE_PROJECT_REPONAME }…` ); +// Get repository name from GitHub Actions environment variable (format: owner/repo). +const repoName = process.env.GITHUB_REPOSITORY?.split( '/' )[ 1 ] || 'unknown'; + +utils.log( `Releasing ${ repoName }…` ); const getConfig = ({ gitBranchName }) => { const branchType = gitBranchName.split("/")[0]; const githubConfig = { assets: [ { - path: `./release/${process.env.CIRCLE_PROJECT_REPONAME}.zip`, - label: `${process.env.CIRCLE_PROJECT_REPONAME}.zip`, + path: `./release/${ repoName }.zip`, + label: `${ repoName }.zip`, }, ], }; From ed7a28c76c672d02b9ee87314be26674c47b729c Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Thu, 22 Jan 2026 16:30:11 -0300 Subject: [PATCH 04/42] fix: post-release workflow --- .github/workflows/reusable-post-release.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/reusable-post-release.yml b/.github/workflows/reusable-post-release.yml index 1fbcdab..611f491 100644 --- a/.github/workflows/reusable-post-release.yml +++ b/.github/workflows/reusable-post-release.yml @@ -3,8 +3,6 @@ name: Post Release on: workflow_call: secrets: - GITHUB_TOKEN: - required: true SLACK_CHANNEL_ID: required: false SLACK_AUTH_TOKEN: From 991821bcb7062dc6aab02a1f2f2b01f0f141db04 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Thu, 22 Jan 2026 16:35:12 -0300 Subject: [PATCH 05/42] fix: i18n workflow --- .github/workflows/reusable-i18n.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/reusable-i18n.yml b/.github/workflows/reusable-i18n.yml index d5b5ab6..2ae2bd9 100644 --- a/.github/workflows/reusable-i18n.yml +++ b/.github/workflows/reusable-i18n.yml @@ -2,9 +2,6 @@ name: i18n on: workflow_call: - secrets: - GITHUB_TOKEN: - required: true jobs: i18n: From 41b03ee7bf40fff14ad13603839dd3e92698fb40 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Fri, 23 Jan 2026 10:34:43 -0300 Subject: [PATCH 06/42] fix: i18n exclude src dir --- .github/workflows/reusable-i18n.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-i18n.yml b/.github/workflows/reusable-i18n.yml index 2ae2bd9..9d8bef4 100644 --- a/.github/workflows/reusable-i18n.yml +++ b/.github/workflows/reusable-i18n.yml @@ -56,7 +56,7 @@ jobs: wp i18n make-pot . languages/${REPO_NAME}.pot --exclude='src' --domain=${REPO_NAME} cd - else - wp i18n make-pot . languages/${REPO_NAME}.pot --domain=${REPO_NAME} + wp i18n make-pot . languages/${REPO_NAME}.pot --exclude='src' --domain=${REPO_NAME} fi - name: Create JSON translation files From 025ea169e53a1f5f6889667229acfdee9f8e8605 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Fri, 23 Jan 2026 10:42:25 -0300 Subject: [PATCH 07/42] fix(i18n): increase php nesting level --- .github/workflows/reusable-i18n.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/reusable-i18n.yml b/.github/workflows/reusable-i18n.yml index 9d8bef4..721fb04 100644 --- a/.github/workflows/reusable-i18n.yml +++ b/.github/workflows/reusable-i18n.yml @@ -45,6 +45,9 @@ jobs: if: steps.check-bot.outputs.skip != 'true' run: npm run build || true + - name: Set higher Xdebug stack limit + run: echo "xdebug.max_nesting_level=1000" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini + - name: Create POT translation files if: steps.check-bot.outputs.skip != 'true' env: From 3a37606d206bc3eab823cd0c815ff6b785c404f1 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Fri, 23 Jan 2026 10:46:51 -0300 Subject: [PATCH 08/42] fix: create xdebug dir --- .github/workflows/reusable-i18n.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/reusable-i18n.yml b/.github/workflows/reusable-i18n.yml index 721fb04..94ad715 100644 --- a/.github/workflows/reusable-i18n.yml +++ b/.github/workflows/reusable-i18n.yml @@ -45,7 +45,10 @@ jobs: if: steps.check-bot.outputs.skip != 'true' run: npm run build || true - - name: Set higher Xdebug stack limit + - name: Create xdebug configuration directory + run: mkdir -p /usr/local/etc/php/conf.d + + - name: Configure xdebug run: echo "xdebug.max_nesting_level=1000" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini - name: Create POT translation files From 172cc5df78d8102e6b5a2231f4c76a0506d6f385 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Fri, 23 Jan 2026 10:54:15 -0300 Subject: [PATCH 09/42] fix: remove custom config --- .github/workflows/reusable-i18n.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/reusable-i18n.yml b/.github/workflows/reusable-i18n.yml index 94ad715..9d8bef4 100644 --- a/.github/workflows/reusable-i18n.yml +++ b/.github/workflows/reusable-i18n.yml @@ -45,12 +45,6 @@ jobs: if: steps.check-bot.outputs.skip != 'true' run: npm run build || true - - name: Create xdebug configuration directory - run: mkdir -p /usr/local/etc/php/conf.d - - - name: Configure xdebug - run: echo "xdebug.max_nesting_level=1000" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini - - name: Create POT translation files if: steps.check-bot.outputs.skip != 'true' env: From 98493219acecca7bd953835438adc7694119a9b8 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Fri, 23 Jan 2026 10:56:58 -0300 Subject: [PATCH 10/42] fix: alternate custom config strategy --- .github/workflows/reusable-i18n.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/reusable-i18n.yml b/.github/workflows/reusable-i18n.yml index 9d8bef4..bc92842 100644 --- a/.github/workflows/reusable-i18n.yml +++ b/.github/workflows/reusable-i18n.yml @@ -34,6 +34,12 @@ jobs: if: steps.check-bot.outputs.skip != 'true' run: npm ci --legacy-peer-deps + - name: Configure PHP for deep nesting + if: steps.check-bot.outputs.skip != 'true' + run: | + # Increase xdebug max_nesting_level to handle deeply nested JS files + echo "xdebug.max_nesting_level=512" | sudo tee -a $(php -i | grep "Scan this dir for additional .ini files" | cut -d' ' -f9)/99-custom.ini + - name: Install WP CLI if: steps.check-bot.outputs.skip != 'true' run: | From 74d2c85795e10b77450ce551cc98b472eb9daaa0 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Fri, 23 Jan 2026 11:18:51 -0300 Subject: [PATCH 11/42] fix: label char limit --- scripts/release.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/release.js b/scripts/release.js index 7c14d36..4dede87 100644 --- a/scripts/release.js +++ b/scripts/release.js @@ -24,6 +24,10 @@ const getConfig = ({ gitBranchName }) => { label: `${ repoName }.zip`, }, ], + // Custom label template that caps at 50 chars (GitHub's limit). + releasedLabels: [ + '<%= ("released" + (nextRelease.channel ? " on @" + nextRelease.channel : "")).substring(0, 50) %>', + ], }; // Only post GH PR comments for alpha, hotfix/*, and release branches. From 37a87cce7b14af4b6b15dfd93b442dfd22afc0b6 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Fri, 23 Jan 2026 12:21:53 -0300 Subject: [PATCH 12/42] fix: release command --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 82063d1..ea1c408 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,4 +39,4 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - run: npm run semantic-release + run: npm run release From bfa681bf617d7bb7b29a01f605ed940fedf2f3fb Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Fri, 23 Jan 2026 12:41:53 -0300 Subject: [PATCH 13/42] fix: post release vars and release asset --- .github/workflows/release.yml | 2 +- post-release.sh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ea1c408..3091d82 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,4 +39,4 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - run: npm run release + run: npm run release:archive && npm run semantic-release diff --git a/post-release.sh b/post-release.sh index 7bac57a..b8a1c19 100755 --- a/post-release.sh +++ b/post-release.sh @@ -23,13 +23,13 @@ if [[ $(echo $SECOND_TO_LAST_COMMIT_MSG | grep '^Merge .*alpha') ]]; then # we don't care about any alpha changes. git reset --hard release -- # Force-push the alpha branch. - git push "https://$GITHUB_TOKEN@github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME.git" --force + git push "https://$GITHUB_TOKEN@github.com/${GITHUB_REPOSITORY}.git" --force else echo '[newspack-scripts] Release was created from a different branch than the alpha branch (e.g. a hotfix branch).' echo '[newspack-scripts] Alpha branch will now be updated with the lastest changes from release.' git merge --no-ff release -m "chore(release): merge in release $LATEST_VERSION_TAG" if [[ $? == 0 ]]; then - git push "https://$GITHUB_TOKEN@github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME.git" + git push "https://$GITHUB_TOKEN@github.com/${GITHUB_REPOSITORY}.git" else git merge --abort echo '[newspack-scripts] Post-release merge to alpha failed.' @@ -55,7 +55,7 @@ git checkout trunk git merge --no-ff release -m "chore(release): merge in release $LATEST_VERSION_TAG" if [[ $? == 0 ]]; then echo '[newspack-scripts] Pushing updated trunk to origin.' - git push "https://$GITHUB_TOKEN@github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME.git" + git push "https://$GITHUB_TOKEN@github.com/${GITHUB_REPOSITORY}.git" else git merge --abort echo '[newspack-scripts] Post-release merge to trunk failed.' From 704b6ee85801396d057ac18e4d8ad7c06dc3b21d Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Fri, 23 Jan 2026 16:09:28 -0300 Subject: [PATCH 14/42] fix: release command --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3091d82..82063d1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,4 +39,4 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - run: npm run release:archive && npm run semantic-release + run: npm run semantic-release From 42fa51aaa5fd7009ea70ef01a724964bb1958fcc Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Fri, 23 Jan 2026 16:30:18 -0300 Subject: [PATCH 15/42] chore: temporarily disable pr comments (prevent spam) --- scripts/release.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/release.js b/scripts/release.js index 4dede87..2f26744 100644 --- a/scripts/release.js +++ b/scripts/release.js @@ -31,10 +31,11 @@ const getConfig = ({ gitBranchName }) => { }; // Only post GH PR comments for alpha, hotfix/*, and release branches. - if ( ! ["alpha", "hotfix", "release"].includes(branchType) ) { - githubConfig.successComment = false; - githubConfig.failComment = false; - } + // if ( ! ["alpha", "hotfix", "release"].includes(branchType) ) { + // Temporarily disable comments for all branches to prevent spam. + githubConfig.successComment = false; + githubConfig.failComment = false; + // } // Only publish alpha and release branches to NPM. const shouldPublishOnNPM = Boolean( process.env.NPM_TOKEN ) && ["alpha", "release"].includes(branchType); From 55eade1ef6f8cae77332fbc937153b193a53ddbf Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Mon, 26 Jan 2026 10:59:09 -0300 Subject: [PATCH 16/42] fix: set repo env var --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 82063d1..e450f92 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -37,6 +37,7 @@ jobs: - name: Release env: + GITHUB_REPOSITORY: ${{ github.repository }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: npm run semantic-release From 43c99ca23dc06477bf6beee71b8940f2360f84d2 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Mon, 26 Jan 2026 11:04:23 -0300 Subject: [PATCH 17/42] fix: disable release labels --- scripts/release.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/scripts/release.js b/scripts/release.js index 2f26744..0c65370 100644 --- a/scripts/release.js +++ b/scripts/release.js @@ -24,10 +24,7 @@ const getConfig = ({ gitBranchName }) => { label: `${ repoName }.zip`, }, ], - // Custom label template that caps at 50 chars (GitHub's limit). - releasedLabels: [ - '<%= ("released" + (nextRelease.channel ? " on @" + nextRelease.channel : "")).substring(0, 50) %>', - ], + releasedLabels: false, }; // Only post GH PR comments for alpha, hotfix/*, and release branches. From a52324c598831b67415628f11245a46919d1037b Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Mon, 26 Jan 2026 11:24:25 -0300 Subject: [PATCH 18/42] fix: github repo env var --- .github/workflows/reusable-release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/reusable-release.yml b/.github/workflows/reusable-release.yml index f35f8b6..721ded8 100644 --- a/.github/workflows/reusable-release.yml +++ b/.github/workflows/reusable-release.yml @@ -41,6 +41,7 @@ jobs: - name: Release new version env: + GITHUB_REPOSITORY: ${{ github.repository }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: npm run release From 1b654fae0446656ac8221ae7400a42bbd80b2140 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Mon, 26 Jan 2026 11:41:57 -0300 Subject: [PATCH 19/42] fix: move repo var to parent repo --- .github/workflows/reusable-release.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/reusable-release.yml b/.github/workflows/reusable-release.yml index 721ded8..fe468d7 100644 --- a/.github/workflows/reusable-release.yml +++ b/.github/workflows/reusable-release.yml @@ -3,6 +3,8 @@ name: Release on: workflow_call: secrets: + GITHUB_REPOSITORY: + required: true NPM_TOKEN: required: false @@ -41,7 +43,7 @@ jobs: - name: Release new version env: - GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_REPOSITORY: ${{ secrets.GITHUB_REPOSITORY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: npm run release From 15be7d52346273a0c0dd0e9de328e1aca1016450 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Tue, 27 Jan 2026 11:11:47 -0300 Subject: [PATCH 20/42] fix: rebase before push --- .github/workflows/reusable-i18n.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/reusable-i18n.yml b/.github/workflows/reusable-i18n.yml index bc92842..924ee1a 100644 --- a/.github/workflows/reusable-i18n.yml +++ b/.github/workflows/reusable-i18n.yml @@ -126,5 +126,6 @@ jobs: git remote set-url origin https://x-access-token:$GITHUB_TOKEN@github.com/${{ github.repository }}.git git add languages/ git commit -m "chore: update translation files [skip ci]" + git pull --rebase origin ${{ github.ref_name }} git push origin ${{ github.ref_name }} fi From 7f5f389782740209d990c527a8fcffa16c9d8d99 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Tue, 27 Jan 2026 11:14:57 -0300 Subject: [PATCH 21/42] fix: install mysql client --- .github/workflows/reusable-test-php.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-test-php.yml b/.github/workflows/reusable-test-php.yml index d13be96..e4419ec 100644 --- a/.github/workflows/reusable-test-php.yml +++ b/.github/workflows/reusable-test-php.yml @@ -49,7 +49,7 @@ jobs: coverage: pcov - name: Install system dependencies - run: sudo apt-get update && sudo apt-get install -y subversion + run: sudo apt-get update && sudo apt-get install -y subversion default-mysql-client - name: Install Composer dependencies run: composer update From ab7fabc11ebb539d86d6876d02cdf4fe4b954767 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Tue, 27 Jan 2026 11:22:51 -0300 Subject: [PATCH 22/42] fix: add php setup --- .github/workflows/reusable-release.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/reusable-release.yml b/.github/workflows/reusable-release.yml index fe468d7..0ad4b20 100644 --- a/.github/workflows/reusable-release.yml +++ b/.github/workflows/reusable-release.yml @@ -29,6 +29,12 @@ jobs: node-version-file: '.nvmrc' cache: 'npm' + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.3' + tools: composer + - name: Verify Node version run: node --version From 8399c70fea978dd34737f492c9eb5af0ff0c1f3f Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Tue, 27 Jan 2026 11:23:27 -0300 Subject: [PATCH 23/42] fix: add php setup --- .github/workflows/reusable-build-distributable.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/reusable-build-distributable.yml b/.github/workflows/reusable-build-distributable.yml index 06308e3..8c8c263 100644 --- a/.github/workflows/reusable-build-distributable.yml +++ b/.github/workflows/reusable-build-distributable.yml @@ -25,6 +25,12 @@ jobs: - name: Verify Node version run: node --version + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.3' + tools: composer + - name: Install dependencies run: npm ci --legacy-peer-deps From 6039e8038d0afa59caaca81cf2e47d5940d70f9b Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Tue, 27 Jan 2026 11:28:06 -0300 Subject: [PATCH 24/42] fix: move secret env --- .github/workflows/reusable-test-php.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/reusable-test-php.yml b/.github/workflows/reusable-test-php.yml index e4419ec..6c0b092 100644 --- a/.github/workflows/reusable-test-php.yml +++ b/.github/workflows/reusable-test-php.yml @@ -34,6 +34,7 @@ jobs: --health-timeout=5s --health-retries=3 env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} WP_TESTS_DIR: /tmp/wordpress-tests-lib WP_CORE_DIR: /tmp/wordpress/ steps: @@ -69,5 +70,3 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} files: coverage.xml fail_ci_if_error: false - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From 9dd364f92af088ba34210b8f966be0a9711765c5 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Tue, 27 Jan 2026 11:33:37 -0300 Subject: [PATCH 25/42] fix: fetch all history --- .github/workflows/reusable-i18n.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/reusable-i18n.yml b/.github/workflows/reusable-i18n.yml index 924ee1a..33038a3 100644 --- a/.github/workflows/reusable-i18n.yml +++ b/.github/workflows/reusable-i18n.yml @@ -10,6 +10,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Setup Node.js uses: actions/setup-node@v4 From 33773588924d65b54d14c1c07a77310782a97dd3 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Tue, 27 Jan 2026 11:36:45 -0300 Subject: [PATCH 26/42] fix: update permissions --- .github/workflows/reusable-post-release.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/reusable-post-release.yml b/.github/workflows/reusable-post-release.yml index 611f491..3c03b14 100644 --- a/.github/workflows/reusable-post-release.yml +++ b/.github/workflows/reusable-post-release.yml @@ -1,5 +1,8 @@ name: Post Release +permissions: + contents: write + on: workflow_call: secrets: From 15442fd495716b7c3aeb1d1188263878d54a49f7 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Tue, 27 Jan 2026 11:37:51 -0300 Subject: [PATCH 27/42] fix: update permissions --- .github/workflows/reusable-i18n.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/reusable-i18n.yml b/.github/workflows/reusable-i18n.yml index 33038a3..a1ee03c 100644 --- a/.github/workflows/reusable-i18n.yml +++ b/.github/workflows/reusable-i18n.yml @@ -3,6 +3,9 @@ name: i18n on: workflow_call: +permissions: + contents: write + jobs: i18n: name: Create translation files From f69ff627a77c84b5e0132b9ac6ff86db0ec31b0a Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Tue, 27 Jan 2026 11:38:58 -0300 Subject: [PATCH 28/42] fix: add GITHUB_REPOSITORY environment variable --- .github/workflows/reusable-post-release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/reusable-post-release.yml b/.github/workflows/reusable-post-release.yml index 3c03b14..30ec343 100644 --- a/.github/workflows/reusable-post-release.yml +++ b/.github/workflows/reusable-post-release.yml @@ -31,6 +31,7 @@ jobs: - name: Perform post-release chores env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_REPOSITORY: ${{ github.repository }} SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} SLACK_AUTH_TOKEN: ${{ secrets.SLACK_AUTH_TOKEN }} run: ./node_modules/newspack-scripts/post-release.sh From 7ee384044b5a4de1902ae111725a0bf414be6d5f Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Tue, 27 Jan 2026 11:43:02 -0300 Subject: [PATCH 29/42] Update .github/workflows/reusable-i18n.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/workflows/reusable-i18n.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-i18n.yml b/.github/workflows/reusable-i18n.yml index a1ee03c..89f5aaa 100644 --- a/.github/workflows/reusable-i18n.yml +++ b/.github/workflows/reusable-i18n.yml @@ -67,7 +67,7 @@ jobs: wp i18n make-pot . languages/${REPO_NAME}.pot --exclude='src' --domain=${REPO_NAME} cd - else - wp i18n make-pot . languages/${REPO_NAME}.pot --exclude='src' --domain=${REPO_NAME} + wp i18n make-pot . languages/${REPO_NAME}.pot --domain=${REPO_NAME} fi - name: Create JSON translation files From 1a22095266c5f26bf7139fc46d1fa24b448de8d3 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Tue, 27 Jan 2026 11:43:39 -0300 Subject: [PATCH 30/42] Update .github/workflows/release.yml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e450f92..9761b8b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,7 +33,7 @@ jobs: run: node --version - name: Install dependencies - run: npm install --legacy-peer-deps + run: npm ci --legacy-peer-deps - name: Release env: From 1947852d2c68aa0ed73841bd063bd1853d59f0be Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Tue, 27 Jan 2026 11:45:47 -0300 Subject: [PATCH 31/42] fix: add GIT_COMMITTER_NAME and GITHUB_COMMITTER_EMAIL to workflow --- .github/workflows/reusable-post-release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/reusable-post-release.yml b/.github/workflows/reusable-post-release.yml index 30ec343..3555960 100644 --- a/.github/workflows/reusable-post-release.yml +++ b/.github/workflows/reusable-post-release.yml @@ -32,6 +32,8 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_REPOSITORY: ${{ github.repository }} + GIT_COMMITTER_NAME: github-actions[bot] + GITHUB_COMMITER_EMAIL: github-actions[bot]@users.noreply.github.com SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} SLACK_AUTH_TOKEN: ${{ secrets.SLACK_AUTH_TOKEN }} run: ./node_modules/newspack-scripts/post-release.sh From 083bc1f06ce575c089282d59e7f01831f8de6df3 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Tue, 27 Jan 2026 11:48:57 -0300 Subject: [PATCH 32/42] refactor: replace GITHUB_REPOSITORY secret with github.repository in reusable-release workflow --- .github/workflows/reusable-release.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/reusable-release.yml b/.github/workflows/reusable-release.yml index 0ad4b20..84b1fa2 100644 --- a/.github/workflows/reusable-release.yml +++ b/.github/workflows/reusable-release.yml @@ -3,8 +3,6 @@ name: Release on: workflow_call: secrets: - GITHUB_REPOSITORY: - required: true NPM_TOKEN: required: false @@ -49,7 +47,7 @@ jobs: - name: Release new version env: - GITHUB_REPOSITORY: ${{ secrets.GITHUB_REPOSITORY }} + GITHUB_REPOSITORY: ${{ github.repository }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: npm run release From 2bde1b7c43af4fd15490095d77f83f275b7895e6 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Tue, 27 Jan 2026 11:50:04 -0300 Subject: [PATCH 33/42] chore: set fetch-depth to 0 in reusable-post-release workflow for complete history --- .github/workflows/reusable-post-release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/reusable-post-release.yml b/.github/workflows/reusable-post-release.yml index 3555960..69b074d 100644 --- a/.github/workflows/reusable-post-release.yml +++ b/.github/workflows/reusable-post-release.yml @@ -18,6 +18,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Setup Node.js uses: actions/setup-node@v4 From b2da51527c5f0f99a3e33c6829e221be7bb2d254 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Tue, 27 Jan 2026 11:51:18 -0300 Subject: [PATCH 34/42] fix: remove XDEBUG_MODE from test command in reusable-test-php workflow --- .github/workflows/reusable-test-php.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-test-php.yml b/.github/workflows/reusable-test-php.yml index 6c0b092..2d7184a 100644 --- a/.github/workflows/reusable-test-php.yml +++ b/.github/workflows/reusable-test-php.yml @@ -61,7 +61,7 @@ jobs: bash bin/install-wp-tests.sh wordpress_test root '' 127.0.0.1 ${{ inputs.wp-version }} - name: Run tests with coverage - run: XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-clover coverage.xml + run: vendor/bin/phpunit --coverage-clover coverage.xml - name: Upload coverage to Codecov if: ${{ env.CODECOV_TOKEN != '' }} From 722c02a51d2aacf5ba11735dbd7fca1ccd5511b3 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Tue, 27 Jan 2026 11:52:40 -0300 Subject: [PATCH 35/42] chore: remove GITHUB_TOKEN requirement from reusable-generate-docs workflow --- .github/workflows/reusable-generate-docs.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/reusable-generate-docs.yml b/.github/workflows/reusable-generate-docs.yml index 9ceb1b6..3f0a6b8 100644 --- a/.github/workflows/reusable-generate-docs.yml +++ b/.github/workflows/reusable-generate-docs.yml @@ -2,9 +2,6 @@ name: Generate Docs on: workflow_call: - secrets: - GITHUB_TOKEN: - required: true jobs: generate-docs: From 46dae4a80cfba76197862dd7f17f677e1ab2314e Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Tue, 27 Jan 2026 11:53:04 -0300 Subject: [PATCH 36/42] chore: add write permissions for contents in reusable-generate-docs workflow --- .github/workflows/reusable-generate-docs.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/reusable-generate-docs.yml b/.github/workflows/reusable-generate-docs.yml index 3f0a6b8..232c08c 100644 --- a/.github/workflows/reusable-generate-docs.yml +++ b/.github/workflows/reusable-generate-docs.yml @@ -1,5 +1,8 @@ name: Generate Docs +permissions: + contents: write + on: workflow_call: From 055fd867cf87ff5a71c0f9439f7830e0f8446905 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Tue, 27 Jan 2026 13:29:11 -0300 Subject: [PATCH 37/42] fix: restore conditional posting of GitHub PR comments for specific branch types in release script --- scripts/release.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/scripts/release.js b/scripts/release.js index 0c65370..f2b14c2 100644 --- a/scripts/release.js +++ b/scripts/release.js @@ -28,11 +28,10 @@ const getConfig = ({ gitBranchName }) => { }; // Only post GH PR comments for alpha, hotfix/*, and release branches. - // if ( ! ["alpha", "hotfix", "release"].includes(branchType) ) { - // Temporarily disable comments for all branches to prevent spam. - githubConfig.successComment = false; - githubConfig.failComment = false; - // } + if ( ! ["alpha", "hotfix", "release"].includes(branchType) ) { + githubConfig.successComment = false; + githubConfig.failComment = false; + } // Only publish alpha and release branches to NPM. const shouldPublishOnNPM = Boolean( process.env.NPM_TOKEN ) && ["alpha", "release"].includes(branchType); From b9ca882e137784bffd85f6f30c28f57edee33103 Mon Sep 17 00:00:00 2001 From: Ramon Corrales Date: Tue, 27 Jan 2026 18:11:48 -0500 Subject: [PATCH 38/42] fix: remove CircleCI references from release-wporg.sh --- release-wporg.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/release-wporg.sh b/release-wporg.sh index 2d84675..58acf66 100755 --- a/release-wporg.sh +++ b/release-wporg.sh @@ -9,7 +9,6 @@ SVN_PLUGINS_URL="https://plugins.svn.wordpress.org" SVN_REPO_LOCAL_PATH="release/svn" -WP_ORG_PLUGIN_NAME="${WP_ORG_PLUGIN_NAME:=$CIRCLE_PROJECT_REPONAME}" SVN_REPO_URL="$SVN_PLUGINS_URL/$WP_ORG_PLUGIN_NAME" LATEST_GIT_TAG=$(git describe --tags `git rev-list --tags --max-count=1`) @@ -36,7 +35,7 @@ svn checkout -q "$SVN_REPO_URL" . rm -rf trunk -cp -r "../$CIRCLE_PROJECT_REPONAME" ./trunk +cp -r "../$WP_ORG_PLUGIN_NAME" ./trunk cp -r ./trunk "./tags/$LATEST_SVN_TAG" # Add new files to SVN From 27edf1087d02db241dd7cf7c41bb0238c43aa6a0 Mon Sep 17 00:00:00 2001 From: Ramon Corrales Date: Fri, 30 Jan 2026 11:29:48 -0500 Subject: [PATCH 39/42] refactor: reusable WP.org release workflow (#226) --- .github/workflows/reusable-release-wporg.yml | 58 ++++++++++++++++++++ .github/workflows/reusable-release.yml | 8 +++ 2 files changed, 66 insertions(+) create mode 100644 .github/workflows/reusable-release-wporg.yml diff --git a/.github/workflows/reusable-release-wporg.yml b/.github/workflows/reusable-release-wporg.yml new file mode 100644 index 0000000..dba4e0c --- /dev/null +++ b/.github/workflows/reusable-release-wporg.yml @@ -0,0 +1,58 @@ +# Release to WordPress.org. +# Requires the calling workflow to run reusable-release.yml first (which uploads release artifacts). +name: Release to WordPress.org + +on: + workflow_call: + inputs: + plugin-name: + description: 'WordPress.org plugin slug. Defaults to the repository name.' + required: false + type: string + default: '' + secrets: + WP_ORG_USERNAME: + required: true + WP_ORG_PASSWORD: + required: true + +jobs: + release-wporg: + name: Release to WordPress.org + runs-on: ubuntu-latest + env: + PLUGIN_NAME: ${{ inputs.plugin-name || github.event.repository.name }} + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Install dependencies + run: npm ci --legacy-peer-deps + + - name: Download release artifacts + uses: actions/download-artifact@v4 + with: + name: release-artifacts + path: release/ + + - name: Verify release artifacts + run: | + if [ ! -d "release/$PLUGIN_NAME" ]; then + echo "::error::release/$PLUGIN_NAME not found. The release job must produce this directory via release:archive." + exit 1 + fi + + - name: Release to WordPress.org + env: + WP_ORG_USERNAME: ${{ secrets.WP_ORG_USERNAME }} + WP_ORG_PASSWORD: ${{ secrets.WP_ORG_PASSWORD }} + WP_ORG_PLUGIN_NAME: ${{ env.PLUGIN_NAME }} + run: ./node_modules/newspack-scripts/release-wporg.sh diff --git a/.github/workflows/reusable-release.yml b/.github/workflows/reusable-release.yml index 84b1fa2..cc8589e 100644 --- a/.github/workflows/reusable-release.yml +++ b/.github/workflows/reusable-release.yml @@ -51,3 +51,11 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} run: npm run release + + - name: Upload release artifacts + uses: actions/upload-artifact@v4 + with: + name: release-artifacts + path: release/ + if-no-files-found: ignore + retention-days: 1 From adb73f92f7efafc874a91f283d2c591560002e81 Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Fri, 30 Jan 2026 13:31:15 -0300 Subject: [PATCH 40/42] chore: restore circleci config --- .circleci/config.yml | 30 ++++++++ src/@orb.yml | 8 +++ src/commands/checkout_with_workspace.yml | 6 ++ src/commands/set_node_version.yml | 20 ++++++ src/executors/default.yml | 8 +++ src/executors/php-81.yml | 8 +++ src/jobs/build-distributable.yml | 25 +++++++ src/jobs/build.yml | 28 ++++++++ src/jobs/check-typescript.yml | 11 +++ src/jobs/generate-docs.yml | 30 ++++++++ src/jobs/i18n.yml | 91 ++++++++++++++++++++++++ src/jobs/lint-js-scss.yml | 11 +++ src/jobs/lint-php.yml | 12 ++++ src/jobs/post-release.yml | 10 +++ src/jobs/release.yml | 21 ++++++ src/jobs/test-js.yml | 11 +++ src/jobs/test-php.yml | 49 +++++++++++++ 17 files changed, 379 insertions(+) create mode 100644 .circleci/config.yml create mode 100755 src/@orb.yml create mode 100755 src/commands/checkout_with_workspace.yml create mode 100755 src/commands/set_node_version.yml create mode 100755 src/executors/default.yml create mode 100755 src/executors/php-81.yml create mode 100644 src/jobs/build-distributable.yml create mode 100755 src/jobs/build.yml create mode 100644 src/jobs/check-typescript.yml create mode 100644 src/jobs/generate-docs.yml create mode 100644 src/jobs/i18n.yml create mode 100644 src/jobs/lint-js-scss.yml create mode 100644 src/jobs/lint-php.yml create mode 100644 src/jobs/post-release.yml create mode 100644 src/jobs/release.yml create mode 100644 src/jobs/test-js.yml create mode 100644 src/jobs/test-php.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..12834ee --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,30 @@ +version: 2 +jobs: + build: + docker: + - image: "circleci/node:latest" + steps: + - checkout + - run: + name: Install nvm and use the node version defined in .nvmrc + command: | + # https://support.circleci.com/hc/en-us/articles/360051656632-Swap-node-version-on-CircleCI-convenience-image + set +e + wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash + export NVM_DIR="$HOME/.nvm" + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" + nvm install + nvm use + # https://stackoverflow.com/a/61823737/3772847 + NODE_DIR=$(dirname $(which node)) + echo "export PATH=$NODE_DIR:\$PATH" >> $BASH_ENV + - run: + name: Check node version (should match the version set in project's .nvmrc file) + command: node --version + - run: + name: install + command: npm install --legacy-peer-deps + - run: + name: release + command: npm run semantic-release || true \ No newline at end of file diff --git a/src/@orb.yml b/src/@orb.yml new file mode 100755 index 0000000..5270831 --- /dev/null +++ b/src/@orb.yml @@ -0,0 +1,8 @@ +version: 2.1 + +description: > + Newspack shared CI config. + +display: + home_url: "https://newspack.com" + source_url: "https://www.github.com/Automattic/newspack-scripts" diff --git a/src/commands/checkout_with_workspace.yml b/src/commands/checkout_with_workspace.yml new file mode 100755 index 0000000..ad3ec5a --- /dev/null +++ b/src/commands/checkout_with_workspace.yml @@ -0,0 +1,6 @@ +description: > + Chechout code and attach workspace. +steps: + - checkout + - attach_workspace: + at: ~/ diff --git a/src/commands/set_node_version.yml b/src/commands/set_node_version.yml new file mode 100755 index 0000000..258ede4 --- /dev/null +++ b/src/commands/set_node_version.yml @@ -0,0 +1,20 @@ +description: > + Set node version to the one defined in the .nvmrc file. +steps: + - run: + name: Install nvm and use the node version defined in .nvmrc + command: | + # https://support.circleci.com/hc/en-us/articles/360051656632-Swap-node-version-on-CircleCI-convenience-image + set +e + wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash + export NVM_DIR="$HOME/.nvm" + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" + nvm install + nvm use + # https://stackoverflow.com/a/61823737/3772847 + NODE_DIR=$(dirname $(which node)) + echo "export PATH=$NODE_DIR:\$PATH" >> $BASH_ENV + - run: + name: Check node version (should match the version set in project's .nvmrc file) + command: node --version diff --git a/src/executors/default.yml b/src/executors/default.yml new file mode 100755 index 0000000..b9c2e06 --- /dev/null +++ b/src/executors/default.yml @@ -0,0 +1,8 @@ +description: PHP executor +docker: + - image: "cimg/php:<>" +parameters: + tag: + default: 8.3-node + description: PHP image version + type: string diff --git a/src/executors/php-81.yml b/src/executors/php-81.yml new file mode 100755 index 0000000..c7e0dfc --- /dev/null +++ b/src/executors/php-81.yml @@ -0,0 +1,8 @@ +description: PHP executor +docker: + - image: "cimg/php:<>" +parameters: + tag: + default: 8.1-node + description: PHP image version + type: string diff --git a/src/jobs/build-distributable.yml b/src/jobs/build-distributable.yml new file mode 100644 index 0000000..79ceb98 --- /dev/null +++ b/src/jobs/build-distributable.yml @@ -0,0 +1,25 @@ +description: > + Build the distributable files, so they are available as CI artifacts. + +executor: default + +parameters: + archive-name: + type: string + default: "" + description: "Name of the ZIP archive distributable." + +steps: + - checkout_with_workspace + - set_node_version + - run: + name: Install rsync + command: sudo apt-get update && sudo apt-get install rsync + - run: + name: Install PHP packages + command: composer install --no-dev --no-scripts + - run: + name: Build plugin files + command: npm run build && npm run release:archive + - store_artifacts: + path: release/<>.zip diff --git a/src/jobs/build.yml b/src/jobs/build.yml new file mode 100755 index 0000000..dce2c58 --- /dev/null +++ b/src/jobs/build.yml @@ -0,0 +1,28 @@ +description: > + Install node dependencies. + +executor: default + +steps: + - checkout_with_workspace + - set_node_version + - restore_cache: + key: v1-npm-{{ checksum "package.json" }}-{{checksum "package-lock.json" }}-{{ checksum ".nvmrc" }} + # https://medium.com/@mdsky1986/caching-node-dependencies-when-using-npm-ci-89fe3f46404a + - run: + name: Install node dependencies + # --legacy-peer-deps flag should be removed once https://github.com/Automattic/newspack-plugin/issues/1218 is resolved + command: | + if test -d "node_modules"; then + echo "package.json and package-lock.json unchanged. Using cache." + else + npm ci --legacy-peer-deps --loglevel warn --yes + fi + - save_cache: + key: v1-npm-{{ checksum "package.json" }}-{{checksum "package-lock.json" }}-{{ checksum ".nvmrc" }} + paths: + - node_modules + - persist_to_workspace: + root: ~/ + paths: + - project diff --git a/src/jobs/check-typescript.yml b/src/jobs/check-typescript.yml new file mode 100644 index 0000000..3af092a --- /dev/null +++ b/src/jobs/check-typescript.yml @@ -0,0 +1,11 @@ +description: > + Validate TypeScript. + +executor: default + +steps: + - checkout_with_workspace + - set_node_version + - run: + name: Validate TypeScript + command: npm run typescript:check diff --git a/src/jobs/generate-docs.yml b/src/jobs/generate-docs.yml new file mode 100644 index 0000000..6a878d8 --- /dev/null +++ b/src/jobs/generate-docs.yml @@ -0,0 +1,30 @@ +description: > + Generate documentation. This will create a new branch called docs and push the HTML documentation to it, as /docs directory. + To make this work with GH pages, visit /settings/pages, set branch to "docs", and folder to "/docs". + +executor: php-81 + +steps: + - checkout + - run: + name: Install dependencies + command: | + sudo apt-get update && sudo apt-get install -y graphviz plantuml + - run: + name: Download PHPDocumentor + command: | + curl -L -o ./phpdocumentor https://phpdoc.org/phpDocumentor.phar + chmod +x ./phpdocumentor + - run: + name: Generate documentation + command: | + ./phpdocumentor run -d . -t ./docs + - run: + name: Switch to docs branch, commit, and push + command: | + git config user.name "${GIT_COMMITTER_NAME}" + git config user.email "${GITHUB_COMMITER_EMAIL}" + git checkout -b docs + git add -f docs + git commit -m "Update the docs" + git push "https://${GITHUB_TOKEN}@github.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}.git" --force diff --git a/src/jobs/i18n.yml b/src/jobs/i18n.yml new file mode 100644 index 0000000..684bff7 --- /dev/null +++ b/src/jobs/i18n.yml @@ -0,0 +1,91 @@ +description: > + Create translation files. + +executor: default + +steps: + - checkout_with_workspace + - run: + name: Check if commit author is bot + command: | + COMMIT_AUTHOR=$(git log -1 --pretty=format:'%ae') + if [ "$COMMIT_AUTHOR" = "$GITHUB_COMMITER_EMAIL" ]; then + echo "Commit was made by bot ($(git rev-parse --short HEAD)), skipping translation update" + circleci step halt + fi + - run: + name: Install WP CLI + command: | + curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar + chmod +x wp-cli.phar + sudo mv wp-cli.phar /usr/local/bin/wp + - run: + name: Build plugin files, so dist dir is available + command: | + npm run build || true + - run: + name: Create POT translation files + command: | + # Theme is excluded, more in https://github.com/Automattic/newspack-theme/pull/2458 + if [ "$CIRCLE_PROJECT_REPONAME" = "newspack-theme" ]; then + cd ./newspack-theme + wp i18n make-pot . languages/${CIRCLE_PROJECT_REPONAME}.pot --exclude='src' --domain=${CIRCLE_PROJECT_REPONAME} + cd - + else + wp i18n make-pot . languages/${CIRCLE_PROJECT_REPONAME}.pot --domain=${CIRCLE_PROJECT_REPONAME} + fi + - run: + name: Create JSON translation files + command: | + if [ "$CIRCLE_PROJECT_REPONAME" = "newspack-theme" ]; then + cd ./newspack-theme + fi + + sudo apt-get update && sudo apt-get install -y gettext + + cd languages + + # Create PO files from POT if they don't exist + if [ ! -f "${CIRCLE_PROJECT_REPONAME}-en_US.po" ]; then + echo "Creating ${CIRCLE_PROJECT_REPONAME}-en_US.po from POT file" + wp i18n update-po ${CIRCLE_PROJECT_REPONAME}.pot . + else + echo "${CIRCLE_PROJECT_REPONAME}-en_US.po file already exists, skipping creation" + fi + + for po in *.po; do + if [ -f "$po" ]; then + echo "Processing file $po …" + # Update translations according to the new POT file + msgmerge $po $CIRCLE_PROJECT_REPONAME.pot -o $po.out + mv $po.out $po + msgfmt $po -o $(basename $po .po).mo + # no-purge since we need the JS translations for the next run + wp i18n make-json --no-purge $po . + fi + done + - run: + name: Commit translation files + command: | + if [ "$CIRCLE_PROJECT_REPONAME" = "newspack-theme" ]; then + cd ./newspack-theme + fi + if [ -d "languages" ]; then + LINES_CHANGED=$(git diff --numstat languages/ | awk '{sum += $1 + $2} END {print sum}') + # If no existing files were changed, check for new files + if [ -z "$LINES_CHANGED" ] || [ "$LINES_CHANGED" -eq 0 ]; then + LINES_CHANGED=$(git ls-files --others --exclude-standard languages/ | xargs wc -l 2>/dev/null | tail -1 | awk '{print $1}') + fi + else + LINES_CHANGED=0 + fi + LINES_CHANGED=${LINES_CHANGED:-0} + echo "Lines changed in languages/: $LINES_CHANGED" + if [ "$LINES_CHANGED" -gt 3 ]; then + git config user.email "$GITHUB_COMMITER_EMAIL" + git config user.name "$GIT_COMMITTER_NAME" + git remote set-url origin https://$GITHUB_TOKEN@github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME.git + git add languages/ + git commit -m "chore: update translation files [skip ci]" + git push origin $CIRCLE_BRANCH + fi diff --git a/src/jobs/lint-js-scss.yml b/src/jobs/lint-js-scss.yml new file mode 100644 index 0000000..86873d2 --- /dev/null +++ b/src/jobs/lint-js-scss.yml @@ -0,0 +1,11 @@ +description: > + Lint the JS & SCSS (temporarily skipped) files. + +executor: default + +steps: + - checkout_with_workspace + - set_node_version + - run: + name: Run Linter + command: npm run lint:js # Temporarily skip linting SCSS due to stylelint config updates. Remove :js when ready to re-enable linting of SCSS. diff --git a/src/jobs/lint-php.yml b/src/jobs/lint-php.yml new file mode 100644 index 0000000..eae5746 --- /dev/null +++ b/src/jobs/lint-php.yml @@ -0,0 +1,12 @@ +description: > + Lint PHP files. + +executor: default + +steps: + - checkout + - run: + name: Lint Files + command: | + composer install + ./vendor/bin/phpcs diff --git a/src/jobs/post-release.yml b/src/jobs/post-release.yml new file mode 100644 index 0000000..418d190 --- /dev/null +++ b/src/jobs/post-release.yml @@ -0,0 +1,10 @@ +description: > + Perform post-release tasks. + +executor: default + +steps: + - checkout_with_workspace + - run: + name: Perform post-release chores + command: ./node_modules/newspack-scripts/post-release.sh diff --git a/src/jobs/release.yml b/src/jobs/release.yml new file mode 100644 index 0000000..09f977f --- /dev/null +++ b/src/jobs/release.yml @@ -0,0 +1,21 @@ +description: > + Release new version. + +executor: default + +steps: + - checkout_with_workspace + - set_node_version + - run: + name: Install rsync + command: sudo apt-get update && sudo apt-get install rsync + - run: + name: Install PHP packages + command: composer install --no-dev --no-scripts + - run: + name: Release new version + command: npm run release + - persist_to_workspace: + root: ~/ + paths: + - project diff --git a/src/jobs/test-js.yml b/src/jobs/test-js.yml new file mode 100644 index 0000000..5c5ddae --- /dev/null +++ b/src/jobs/test-js.yml @@ -0,0 +1,11 @@ +description: > + Run JS tests. + +executor: default + +steps: + - checkout_with_workspace + - set_node_version + - run: + name: Run JS Tests + command: npm run test diff --git a/src/jobs/test-php.yml b/src/jobs/test-php.yml new file mode 100644 index 0000000..c27feff --- /dev/null +++ b/src/jobs/test-php.yml @@ -0,0 +1,49 @@ +description: > + Run PHP tests. + +docker: + - image: cimg/php:8.3 + - image: circleci/mysql:5.6.50 + +environment: + - WP_TESTS_DIR: "/tmp/wordpress-tests-lib" + - WP_CORE_DIR: "/tmp/wordpress/" +steps: + - checkout + - run: + name: Setup Environment Variables + command: | + echo "export PATH=$HOME/.composer/vendor/bin:$PATH" >> $BASH_ENV + source /home/circleci/.bashrc + - run: + name: Install Dependencies + command: | + sudo apt-get update && sudo apt-get install -y subversion default-mysql-client + - run: + name: Run Tests with Coverage + command: | + composer update + rm -rf $WP_TESTS_DIR $WP_CORE_DIR + bash bin/install-wp-tests.sh wordpress_test root '' 127.0.0.1 latest + # https://circleci.com/docs/code-coverage/#php + XDEBUG_MODE=coverage phpdbg -qrr vendor/bin/phpunit --coverage-clover coverage.xml + - run: + name: Upload Test Results to Codecov + command: | + if [[ -n $CODECOV_TOKEN ]]; then + # download Codecov CLI + curl -Os https://cli.codecov.io/latest/linux/codecov + + # integrity check + curl https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --no-default-keyring --keyring trustedkeys.gpg --import # One-time step + curl -Os https://cli.codecov.io/latest/linux/codecov + curl -Os https://cli.codecov.io/latest/linux/codecov.SHA256SUM + curl -Os https://cli.codecov.io/latest/linux/codecov.SHA256SUM.sig + gpgv codecov.SHA256SUM.sig codecov.SHA256SUM + + shasum -a 256 -c codecov.SHA256SUM + sudo chmod +x codecov + ./codecov upload-process -t $CODECOV_TOKEN + else + echo "CODECOV_TOKEN is not set. Skipping upload to Codecov." + fi From a61eef4fb268d0aadab8984c1114836172c8ca8e Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Fri, 30 Jan 2026 13:39:25 -0300 Subject: [PATCH 41/42] chore: restore scripts --- .github/workflows/reusable-post-release.yml | 2 +- .github/workflows/reusable-release-wporg.yml | 2 +- post-release.sh | 6 +- release-wporg.sh | 3 +- scripts/github/post-release.sh | 73 ++++++++ scripts/github/release-wporg.sh | 48 ++++++ scripts/github/release.js | 165 +++++++++++++++++++ scripts/release.js | 10 +- 8 files changed, 296 insertions(+), 13 deletions(-) create mode 100755 scripts/github/post-release.sh create mode 100755 scripts/github/release-wporg.sh create mode 100644 scripts/github/release.js diff --git a/.github/workflows/reusable-post-release.yml b/.github/workflows/reusable-post-release.yml index 69b074d..f118f98 100644 --- a/.github/workflows/reusable-post-release.yml +++ b/.github/workflows/reusable-post-release.yml @@ -38,4 +38,4 @@ jobs: GITHUB_COMMITER_EMAIL: github-actions[bot]@users.noreply.github.com SLACK_CHANNEL_ID: ${{ secrets.SLACK_CHANNEL_ID }} SLACK_AUTH_TOKEN: ${{ secrets.SLACK_AUTH_TOKEN }} - run: ./node_modules/newspack-scripts/post-release.sh + run: ./node_modules/newspack-scripts/scripts/github/post-release.sh diff --git a/.github/workflows/reusable-release-wporg.yml b/.github/workflows/reusable-release-wporg.yml index dba4e0c..79c7535 100644 --- a/.github/workflows/reusable-release-wporg.yml +++ b/.github/workflows/reusable-release-wporg.yml @@ -55,4 +55,4 @@ jobs: WP_ORG_USERNAME: ${{ secrets.WP_ORG_USERNAME }} WP_ORG_PASSWORD: ${{ secrets.WP_ORG_PASSWORD }} WP_ORG_PLUGIN_NAME: ${{ env.PLUGIN_NAME }} - run: ./node_modules/newspack-scripts/release-wporg.sh + run: ./node_modules/newspack-scripts/scripts/github/release-wporg.sh diff --git a/post-release.sh b/post-release.sh index b8a1c19..7bac57a 100755 --- a/post-release.sh +++ b/post-release.sh @@ -23,13 +23,13 @@ if [[ $(echo $SECOND_TO_LAST_COMMIT_MSG | grep '^Merge .*alpha') ]]; then # we don't care about any alpha changes. git reset --hard release -- # Force-push the alpha branch. - git push "https://$GITHUB_TOKEN@github.com/${GITHUB_REPOSITORY}.git" --force + git push "https://$GITHUB_TOKEN@github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME.git" --force else echo '[newspack-scripts] Release was created from a different branch than the alpha branch (e.g. a hotfix branch).' echo '[newspack-scripts] Alpha branch will now be updated with the lastest changes from release.' git merge --no-ff release -m "chore(release): merge in release $LATEST_VERSION_TAG" if [[ $? == 0 ]]; then - git push "https://$GITHUB_TOKEN@github.com/${GITHUB_REPOSITORY}.git" + git push "https://$GITHUB_TOKEN@github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME.git" else git merge --abort echo '[newspack-scripts] Post-release merge to alpha failed.' @@ -55,7 +55,7 @@ git checkout trunk git merge --no-ff release -m "chore(release): merge in release $LATEST_VERSION_TAG" if [[ $? == 0 ]]; then echo '[newspack-scripts] Pushing updated trunk to origin.' - git push "https://$GITHUB_TOKEN@github.com/${GITHUB_REPOSITORY}.git" + git push "https://$GITHUB_TOKEN@github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME.git" else git merge --abort echo '[newspack-scripts] Post-release merge to trunk failed.' diff --git a/release-wporg.sh b/release-wporg.sh index 58acf66..2d84675 100755 --- a/release-wporg.sh +++ b/release-wporg.sh @@ -9,6 +9,7 @@ SVN_PLUGINS_URL="https://plugins.svn.wordpress.org" SVN_REPO_LOCAL_PATH="release/svn" +WP_ORG_PLUGIN_NAME="${WP_ORG_PLUGIN_NAME:=$CIRCLE_PROJECT_REPONAME}" SVN_REPO_URL="$SVN_PLUGINS_URL/$WP_ORG_PLUGIN_NAME" LATEST_GIT_TAG=$(git describe --tags `git rev-list --tags --max-count=1`) @@ -35,7 +36,7 @@ svn checkout -q "$SVN_REPO_URL" . rm -rf trunk -cp -r "../$WP_ORG_PLUGIN_NAME" ./trunk +cp -r "../$CIRCLE_PROJECT_REPONAME" ./trunk cp -r ./trunk "./tags/$LATEST_SVN_TAG" # Add new files to SVN diff --git a/scripts/github/post-release.sh b/scripts/github/post-release.sh new file mode 100755 index 0000000..b8a1c19 --- /dev/null +++ b/scripts/github/post-release.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +# This script should be ran on CI after a new regular (not pre-release) version is released. + +git config user.name "$GIT_COMMITTER_NAME" +git config user.email "$GITHUB_COMMITER_EMAIL" + +# The last commit message at this point is the automated release commit. The second-to-last +# commit message should contain data about the merge. +SECOND_TO_LAST_COMMIT_MSG=$(git log -n 1 --skip 1 --pretty=format:"%s") + +LATEST_VERSION_TAG=$(git describe --tags --abbrev=0) + +git pull origin release +git checkout alpha + +# If the merge was from alpha branch (the basic flow), alpha branch should be reset. +if [[ $(echo $SECOND_TO_LAST_COMMIT_MSG | grep '^Merge .*alpha') ]]; then + echo '[newspack-scripts] Release was created from the alpha branch. Alpha branch will now be reset.' + + # Reset the tip of alpha branch to the release branch. + # The alpha branch is single-serving, just for alpha releases. After a release, + # we don't care about any alpha changes. + git reset --hard release -- + # Force-push the alpha branch. + git push "https://$GITHUB_TOKEN@github.com/${GITHUB_REPOSITORY}.git" --force +else + echo '[newspack-scripts] Release was created from a different branch than the alpha branch (e.g. a hotfix branch).' + echo '[newspack-scripts] Alpha branch will now be updated with the lastest changes from release.' + git merge --no-ff release -m "chore(release): merge in release $LATEST_VERSION_TAG" + if [[ $? == 0 ]]; then + git push "https://$GITHUB_TOKEN@github.com/${GITHUB_REPOSITORY}.git" + else + git merge --abort + echo '[newspack-scripts] Post-release merge to alpha failed.' + if [ -z "$SLACK_CHANNEL_ID" ] || [ -z "$SLACK_AUTH_TOKEN" ]; then + echo '[newspack-scripts] Missing Slack channel ID and/or token. Cannot notify.' + else + echo '[newspack-scripts] Notifying the team on Slack.' + curl \ + --data "{\"channel\":\"$SLACK_CHANNEL_ID\",\"blocks\":[{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"⚠️ Post-release merge to alpha failed for: \`$CIRCLE_PROJECT_REPONAME\`. Check <$CIRCLE_BUILD_URL|the build> for details.\"}}]}" \ + -H "Content-type: application/json" \ + -H "Authorization: Bearer $SLACK_AUTH_TOKEN" \ + -X POST https://slack.com/api/chat.postMessage \ + -s > /dev/null + fi + fi +fi + +# Update trunk branch with latest changes from the release branch, so they are in sync. +echo '[newspack-scripts] Merging the release branch into trunk.' +git checkout trunk + +# Merge release branch into trunk branch, and notify the team if any conflicts arise. +git merge --no-ff release -m "chore(release): merge in release $LATEST_VERSION_TAG" +if [[ $? == 0 ]]; then + echo '[newspack-scripts] Pushing updated trunk to origin.' + git push "https://$GITHUB_TOKEN@github.com/${GITHUB_REPOSITORY}.git" +else + git merge --abort + echo '[newspack-scripts] Post-release merge to trunk failed.' + if [ -z "$SLACK_CHANNEL_ID" ] || [ -z "$SLACK_AUTH_TOKEN" ]; then + echo '[newspack-scripts] Missing Slack channel ID and/or token. Cannot notify.' + else + echo '[newspack-scripts] Notifying the team on Slack.' + curl \ + --data "{\"channel\":\"$SLACK_CHANNEL_ID\",\"blocks\":[{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"⚠️ Post-release merge to \`trunk\` failed for: \`$CIRCLE_PROJECT_REPONAME\`. Check <$CIRCLE_BUILD_URL|the build> for details.\"}}]}" \ + -H "Content-type: application/json" \ + -H "Authorization: Bearer $SLACK_AUTH_TOKEN" \ + -X POST https://slack.com/api/chat.postMessage \ + -s > /dev/null + fi +fi diff --git a/scripts/github/release-wporg.sh b/scripts/github/release-wporg.sh new file mode 100755 index 0000000..58acf66 --- /dev/null +++ b/scripts/github/release-wporg.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash + +# Release the latest version on wordpress.org plugin repository. +# To be run as part of CI workflow. +# Assumptions: +# - repository name matches the wordpress.org plugin name or WP_ORG_PLUGIN_NAME is set, +# - there is a `release` directory with the folder containing the files and named as the plugin in it +# Partially adapted from https://carlalexander.ca/continuous-deployment-wordpress-directory-circleci/ + +SVN_PLUGINS_URL="https://plugins.svn.wordpress.org" +SVN_REPO_LOCAL_PATH="release/svn" +SVN_REPO_URL="$SVN_PLUGINS_URL/$WP_ORG_PLUGIN_NAME" + +LATEST_GIT_TAG=$(git describe --tags `git rev-list --tags --max-count=1`) +# Remove the "v" at the beginning of the git tag +LATEST_SVN_TAG=${LATEST_GIT_TAG:1} + +mkdir -p $SVN_REPO_LOCAL_PATH && cd $SVN_REPO_LOCAL_PATH +sudo apt-get update +sudo apt-get install subversion + +# Check if the latest SVN tag exists already +TAG=$(svn ls "$SVN_REPO_URL/tags/$LATEST_SVN_TAG") +error=$? +if [ $error == 0 ]; then + # Tag exists, don't deploy + echo "Latest tag ($LATEST_SVN_TAG) already exists on the WordPress directory. No deployment needed!" + exit 0 +fi + +# Wait a moment to avoid a 429 by WPORG's server. +sleep 3 + +svn checkout -q "$SVN_REPO_URL" . + +rm -rf trunk + +cp -r "../$WP_ORG_PLUGIN_NAME" ./trunk +cp -r ./trunk "./tags/$LATEST_SVN_TAG" + +# Add new files to SVN +svn stat | grep '^?' | awk '{print $2}' | xargs -I x svn add x@ + +# Remove deleted files from SVN +svn stat | grep '^!' | awk '{print $2}' | xargs -I x svn rm --force x@ + +# Commit to SVN +svn ci --no-auth-cache --username $WP_ORG_USERNAME --password $WP_ORG_PASSWORD -m "Deploy version $LATEST_SVN_TAG" diff --git a/scripts/github/release.js b/scripts/github/release.js new file mode 100644 index 0000000..f2b14c2 --- /dev/null +++ b/scripts/github/release.js @@ -0,0 +1,165 @@ +'use strict'; + +const utils = require( './utils/index.js' ); + +const semanticRelease = require( 'semantic-release' ); + +const { files, ...otherArgs } = require( 'yargs/yargs' )( + process.argv.slice( 2 ) +).parse(); + +const filesList = files.split( ',' ); + +// Get repository name from GitHub Actions environment variable (format: owner/repo). +const repoName = process.env.GITHUB_REPOSITORY?.split( '/' )[ 1 ] || 'unknown'; + +utils.log( `Releasing ${ repoName }…` ); + +const getConfig = ({ gitBranchName }) => { + const branchType = gitBranchName.split("/")[0]; + const githubConfig = { + assets: [ + { + path: `./release/${ repoName }.zip`, + label: `${ repoName }.zip`, + }, + ], + releasedLabels: false, + }; + + // Only post GH PR comments for alpha, hotfix/*, and release branches. + if ( ! ["alpha", "hotfix", "release"].includes(branchType) ) { + githubConfig.successComment = false; + githubConfig.failComment = false; + } + + // Only publish alpha and release branches to NPM. + const shouldPublishOnNPM = Boolean( process.env.NPM_TOKEN ) && ["alpha", "release"].includes(branchType); + if ( shouldPublishOnNPM ) { + utils.log( `Will publish to npm.` ); + } + + const config = { + dryRun: otherArgs.dryRun, + ci: otherArgs.ci, + debug: otherArgs.debug, + + branches: [ + // `release` branch is published on the main distribution channel (a new version on GH). + "release", + // `alpha` branch – for regular pre-releases. + { + name: "alpha", + prerelease: true, + }, + // `hotfix/*` branches – for releases outside of the release schedule. + { + name: "hotfix/*", + // With `prerelease: true`, the `name` would be used for the pre-release tag. A name with a `/` + // is not valid, though. See https://semver.org/#spec-item-9. + prerelease: '${name.replace(/\\//g, "-")}', + }, + // `epic/*` branches – for beta testing/QA pre-release builds. + { + name: "epic/*", + // With `prerelease: true`, the `name` would be used for the pre-release tag. A name with a `/` + // is not valid, though. See https://semver.org/#spec-item-9. + prerelease: '${name.replace(/\\//g, "-")}', + }, + ], + prepare: ["@semantic-release/changelog", "@semantic-release/npm"], + plugins: [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-notes-generator", + [ + // Whether to publish on npm. + "@semantic-release/npm", + { + npmPublish: shouldPublishOnNPM, + }, + ], + "semantic-release-version-bump", + // Add the built ZIP archive to GH release. + [ + "@semantic-release/github", + githubConfig, + ], + ], + }; + + // Bump the semver and prepare a build package. + config.prepare.push( [ + // Increment the version in additional files, and the create the release archive. + 'semantic-release-version-bump', + { + files: filesList, + callback: 'npm run release:archive', + }, + ] ); + + // Unless on a hotfix or epic branch, add a commit that updates the files. + if ( [ 'hotfix', 'epic' ].indexOf( branchType ) === -1 ) { + let assets = filesList; + // These assets should be added to source control after a release. + if ( branchType === 'release' ) { + assets = [ + ...filesList, + 'package.json', + 'package-lock.json', + 'CHANGELOG.md', + ]; + } + utils.log( + `On ${ branchType } branch, following files will be updated: ${ assets.join( + ', ' + ) }` + ); + config.prepare.push( { + path: '@semantic-release/git', + assets, + message: + 'chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}', + } ); + } else { + utils.log( + `This branch is ${ branchType }, plugin files and the changelog will *not* be updated.` + ); + } + + return config; +}; + +const run = async () => { + try { + const gitBranch = await utils.getGitBranch(); + + const result = await semanticRelease.default( + getConfig( { gitBranchName: gitBranch } ) + ); + + if ( result ) { + const { lastRelease, commits, nextRelease, releases } = result; + + utils.log( + `Published ${ nextRelease.type } release version ${ nextRelease.version } containing ${ commits.length } commits.` + ); + + if ( lastRelease.version ) { + utils.log( `The last release was "${ lastRelease.version }".` ); + } + + for ( const release of releases ) { + utils.log( + `The release was published with plugin "${ release.pluginName }".` + ); + } + } else { + utils.log( 'No release published.' ); + } + } catch ( err ) { + console.error( 'The automated release failed with %O', err ); + process.exit( 1 ); + } +}; + +run(); diff --git a/scripts/release.js b/scripts/release.js index f2b14c2..40c3974 100644 --- a/scripts/release.js +++ b/scripts/release.js @@ -10,21 +10,17 @@ const { files, ...otherArgs } = require( 'yargs/yargs' )( const filesList = files.split( ',' ); -// Get repository name from GitHub Actions environment variable (format: owner/repo). -const repoName = process.env.GITHUB_REPOSITORY?.split( '/' )[ 1 ] || 'unknown'; - -utils.log( `Releasing ${ repoName }…` ); +utils.log( `Releasing ${ process.env.CIRCLE_PROJECT_REPONAME }…` ); const getConfig = ({ gitBranchName }) => { const branchType = gitBranchName.split("/")[0]; const githubConfig = { assets: [ { - path: `./release/${ repoName }.zip`, - label: `${ repoName }.zip`, + path: `./release/${process.env.CIRCLE_PROJECT_REPONAME}.zip`, + label: `${process.env.CIRCLE_PROJECT_REPONAME}.zip`, }, ], - releasedLabels: false, }; // Only post GH PR comments for alpha, hotfix/*, and release branches. From 6afc6e16c1b23435269f6614752e3ffba307296d Mon Sep 17 00:00:00 2001 From: Miguel Peixe Date: Fri, 30 Jan 2026 13:45:24 -0300 Subject: [PATCH 42/42] feat: add script path resolution for GitHub Actions --- bin/newspack-scripts.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/bin/newspack-scripts.js b/bin/newspack-scripts.js index 550e3a4..01e41a5 100755 --- a/bin/newspack-scripts.js +++ b/bin/newspack-scripts.js @@ -1,10 +1,33 @@ #!/usr/bin/env node +const fs = require( 'fs' ); +const path = require( 'path' ); const spawn = require( 'cross-spawn' ); const utils = require( '../scripts/utils/index.js' ); const [ scriptName, ...nodeArgs ] = process.argv.slice( 2 ); +/** + * Resolve script path. If running in GitHub Actions, try to find the script + * in `scripts/github/` first, otherwise fall back to `scripts/`. + * + * @param {string} name Script name. + * @return {string} Resolved script path. + */ +const resolveScript = ( name ) => { + if ( process.env.GITHUB_ACTIONS ) { + const githubScriptPath = path.resolve( + __dirname, + '../scripts/github/', + name + '.js' + ); + if ( fs.existsSync( githubScriptPath ) ) { + return githubScriptPath; + } + } + return require.resolve( '../scripts/' + name ); +}; + if ( [ 'test', @@ -18,7 +41,7 @@ if ( ) { const result = spawn.sync( process.execPath, - [ require.resolve( '../scripts/' + scriptName ), ...nodeArgs ], + [ resolveScript( scriptName ), ...nodeArgs ], { stdio: 'inherit' } ); if ( result.signal ) {