E2E: add activation smoke tests + license activation test#29
E2E: add activation smoke tests + license activation test#29
Conversation
Bootstrap-based E2E setup using @gravitykit/e2e-bootstrap: - generateWpEnvConfig / createPlaywrightConfig / createGlobalSetup / createGlobalTeardown - Standardized npm scripts (wp-env:start/stop/cli, tests:e2e:setup/run/debug) - wp-env:cli targets the dev `cli` container (not `tests-cli`) so the bootstrap's afterStart commands configure the same WP instance Playwright queries (see Tooling/.claude/e2e-bootstrap-migration.md, critical lesson #1) Activation smoke spec covers the four required checks: - Plugin activates without fatal PHP errors (via plugins.php Deactivate link) - WordPress admin dashboard loads cleanly - Gravity Forms admin page loads (exercises full plugin init path) - Product is listed as active on the GravityKit licenses page CircleCI restructured to add prepare_test_and_build_environment + run_e2e_tests jobs feeding into the existing build_package_release job, matching the GravityCharts pattern. Verified locally: cold-start tests:e2e:setup → tests:e2e:run → 4/4 passed.
WalkthroughRestructures CI into prepare → E2E → package jobs; adds Playwright + wp-env E2E setup and tests, new npm/dev dependencies and scripts, Changes
Sequence Diagram(s)sequenceDiagram
rect rgba(87, 156, 212, 0.5)
participant CircleCI
end
rect rgba(46, 204, 113, 0.5)
participant Workspace
end
rect rgba(241, 196, 15, 0.5)
participant Playwright
end
rect rgba(155, 89, 182, 0.5)
participant WP_Env
end
CircleCI->>Workspace: prepare_test_and_build_environment\n(create .npmrc, restore caches, install deps, download/unzip releases, generate .env, persist workspace)
Workspace-->>CircleCI: persisted workspace
CircleCI->>Workspace: run_e2e_tests (attach workspace)
loop up to 3 attempts
Workspace->>WP_Env: npm run tests:e2e:setup (generate wp-env files)
WP_Env-->>Workspace: wp-env config and environment
Workspace->>Playwright: run Playwright tests (tests/E2E/setup/playwright.config.js)
Playwright-->>Workspace: artifacts, junit results
Workspace->>Workspace: remove /home/circleci/.wp-env (between attempts if failed)
end
CircleCI->>Workspace: build_package_release (attach workspace)
Workspace->>Workspace: composer install --no-dev
Workspace-->>CircleCI: package artifacts
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (3)
package.json (1)
5-7: Move@gravitykit/e2e-bootstraptodevDependencies.This package is only used in E2E test setup files (
tests/E2E/setup/) and has no runtime usage. Keeping it independenciesincreases production installation surface without benefit.♻️ Proposed fix
- "dependencies": { - "@gravitykit/e2e-bootstrap": "^1.0.0" - }, + "dependencies": {}, "devDependencies": { + "@gravitykit/e2e-bootstrap": "^1.0.0", "@playwright/test": "1.56.1",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@package.json` around lines 5 - 7, Move the package "@gravitykit/e2e-bootstrap" from the "dependencies" block to the "devDependencies" block in package.json; update the JSON so "@gravitykit/e2e-bootstrap": "^1.0.0" appears under devDependencies (not dependencies) to ensure it's only installed for development/test environments and not included in production installs..circleci/config.yml (2)
61-64: Broad workspace persistence may include sensitive data.Persisting the entire home directory (
/home/circleci/.) includes the.envfile with license keys. While the workspace is internal to CircleCI, consider persisting only required paths to minimize exposure surface and reduce workspace size/transfer time.Suggested more targeted persistence
- persist_to_workspace: root: /home/circleci paths: - - . + - plugin + - tooling + - .npmrc🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.circleci/config.yml around lines 61 - 64, The current persist_to_workspace step is persisting the entire home directory (persist_to_workspace with root: /home/circleci and paths: - .), which can include sensitive files like .env; update this step to persist only the specific directories or files needed for downstream jobs (e.g., the repository workspace, build/artifact directories, and any generated caches) and explicitly exclude secrets (.env, SSH keys, license files). Replace the broad paths entry with a targeted list (only the exact folders used later in your workflow) or add an explicit exclusion mechanism, and ensure downstream jobs reference those specific paths instead of assuming the whole home directory is available.
22-22: Unused.datefile generated.The
.datefile is written but not referenced in any cache key or subsequent step. If this was intended for cache busting, it should be included in a cache key checksum; otherwise, this line can be removed.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.circleci/config.yml at line 22, The pipeline step that runs "date +%F > .date" is creating an unused artifact; either remove that run step entirely from the workflow or make the file serve a purpose by including ".date" in the cache key/checksum used by the cache step (so it affects cache busting). Locate the run step that writes ".date" in the CircleCI job and either delete that line or update the corresponding cache restore/save steps to reference ".date" in their key/checksum parameters.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.circleci/config.yml:
- Around line 96-97: The CircleCI job uses store_test_results with a file path;
change the value under store_test_results (the store_test_results key) to the
directory containing the results (e.g., "tests/E2E/results" or
"tests/E2E/results/") instead of "tests/E2E/results/junit.xml" so CircleCI can
collect all test result files.
In `@tests/E2E/setup/wp-env.config.js`:
- Line 5: Before calling loadEnv(path.resolve(__dirname, '../../../.env')) add
an explicit filesystem check (e.g., using fs.existsSync or fs.stat) to verify
the .env file exists; if it does not, log a clear error instructing the user to
copy .env.sample to .env (include the resolved path) and exit with a non-zero
status instead of allowing loadEnv to throw. Modify the setup in
tests/E2E/setup/wp-env.config.js around the loadEnv call so the existence check
runs first and only calls loadEnv when the file is present.
In `@tests/E2E/tests/activation.spec.js`:
- Around line 43-52: Guard the end-to-end test that checks GravityKit licenses
by skipping it when the license env var is not provided: wrap or modify the test
named "product is listed as active in GravityKit licenses" (the test(...) block
that defines productCard and assertions) to call Playwright's test.skip when
process.env.GRAVITYKIT_LICENSE_KEY (or equivalent GRAVITYKIT_LICENSE_KEY env) is
falsy, so local runs without a license key do not execute the license-specific
navigation and assertions.
---
Nitpick comments:
In @.circleci/config.yml:
- Around line 61-64: The current persist_to_workspace step is persisting the
entire home directory (persist_to_workspace with root: /home/circleci and paths:
- .), which can include sensitive files like .env; update this step to persist
only the specific directories or files needed for downstream jobs (e.g., the
repository workspace, build/artifact directories, and any generated caches) and
explicitly exclude secrets (.env, SSH keys, license files). Replace the broad
paths entry with a targeted list (only the exact folders used later in your
workflow) or add an explicit exclusion mechanism, and ensure downstream jobs
reference those specific paths instead of assuming the whole home directory is
available.
- Line 22: The pipeline step that runs "date +%F > .date" is creating an unused
artifact; either remove that run step entirely from the workflow or make the
file serve a purpose by including ".date" in the cache key/checksum used by the
cache step (so it affects cache busting). Locate the run step that writes
".date" in the CircleCI job and either delete that line or update the
corresponding cache restore/save steps to reference ".date" in their
key/checksum parameters.
In `@package.json`:
- Around line 5-7: Move the package "@gravitykit/e2e-bootstrap" from the
"dependencies" block to the "devDependencies" block in package.json; update the
JSON so "@gravitykit/e2e-bootstrap": "^1.0.0" appears under devDependencies (not
dependencies) to ensure it's only installed for development/test environments
and not included in production installs.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: dbe23ec8-7f27-44a3-9de2-abde74506bd9
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (9)
.circleci/config.yml.env.sample.gitignorepackage.jsontests/E2E/setup/playwright.config.jstests/E2E/setup/playwright.global.setup.jstests/E2E/setup/playwright.global.teardown.jstests/E2E/setup/wp-env.config.jstests/E2E/tests/activation.spec.js
| - store_test_results: | ||
| path: tests/E2E/results/junit.xml |
There was a problem hiding this comment.
store_test_results expects a directory path, not a file.
CircleCI's store_test_results requires a directory containing test result files, not a direct file path. The current path tests/E2E/results/junit.xml should be changed to the directory.
Proposed fix
- store_test_results:
- path: tests/E2E/results/junit.xml
+ path: tests/E2E/results🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.circleci/config.yml around lines 96 - 97, The CircleCI job uses
store_test_results with a file path; change the value under store_test_results
(the store_test_results key) to the directory containing the results (e.g.,
"tests/E2E/results" or "tests/E2E/results/") instead of
"tests/E2E/results/junit.xml" so CircleCI can collect all test result files.
| const { generateWpEnvConfig, loadEnv } = require('@gravitykit/e2e-bootstrap'); | ||
|
|
||
| // Explicit load — INIT_CWD unreliable via npm run on some machines (see Tooling/.claude/e2e-bootstrap-migration.md) | ||
| loadEnv(path.resolve(__dirname, '../../../.env')); |
There was a problem hiding this comment.
Add explicit .env existence validation before loading.
Line 5 unconditionally loads .env; on fresh clones this can fail with a non-actionable stack trace. Add a clear precheck and message to copy from .env.sample.
🛠️ Proposed fix
const path = require('path');
+const fs = require('fs');
const { generateWpEnvConfig, loadEnv } = require('@gravitykit/e2e-bootstrap');
// Explicit load — INIT_CWD unreliable via npm run on some machines (see Tooling/.claude/e2e-bootstrap-migration.md)
-loadEnv(path.resolve(__dirname, '../../../.env'));
+const envPath = path.resolve(__dirname, '../../../.env');
+if (!fs.existsSync(envPath)) {
+ console.error('Missing .env file. Copy .env.sample to .env and set required keys.');
+ process.exit(1);
+}
+loadEnv(envPath);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tests/E2E/setup/wp-env.config.js` at line 5, Before calling
loadEnv(path.resolve(__dirname, '../../../.env')) add an explicit filesystem
check (e.g., using fs.existsSync or fs.stat) to verify the .env file exists; if
it does not, log a clear error instructing the user to copy .env.sample to .env
(include the resolved path) and exit with a non-zero status instead of allowing
loadEnv to throw. Modify the setup in tests/E2E/setup/wp-env.config.js around
the loadEnv call so the existence check runs first and only calls loadEnv when
the file is present.
| test('product is listed as active in GravityKit licenses', async ({ page }) => { | ||
| await page.goto('/wp-admin/admin.php?page=gk_licenses&filter=active'); | ||
|
|
||
| const productCard = page.locator('.sections .grid > div').filter({ | ||
| has: page.locator('h3', { hasText: 'Dashboard Views' }), | ||
| }); | ||
|
|
||
| await expect(productCard).toBeVisible(); | ||
| await expect(productCard.locator('button[role="switch"][aria-checked="true"]')).toBeVisible(); | ||
| }); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify current license-test gating and env-key usage in E2E tests.
rg -n -C3 "GRAVITYKIT_LICENSE_KEY|gk_licenses|test\\.skip" tests/E2ERepository: GravityKit/Dashboard-Views
Length of output: 626
🏁 Script executed:
# Read the full activation.spec.js file
cat -n tests/E2E/tests/activation.spec.jsRepository: GravityKit/Dashboard-Views
Length of output: 2440
🏁 Script executed:
# Check .env.sample to see default license config
cat -n .env.sample 2>/dev/null || cat -n .env.example 2>/dev/null || echo "No env sample found"Repository: GravityKit/Dashboard-Views
Length of output: 677
🏁 Script executed:
# Search for any existing skip logic or license checks in E2E tests
rg -n "test\.skip|testInfo\.skip|\.skip\(" tests/E2E --type javascriptRepository: GravityKit/Dashboard-Views
Length of output: 104
🏁 Script executed:
# Search for env variable usage in E2E tests
rg -n "process\.env" tests/E2E --type javascriptRepository: GravityKit/Dashboard-Views
Length of output: 104
🏁 Script executed:
# Search for test setup, hooks, or beforeAll/beforeEach in E2E tests
rg -n "beforeAll|beforeEach|test\.describe|skip" tests/E2E/tests/Repository: GravityKit/Dashboard-Views
Length of output: 171
🏁 Script executed:
# Search for any other tests that might check license availability
rg -n "gk_licenses" --type js .Repository: GravityKit/Dashboard-Views
Length of output: 182
🏁 Script executed:
# Check if there's a setup file or config for E2E tests
find tests/E2E -name "*.config.*" -o -name "setup*" -o -name "fixtures*" | head -20Repository: GravityKit/Dashboard-Views
Length of output: 155
🏁 Script executed:
# Search entire codebase for GRAVITYKIT_LICENSE_KEY to understand how it's used
rg -n "GRAVITYKIT_LICENSE_KEY" --type js .Repository: GravityKit/Dashboard-Views
Length of output: 52
🏁 Script executed:
# Check playwright config
cat -n tests/E2E/setup/playwright.config.jsRepository: GravityKit/Dashboard-Views
Length of output: 251
🏁 Script executed:
# Check wp-env config to understand test environment
cat -n tests/E2E/setup/wp-env.config.js | head -50Repository: GravityKit/Dashboard-Views
Length of output: 665
🌐 Web query:
Playwright test.skip() API correct syntax
💡 Result:
Playwright test.skip() syntax (Playwright Test)
1) Declare a skipped test (never runs)
import { test } from '@playwright/test';
test.skip('never run', async ({ page }) => {
// ...
});Also supported:
test.skip(title, details, body);[1]
2) Skip at runtime (conditional) inside a test (or hook)
test('example', async ({ browserName }) => {
test.skip(browserName === 'webkit', 'Not supported in WebKit');
// ... rest of test won't run if condition is true
});Supported forms:
test.skip(condition, description);
test.skip(callback, description); // for file/describe-wide conditional skipping
test.skip(); // unconditionally skip all tests in a file or describe block[1]
3) Skip an entire file (all tests in the file)
import { test } from '@playwright/test';
test.skip(); // applies to the whole file
test('a', async () => {});
test('b', async () => {});[1]
Note: test.skip() marks a test as skipped (not run). If you intend to come back and fix it, Playwright suggests test.fixme() instead. [1][2]
Guard the license-specific test when license env is not configured.
This test navigates to the GravityKit licenses admin page, which requires a valid license key. With the default empty GRAVITYKIT_LICENSE_KEY in .env.sample, the test will fail even when core activation checks pass. Add a skip guard to prevent failures in local smoke runs without license secrets.
Proposed fix
test('product is listed as active in GravityKit licenses', async ({ page }) => {
+ test.skip(!process.env.GRAVITYKIT_LICENSE_KEY, 'GRAVITYKIT_LICENSE_KEY is not configured');
+
await page.goto('/wp-admin/admin.php?page=gk_licenses&filter=active');📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| test('product is listed as active in GravityKit licenses', async ({ page }) => { | |
| await page.goto('/wp-admin/admin.php?page=gk_licenses&filter=active'); | |
| const productCard = page.locator('.sections .grid > div').filter({ | |
| has: page.locator('h3', { hasText: 'Dashboard Views' }), | |
| }); | |
| await expect(productCard).toBeVisible(); | |
| await expect(productCard.locator('button[role="switch"][aria-checked="true"]')).toBeVisible(); | |
| }); | |
| test('product is listed as active in GravityKit licenses', async ({ page }) => { | |
| test.skip(!process.env.GRAVITYKIT_LICENSE_KEY, 'GRAVITYKIT_LICENSE_KEY is not configured'); | |
| await page.goto('/wp-admin/admin.php?page=gk_licenses&filter=active'); | |
| const productCard = page.locator('.sections .grid > div').filter({ | |
| has: page.locator('h3', { hasText: 'Dashboard Views' }), | |
| }); | |
| await expect(productCard).toBeVisible(); | |
| await expect(productCard.locator('button[role="switch"][aria-checked="true"]')).toBeVisible(); | |
| }); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tests/E2E/tests/activation.spec.js` around lines 43 - 52, Guard the
end-to-end test that checks GravityKit licenses by skipping it when the license
env var is not provided: wrap or modify the test named "product is listed as
active in GravityKit licenses" (the test(...) block that defines productCard and
assertions) to call Playwright's test.skip when
process.env.GRAVITYKIT_LICENSE_KEY (or equivalent GRAVITYKIT_LICENSE_KEY env) is
falsy, so local runs without a license key do not execute the license-specific
navigation and assertions.
Dashboard Views registers GravityKit Foundation inside the `gravityview/loaded` action, so when GravityView is not active the Foundation admin pages (including /wp-admin/admin.php?page=gk_licenses) are never registered. The license activation smoke test then navigates to that URL and gets "Sorry, you are not allowed to access this page". Mirror the existing GravityForms download in the prepare step to also fetch the latest GravityView release and add it to WP_ENV_PLUGINS so the hook fires and Foundation registers the licenses page.
There was a problem hiding this comment.
♻️ Duplicate comments (1)
.circleci/config.yml (1)
102-103:⚠️ Potential issue | 🟡 Minor
store_test_resultsexpects a directory path, not a file.CircleCI's
store_test_resultsrequires a directory containing test result files, not a direct file path.Proposed fix
- store_test_results: - path: tests/E2E/results/junit.xml + path: tests/E2E/results🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.circleci/config.yml around lines 102 - 103, The CircleCI step uses store_test_results with a file path; change it to point at the directory containing test results instead (replace the path value used with the directory that contains tests/E2E/results/junit.xml, e.g. tests/E2E/results or the proper results folder), so update the store_test_results entry (symbol: store_test_results and its path field) to reference the directory rather than the file.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In @.circleci/config.yml:
- Around line 102-103: The CircleCI step uses store_test_results with a file
path; change it to point at the directory containing test results instead
(replace the path value used with the directory that contains
tests/E2E/results/junit.xml, e.g. tests/E2E/results or the proper results
folder), so update the store_test_results entry (symbol: store_test_results and
its path field) to reference the directory rather than the file.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: cb07966a-5952-427b-981c-1b1a27a95bde
📒 Files selected for processing (1)
.circleci/config.yml
…ing failure `package_build` makes a git commit during the packaging step. That triggers .husky/pre-commit → `npx lint-staged` → `vendor/bin/phpcs`. Because the preceding `composer install --no-dev` strips phpcs (it is a dev dependency), the hook fails with `ENOENT` and the job dies before producing any output. This is a long-standing develop bug — the husky hook was added in `31290ed Add code sniffer & fix all issues` (Jan 2024) and CI was first configured in `9ffa680 Configure CI` (May 2024). The two have been incompatible ever since: every CircleCI run on develop has failed in the packaging step. It went unnoticed because the failure surfaces at the very end of the only job in the pipeline and nobody was gating on it. The new workflow now requires `build_package_release` to succeed downstream of `run_e2e_tests`, so we have to fix it. Setting `HUSKY=0` is the standard escape hatch documented by husky for disabling hooks in non-interactive environments. It scopes the change to CI only — local pre-commit hooks continue to work for developers.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.circleci/config.yml:
- Around line 28-31: The persist_to_workspace configuration currently uses
paths: - . which attempts to persist the workspace root and leaks secrets and
temp files; update the persist_to_workspace entries (the workspace persistence
steps) to remove paths: - . and instead list only the needed directories (e.g.,
plugin and tooling) so only those folders are passed between jobs, and move
creation of the E2E-specific .env (currently created earlier alongside the
Create .npmrc step) into the run_e2e_tests job so the auth token/.env are not
persisted; ensure all workspace persistence blocks (the ones that currently
include '.') are updated consistently and that run_e2e_tests generates the .env
before using it.
- Around line 47-53: The GH release download commands for GravityForms and
GravityView currently omit explicit tags, causing them to fetch the latest
release and drift; update the two invocations of build_tools.sh (the commands
that call "gh -o 'release download -R gravityforms/gravityforms ...'" and "gh -o
'release download -R GravityKit/GravityView ...'") to include explicit release
tags/versions (e.g., use shell variables like GF_TAG/GV_TAG or hardcoded tags)
passed into the 'release download -R ... --clobber --pattern ... --dir ...'
arguments so the E2E job consistently downloads pinned artifact versions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 3372a048-27d2-416f-8829-330bf5bc7b69
📒 Files selected for processing (1)
.circleci/config.yml
| name: Create .npmrc | ||
| command: | | ||
| echo "//npm.pkg.github.com/:_authToken=${GH_AUTH_TOKEN}" >> ~/.npmrc | ||
| echo "@gravitykit:registry=https://npm.pkg.github.com" >> ~/.npmrc |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
git ls-files | grep -E "\.circleci|circleci"Repository: GravityKit/Dashboard-Views
Length of output: 90
🏁 Script executed:
cat -n .circleci/config.yml | head -100Repository: GravityKit/Dashboard-Views
Length of output: 4772
🌐 Web query:
CircleCI persist_to_workspace paths root configuration documentation
💡 Result:
In CircleCI config, persist_to_workspace has two required keys:
root: a directory on the container that becomes the workspace root for this step. It can be an absolute path or relative toworking_directory. [1]paths: a list of files/globs or directories to upload, interpreted relative toroot(the workspace root). It must not be the workspace root itself (sopaths: ['.']is invalid ifrootis.). Patterns use Go’sfilepath.Matchglobbing rules. [1]
Minimal example (persist one file created under workspace/):
- persist_to_workspace:
root: workspace
paths:
- echo-outputA downstream job then downloads the entire workspace and copies it into the directory you choose via attach_workspace:
- attach_workspace:
at: /tmp/workspaceSo the file above becomes available at /tmp/workspace/echo-output. [2]
Sources: CircleCI configuration reference (persist_to_workspace, attach_workspace) [1]; CircleCI “Using workspaces to share data between jobs” guide (end-to-end example) [2].
🏁 Script executed:
cat -n .circleci/config.yml | tail -50Repository: GravityKit/Dashboard-Views
Length of output: 2668
🏁 Script executed:
# Check for any other setup that creates files in /home/circleci root
rg "home/circleci|~/" .circleci/config.yml -A 2 -B 2Repository: GravityKit/Dashboard-Views
Length of output: 3975
Remove paths: - . from persist_to_workspace as it violates CircleCI's documented constraint.
CircleCI's configuration reference explicitly states that persist_to_workspace.paths must not reference the workspace root itself. With root: /home/circleci and paths: - ., the configuration attempts to persist the root directory, which is unsupported and will fail.
Beyond the constraint violation, this persists unintended files: the .npmrc file containing the auth token, the .env file with license keys, temporary .tmp artifacts, and other temporary state. Persist only the directories needed downstream (plugin and tooling), and generate the E2E-specific .env inside run_e2e_tests instead.
Suggested change
- persist_to_workspace:
root: /home/circleci
paths:
- - .
+ - plugin
+ - toolingAlso applies to: 54-57 (move .env creation to run_e2e_tests), 67-70 (workspace paths)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.circleci/config.yml around lines 28 - 31, The persist_to_workspace
configuration currently uses paths: - . which attempts to persist the workspace
root and leaks secrets and temp files; update the persist_to_workspace entries
(the workspace persistence steps) to remove paths: - . and instead list only the
needed directories (e.g., plugin and tooling) so only those folders are passed
between jobs, and move creation of the E2E-specific .env (currently created
earlier alongside the Create .npmrc step) into the run_e2e_tests job so the auth
token/.env are not persisted; ensure all workspace persistence blocks (the ones
that currently include '.') are updated consistently and that run_e2e_tests
generates the .env before using it.
| /home/circleci/tooling/build-tools/build_tools.sh gh -o 'release download -R gravityforms/gravityforms --clobber --pattern "*.zip" --dir .tmp' | ||
| unzip .tmp/gravityforms*.zip -d .tmp | ||
| # GravityView — Dashboard Views hooks into `gravityview/loaded` to register Foundation, | ||
| # so without GravityView active the GK licenses admin page is never registered and the | ||
| # license activation smoke test cannot find the product card. | ||
| /home/circleci/tooling/build-tools/build_tools.sh gh -o 'release download -R GravityKit/GravityView --clobber --pattern "gravityview-*.zip" --dir .tmp' | ||
| unzip .tmp/gravityview-*.zip -d .tmp |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's look at the .circleci/config.yml file and the specific lines mentioned
cat -n .circleci/config.yml | sed -n '40,60p'Repository: GravityKit/Dashboard-Views
Length of output: 1701
🏁 Script executed:
# Also check the broader context around those lines
cat -n .circleci/config.yml | sed -n '1,70p'Repository: GravityKit/Dashboard-Views
Length of output: 3497
🌐 Web query:
gh release download default version no tag specified cli.github.com
💡 Result:
With gh release download, the positional argument is the release tag. If you don’t specify a tag, GitHub CLI targets the repo’s latest release, but it requires you to also provide either --pattern or --archive. [1]
Examples:
- Download a specific asset (or assets) from the latest release:
gh release download --pattern '*.deb'This works because omitting <tag> means “latest release”. [1]
- Download the source archive for the latest release:
gh release download --archive=zip[1]
- Download all assets from the latest release (by first resolving the latest tag, then downloading by tag):
tag="$(gh release view --json tagName --jq .tagName)"
gh release download "$tag"gh release view shows the latest release when no tag is provided, and tagName is available via --json. [2]
Sources:
[1] gh release download manual (GitHub CLI)
[2] gh release view manual (GitHub CLI)
🏁 Script executed:
# Search for GRAVITYFORMS_RELEASE and GRAVITYVIEW_RELEASE in the config
rg 'GRAVITYFORMS_RELEASE|GRAVITYVIEW_RELEASE' .circleci/config.ymlRepository: GravityKit/Dashboard-Views
Length of output: 52
🏁 Script executed:
# Check if there are any environment variable definitions in the config
grep -n "env:" .circleci/config.yml | head -20Repository: GravityKit/Dashboard-Views
Length of output: 52
🏁 Script executed:
# Look for any variables section or environment setup
cat -n .circleci/config.yml | grep -A 5 -B 5 "variables:\|environment:"Repository: GravityKit/Dashboard-Views
Length of output: 1258
🏁 Script executed:
# Search the entire repo for GRAVITYFORMS_RELEASE or GRAVITYVIEW_RELEASE
rg 'GRAVITYFORMS_RELEASE|GRAVITYVIEW_RELEASE' --type yml --type yaml --type mdRepository: GravityKit/Dashboard-Views
Length of output: 97
🏁 Script executed:
# Check the README or any documentation for E2E setup
find . -maxdepth 2 -name "README*" -o -name "*.md" | head -10Repository: GravityKit/Dashboard-Views
Length of output: 81
🏁 Script executed:
# Search more broadly for these variables
rg 'GRAVITYFORMS_RELEASE|GRAVITYVIEW_RELEASE'Repository: GravityKit/Dashboard-Views
Length of output: 52
🏁 Script executed:
# Check the README for E2E setup instructions
cat readme.md | grep -A 10 -B 5 -i "gravityforms\|gravityview\|e2e\|release"Repository: GravityKit/Dashboard-Views
Length of output: 1106
🏁 Script executed:
# Check if there's a .env.sample mentioned in config
cat -n .env.sample 2>/dev/null | head -30Repository: GravityKit/Dashboard-Views
Length of output: 677
🏁 Script executed:
# Check CircleCI documentation/scripts to see if there's any release pinning mechanism
find . -name "*.sh" -o -name "*circleci*" | head -20Repository: GravityKit/Dashboard-Views
Length of output: 81
🏁 Script executed:
# Look for any other CircleCI configuration files that might define variables
find . -path "./.circleci*" -type fRepository: GravityKit/Dashboard-Views
Length of output: 92
🌐 Web query:
gh release download tag syntax --pattern example
💡 Result:
gh release download syntax:
- With an explicit tag:
gh release download <tag> [--pattern <glob> ...] - Without a tag (downloads “latest” release): you must pass either
--patternor--archive. [1]
--pattern takes glob patterns (you can repeat it):
# Download all assets from tag v1.2.3
gh release download v1.2.3# Download only matching assets from the latest release
gh release download --pattern '*.deb'# Multiple patterns
gh release download -p '*.deb' -p '*.rpm'# Filter assets from a specific tag
gh release download v1.2.3 --pattern '*linux*amd64*.tar.gz'[1]
Pin the upstream plugin releases used by E2E.
gh release download pulls assets from the latest release when no tag is provided. These two downloads will drift as GravityForms or GravityView publish new releases, so the smoke suite can start failing on unrelated upstream changes and become hard to reproduce. Pass explicit release tags/versions into both commands instead of relying on "latest."
Suggested change
+ : "${GRAVITYFORMS_RELEASE:?Missing GRAVITYFORMS_RELEASE}"
+ : "${GRAVITYVIEW_RELEASE:?Missing GRAVITYVIEW_RELEASE}"
- /home/circleci/tooling/build-tools/build_tools.sh gh -o 'release download -R gravityforms/gravityforms --clobber --pattern "*.zip" --dir .tmp'
+ /home/circleci/tooling/build-tools/build_tools.sh gh -o "release download ${GRAVITYFORMS_RELEASE} -R gravityforms/gravityforms --clobber --pattern '*.zip' --dir .tmp"
unzip .tmp/gravityforms*.zip -d .tmp
- /home/circleci/tooling/build-tools/build_tools.sh gh -o 'release download -R GravityKit/GravityView --clobber --pattern "gravityview-*.zip" --dir .tmp'
+ /home/circleci/tooling/build-tools/build_tools.sh gh -o "release download ${GRAVITYVIEW_RELEASE} -R GravityKit/GravityView --clobber --pattern 'gravityview-*.zip' --dir .tmp"
unzip .tmp/gravityview-*.zip -d .tmp📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /home/circleci/tooling/build-tools/build_tools.sh gh -o 'release download -R gravityforms/gravityforms --clobber --pattern "*.zip" --dir .tmp' | |
| unzip .tmp/gravityforms*.zip -d .tmp | |
| # GravityView — Dashboard Views hooks into `gravityview/loaded` to register Foundation, | |
| # so without GravityView active the GK licenses admin page is never registered and the | |
| # license activation smoke test cannot find the product card. | |
| /home/circleci/tooling/build-tools/build_tools.sh gh -o 'release download -R GravityKit/GravityView --clobber --pattern "gravityview-*.zip" --dir .tmp' | |
| unzip .tmp/gravityview-*.zip -d .tmp | |
| : "${GRAVITYFORMS_RELEASE:?Missing GRAVITYFORMS_RELEASE}" | |
| : "${GRAVITYVIEW_RELEASE:?Missing GRAVITYVIEW_RELEASE}" | |
| /home/circleci/tooling/build-tools/build_tools.sh gh -o "release download ${GRAVITYFORMS_RELEASE} -R gravityforms/gravityforms --clobber --pattern '*.zip' --dir .tmp" | |
| unzip .tmp/gravityforms*.zip -d .tmp | |
| # GravityView — Dashboard Views hooks into `gravityview/loaded` to register Foundation, | |
| # so without GravityView active the GK licenses admin page is never registered and the | |
| # license activation smoke test cannot find the product card. | |
| /home/circleci/tooling/build-tools/build_tools.sh gh -o "release download ${GRAVITYVIEW_RELEASE} -R GravityKit/GravityView --clobber --pattern 'gravityview-*.zip' --dir .tmp" | |
| unzip .tmp/gravityview-*.zip -d .tmp |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.circleci/config.yml around lines 47 - 53, The GH release download commands
for GravityForms and GravityView currently omit explicit tags, causing them to
fetch the latest release and drift; update the two invocations of build_tools.sh
(the commands that call "gh -o 'release download -R gravityforms/gravityforms
...'" and "gh -o 'release download -R GravityKit/GravityView ...'") to include
explicit release tags/versions (e.g., use shell variables like GF_TAG/GV_TAG or
hardcoded tags) passed into the 'release download -R ... --clobber --pattern ...
--dir ...' arguments so the E2E job consistently downloads pinned artifact
versions.
Clicks the GravityView deactivate link on the plugins page and asserts that a browser dialog containing "GravityView is required by" is shown. Accepts the dialog, then re-activates GravityView so subsequent tests are unaffected.
Summary
First-time E2E setup for Dashboard Views using
@gravitykit/e2e-bootstrap.generateWpEnvConfig,createPlaywrightConfig,createGlobalSetup,createGlobalTeardown)wp-env:start/stop/cli,tests:e2e:setup/run/debug)wp-env:clitargets the devclicontainer so the bootstrap'safterStartcommands (rewrite, plugin install, license activation) configure the same WP instance Playwright queries — see the bootstrap migration plan, critical lesson Links all don't work #1prepare_test_and_build_environment+run_e2e_testsjobs feeding into the existingbuild_package_releasejob.env.sampletemplate,.gitignoreentries for generated wp-env / playwright artifactsTest plan
npm run tests:e2e:setup→ no afterStart errorsnpm run tests:e2e:run→ 4/4 passedprepare_test_and_build_environmentpassesrun_e2e_testspasses (all 4 activation tests)build_package_releasestill passesSummary by CodeRabbit
💾 Build file (2103899).