Skip to content

Select plugin version prototype (Not meant to be merged)#345

Open
sandyfzu wants to merge 4 commits into
developfrom
select-version-prototype
Open

Select plugin version prototype (Not meant to be merged)#345
sandyfzu wants to merge 4 commits into
developfrom
select-version-prototype

Conversation

@sandyfzu
Copy link
Copy Markdown
Member

@sandyfzu sandyfzu commented Mar 3, 2026

Description

Fixes #6 and #315

This code uses https://github.com/wp-media/automation-plugin-version-manager to build plugins from Git refs (tags, branches, and commits). The repo is written in safe Rust but exposed to NodeJS JavaScript/TypeScript through napi.rs leveraging Rust safety from NodeJS with all TypeScript types defined.

This is just a test. If this approach is approved, we can find a better way of writing the code. I just used a BeforeAll hook to build plugins there using some environment variables, but we can change this if we think of a better approach.

To test this, just try the following:

For WP Rocket:

E2E_WPR_PREV=v3.20.4 E2E_WPR_NEW=v3.20.5 npm run test:e2e

For BackWPup:

E2E_WPR_BACKWPUP=5.6.5 npm run test:bwpup

Passing existing Git tags to the environment variables.

For private repositories like BackWPup, the method createWithTokenResolution will attempt to resolve any git/github authentication in the environment (SSH keys, Github tokens, etc)

Recording: https://jmp.sh/Kr4DZQVl

Type of change

  • New feature (non-breaking change which adds functionality).
  • Bug fix (non-breaking change which fixes an issue).
  • Enhancement (non-breaking change which improves an existing functionality).
  • Breaking change (fix or feature that would cause existing functionality to not work as before).
  • Sub-task of #(issue number)
  • Chore
  • Release

Detailed scenario

What was tested

Plugin building before E2E test.

How to test

Pass any gitref to the environment variables (tags, branches, or commits), the tool will build the plugins from there:

For WP Rocket:

E2E_WPR_PREV=v3.20.4 E2E_WPR_NEW=v3.20.5 npm run test:e2e

For BackWPup:

E2E_WPR_BACKWPUP=5.6.5 npm run test:bwpup

Affected Features & Quality Assurance Scope

N/A

Technical description

Documentation

Used APVM in a BeforeAll hook.

New dependencies

    "apvm-napi": "github:wp-media/automation-plugin-version-manager",

Risks

N/A

Mandatory Checklist

Code validation

N/A

Code style

N/A

Unticked items justification

N/A

@sandyfzu sandyfzu requested review from a team March 3, 2026 15:52
@sandyfzu sandyfzu self-assigned this Mar 3, 2026
Copilot AI review requested due to automatic review settings March 3, 2026 15:52
@sandyfzu sandyfzu added the enhancement New feature or request label Mar 3, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces a prototype workflow to automatically build WP Rocket / BackWPup plugin ZIPs from Git refs at test startup (via APVM), so E2E runs can target specific versions without manually preparing plugin/*.zip files.

Changes:

  • Add a BeforeAll hook that builds plugin artifacts from env-provided git refs and writes them to the expected stable ZIP names in ./plugin/.
  • Add helper logic to build via apvm-napi and move the resulting artifact to a known path.
  • Add apvm-napi as a new dev dependency (with lockfile updates).

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.

File Description
src/support/hooks.ts Adds APVM-powered plugin build step in a global BeforeAll hook and a helper to move artifacts into plugin/ ZIP paths used by tests.
package.json Adds apvm-napi dependency to enable building plugins from Git refs during test runs.
package-lock.json Locks apvm-napi to a specific commit (currently via an SSH-resolved URL).

Comment thread src/support/hooks.ts
@Mai-Saad
Copy link
Copy Markdown
Contributor

Mai-Saad commented Apr 8, 2026

Comment thread src/support/hooks.ts
Comment on lines +93 to +204
/**
* Hook that runs before all tests to build the plugins specified by environment variables and store them in a known location for E2E tests.
* It uses APVM to build the plugins from specified git references and moves the resulting artifacts to stable zip paths.
* If no environment variables are set for plugin builds, it simply returns without performing any actions.
*/
BeforeAll(async function() {
const WORKSPACE_ROOT_DIR = process.env.PWD ?? process.cwd();
const PLUGIN_OUTPUT_DIR = `${WORKSPACE_ROOT_DIR}/plugin`;
const PREVIOUS_STABLE_PLUGIN_ZIP = `${PLUGIN_OUTPUT_DIR}/previous_stable.zip`;
const NEW_RELEASE_PLUGIN_ZIP = `${PLUGIN_OUTPUT_DIR}/new_release.zip`;
const BACKWPUP_PLUGIN_ZIP = `${PLUGIN_OUTPUT_DIR}/backwpup-pro.zip`;

const previousStableToBuild = process.env.E2E_WPR_PREV || null;
const newReleaseToBuild = process.env.E2E_WPR_NEW || null;
const backWPUpToBuild = process.env.E2E_WPR_BACKWPUP || null;

if (!previousStableToBuild && !newReleaseToBuild && !backWPUpToBuild) {
return;
}
// Apvm.createWithTokenResolution attempts to resolve github tokens in this environment to be able to access private repositories.
const apvm = await Apvm.createWithTokenResolution();

if (previousStableToBuild) {
await buildAndStorePluginArtifact({
apvm,
pluginName: 'WP Rocket previous stable',
targetPath: PREVIOUS_STABLE_PLUGIN_ZIP,
options: {
project: 'wp-rocket',
gitRef: previousStableToBuild,
outputDir: PLUGIN_OUTPUT_DIR
}
});
}

if (newReleaseToBuild) {
await buildAndStorePluginArtifact({
apvm,
pluginName: 'WP Rocket new release',
targetPath: NEW_RELEASE_PLUGIN_ZIP,
options: {
project: 'wp-rocket',
gitRef: newReleaseToBuild,
outputDir: PLUGIN_OUTPUT_DIR
}
});
}

if (backWPUpToBuild) {
await buildAndStorePluginArtifact({
apvm,
pluginName: 'BackWPUp',
targetPath: BACKWPUP_PLUGIN_ZIP,
options: {
project: 'backwpup',
gitRef: backWPUpToBuild,
outputDir: PLUGIN_OUTPUT_DIR,
variants: ['pro-en'],
version: '5.6.5'
}
});
}
});

interface BuildAndStorePluginArtifactArgs {
apvm: Apvm;
pluginName: string;
options: BuildOptions;
targetPath: string;
}

/**
* Builds a plugin artifact using APVM and moves it to a stable zip path used by E2E tests.
*
* @param {BuildAndStorePluginArtifactArgs} args - Build and output options.
* @return {Promise<void>}
*/
async function buildAndStorePluginArtifact({ apvm, pluginName, options, targetPath }: BuildAndStorePluginArtifactArgs): Promise<void> {
const gitRef = options.gitRef ?? 'unknown-ref';
console.log(`\nBuilding ${pluginName} plugin from: ${gitRef}\n`);
let hasPrintedStepProgress = false;

const reporter = (error: Error, event: JsBuildEvent): void => {
if (error) console.error(error);
if (event.type === 'step_completed') {
hasPrintedStepProgress = true;
process.stdout.write('.');
}
};

try {
const result = await apvm.build(options, reporter);

if (hasPrintedStepProgress) process.stdout.write('100%\n');
const firstArtifactPath = result.result.artifacts[0]?.path;

if (result.result.artifactCount < 1 || !firstArtifactPath) {
throw new Error(`No artifact path found in build result for "${pluginName}"`);
}

await access(firstArtifactPath);
// Remove existing artifact at target path if it exists, then move new artifact to target path
await nodeRm(targetPath, { force: true });
await nodeRename(firstArtifactPath, targetPath);
console.log(`\nSaved ${pluginName} build artifact to: ${targetPath}`);
} catch (error) {
if (hasPrintedStepProgress) process.stdout.write('\n');
const message = error instanceof Error ? error.message : String(error);
throw new Error(`Failed to build ${pluginName} plugin from '${gitRef}': ${message}`);
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a BeforeAll hook registered here already, I'll recommend we move the entire logic for version compilation to a separate file. Then we can import it here and use the exposed function/method in the already existing BeforeAll hook.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

As a QA engineer, I want the plugin versions to be automatically handled so that I can easily run tests on a selected version

4 participants