Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
ed89cc1
Add E2E smoke tests with @gravitykit/e2e-bootstrap
Mwalek Apr 2, 2026
4bff5fc
Run composer install in prepare job so vendor/ is available for E2E
Mwalek Apr 2, 2026
7f30e42
Fix activation spec: use descendant .deactivate selector to avoid str…
Mwalek Apr 2, 2026
4ea8358
Standardize command to run E2E tests
mrcasual Apr 2, 2026
0529ae6
Merge pull request #236 from GravityKit/feature/e2e-setup
mrcasual Apr 2, 2026
209d112
Update CI config to use gktools
Apr 14, 2026
458aede
Add a translations job to CI pipeline
mrcasual Apr 15, 2026
4112a5d
Update translations.pot [ci skip]
Apr 15, 2026
4a23ca2
Replace printf-style placeholders with named placeholders in JS-facin…
mrcasual Apr 15, 2026
e75307c
Update translations.pot [ci skip]
Apr 15, 2026
88d47bf
Add new translated languages
mrcasual Apr 16, 2026
cfa3155
CI: add sign step and guard replace-since to main
mrcasual Apr 17, 2026
f1faf0f
Fix E2E port mismatch: point Playwright at wpTestsPort
Mwalek May 11, 2026
798f870
Add E2E happy-path Playwright suite
Mwalek May 11, 2026
4f55546
Ignore playwright-transform-* cache dirs
Mwalek May 11, 2026
6ceaf4f
Make notification specs resilient to keep-alive connection drops
Mwalek May 11, 2026
05e1200
Make CI-resilient: bind-mount mail capture and harden form-settings w…
Mwalek May 11, 2026
e2f09bb
Bypass GF async notification queue in submitEntryTriggeringNotifications
Mwalek May 12, 2026
4019c7e
Address CodeRabbit review on PR #239
Mwalek May 12, 2026
dfd260a
CircleCI: stop wp-env and use sudo when cleaning up between retries
Mwalek May 12, 2026
11e672a
Merge pull request #239 from GravityKit/tests/happy-path
Mwalek May 12, 2026
ad3a446
Add post-build smoke E2E against built .zip artifact
Mwalek May 15, 2026
154e40c
Address CodeRabbit review on .circleci/config.yml
Mwalek May 15, 2026
9344b4d
Merge pull request #241 from GravityKit/tests/post-build-smoke
Mwalek May 15, 2026
69b5ccd
Fix copy button icon alignment on WordPress 7
mrcasual May 25, 2026
5d69aad
Persist signing sidecar so publish_release registers the signature
Mwalek May 27, 2026
172c165
Remove redundant gktools sign step
mrcasual May 27, 2026
4ed3df4
Remove docker_layer_caching from post-build smoke job
mrcasual May 27, 2026
1e83b74
Build download-URL action messages lazily, not in the constructor
mrcasual Jul 8, 2026
01a9d67
Report download-URL action outcomes via a typed ActionNotice
mrcasual Jul 8, 2026
7ee7e31
Update translations.pot [ci skip]
Jul 8, 2026
482da41
Read the notification attachment setting as a list of IDs
mrcasual Aug 5, 2026
5ece254
Bump version to 2.7.0 & update changelog
mrcasual Aug 6, 2026
cca889a
Restate the settings renderer and filter value types for PHPStan
mrcasual Aug 6, 2026
74a524f
Set the 2.7.0 stable tag and repair literal tokens in translations
mrcasual Aug 7, 2026
70f2aa8
Drop the .claude directory from the repository
mrcasual Aug 7, 2026
69b33ae
Fall back to the default export path when the filtered one is unwritable
mrcasual Aug 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 158 additions & 24 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,52 +9,186 @@ anchors:
machine:
image: default

test_job_config: &test_job_config
<<: *context
requires:
- prepare

jobs:
build_package_release:
prepare:
<<: *default_job_config
steps:
- checkout
- run:
name: Getting GravityKit test/build tools
name: Fetch tags
command: git fetch --tags
- run:
name: Create .npmrc
command: |
git clone git@github.com:GravityKit/Tooling.git /home/circleci/tooling
echo "//npm.pkg.github.com/:_authToken=${GH_AUTH_TOKEN}" >> ~/.npmrc
echo "@gravitykit:registry=https://npm.pkg.github.com" >> ~/.npmrc
- run:
name: Building and packaging
name: Install dependencies
command: |
/home/circleci/tooling/build-tools/build_tools.sh composer -o "build"
if [ "${CIRCLE_BRANCH}" != "main" ]; then
/home/circleci/tooling/build-tools/build_tools.sh package_build -o "gf-entries-in-excel gfexcel.php --include-hash"
else
/home/circleci/tooling/build-tools/build_tools.sh package_build -o "gf-entries-in-excel gfexcel.php $([[ $(git log -n 1 | grep "\[skip release\]") ]] && echo --include-hash)"
npx @gravitykit/gktools composer install
npx @gravitykit/gktools npm install
- run:
name: Configure E2E environment
command: |
npx @gravitykit/gktools gh release download -R gravityforms/gravityforms --clobber --pattern "*.zip" --dir .tmp
unzip .tmp/gravityforms*.zip -d .tmp
cp .env.sample .env
sed -i "s|WP_ENV_PLUGINS=.*|WP_ENV_PLUGINS=${PWD}/.tmp/gravityforms|" .env
sed -i "s|GRAVITY_FORMS_LICENSE_KEY=.*|GRAVITY_FORMS_LICENSE_KEY=${GRAVITYFORMS_KEY}|" .env
sed -i "s|GRAVITYKIT_LICENSE_KEY=.*|GRAVITYKIT_LICENSE_KEY=${GRAVITYVIEW_KEY}|" .env
- persist_to_workspace:
root: /home/circleci
paths:
- .
Comment thread
coderabbitai[bot] marked this conversation as resolved.

run_e2e_tests:
<<: *default_job_config
parallelism: 1
resource_class: xlarge
steps:
- attach_workspace:
at: /home/circleci
- run:
name: Run E2E tests
command: |
attempt=0
max_attempts=3
sleep_time=5
while [ $attempt -lt $max_attempts ]; do
npm run tests:e2e:setup && break
attempt=$(( attempt + 1 ))
# Apache inside the wp-env container creates the bind-mounted
# mu-plugin files (e2e-fixtures.php, e2e-mail-capture.php) as
# uid 0, so a plain `rm -rf` from the circleci user fails on
# them and every retry hits the same "permission denied"
# state. Stop the containers first, then clean up with sudo
# which is available on CircleCI Linux machine runners.
(cd tests/E2E/setup && npx wp-env stop 2>/dev/null) || true
sudo rm -rf /home/circleci/.wp-env
echo "Retrying WP-ENV setup in $sleep_time seconds… (attempt $attempt/$max_attempts)"
sleep $sleep_time
done
if [ $attempt -eq $max_attempts ]; then
echo "WP-ENV setup failed."
exit 1
fi
mkdir -p gf-entries-in-excel
cp -R build gf-entries-in-excel
rm -rf gf-entries-in-excel/build/composer.* gf-entries-in-excel/build/strauss.phar
zip -gr $(ls gf-entries-in-excel-*.zip) gf-entries-in-excel
zip -d $(ls gf-entries-in-excel-*.zip) "gf-entries-in-excel/src/*" "gf-entries-in-excel/assets/*"
mkdir .release
cp gf-entries-in-excel-*.zip .release
TESTFILES=$(circleci tests glob "tests/E2E/tests/**/*.spec.js")
echo "$TESTFILES" | circleci tests run --command="xargs npx playwright test --config=tests/E2E/setup/playwright.config.js" --verbose
- store_artifacts:
path: tests/E2E/results
- store_artifacts:
path: tests/E2E/report
- store_test_results:
path: tests/E2E/results/junit.xml

build_package_release:
<<: *default_job_config
steps:
- attach_workspace:
at: /home/circleci
- run:
name: Creating a GitHub release
name: Configure git
command: |
git config user.email "support@gravitykit.com"
git config user.name "GravityKit - CI"
- run:
name: Replace @since tags
command: |
if [ "${CIRCLE_BRANCH}" == "main" ]; then
git config user.email "support@gravitykit.com"
git config user.name "GravityKit - CI"
/home/circleci/tooling/build-tools/build_tools.sh create_release -o "gfexcel.php $(ls gf-entries-in-excel-*.zip)"
npx @gravitykit/gktools replace-since --commit
else
echo "Skipping @since tag replacement (only runs on main, before release build)."
fi
- run:
name: Notifying GravityKit Release Manager
name: Build and package
command: npx @gravitykit/gktools build
- run:
name: Trigger translation pipeline
command: |
if ! [[ $(git log -n 1 | grep "\[skip notify\]") ]]; then
/home/circleci/tooling/build-tools/build_tools.sh announce_build -o "gfexcel.php $(ls gf-entries-in-excel-*.zip) --with-circle"
if [ "${CIRCLE_BRANCH}" == "develop" ] || [ "${CIRCLE_BRANCH}" == "main" ]; then
npx @gravitykit/gktools translate gk-gravityexport-lite --commit --push
else
echo "Skipping translation pipeline."
fi
- run:
name: Collect build artifacts
command: |
mkdir -p .release
cp gf-entries-in-excel-*.zip .release/
- store_artifacts:
path: .release
destination: release
- persist_to_workspace:
root: /home/circleci
paths:
- plugin/.release
- plugin/gf-entries-in-excel-*.zip

run_post_build_smoke:
<<: *default_job_config
machine:
image: default
resource_class: xlarge
steps:
- attach_workspace:
at: /home/circleci
- run:
name: Post-build smoke
# Unzips .release/*.zip, restores dev deps via gktools' Docker composer,
# boots wp-env with retry, runs `playwright test --grep=@smoke` against
# the built artifact. See @gravitykit/e2e-bootstrap README for details.
command: |
npx @gravitykit/e2e-bootstrap smoke \
--composer-cmd "npx @gravitykit/gktools composer install"
- store_artifacts:
path: tests/E2E/results
- store_artifacts:
path: tests/E2E/report
- store_test_results:
path: tests/E2E/results/junit.xml

publish_release:
<<: *default_job_config
steps:
- attach_workspace:
at: /home/circleci
- run:
name: Configure git
command: |
git config user.email "support@gravitykit.com"
git config user.name "GravityKit - CI"
- run:
name: Create GitHub release
command: npx @gravitykit/gktools release
- run:
name: Announce build
command: |
if ! git log -1 --pretty=%B | grep -iq "\[skip notify\]"; then
npx @gravitykit/gktools announce
fi

workflows:
version: 2
test_and_package:
test_and_release:
jobs:
- prepare:
<<: *context
- run_e2e_tests:
<<: *test_job_config
- build_package_release:
<<: *context
requires:
- prepare
- run_post_build_smoke:
<<: *context
requires:
- build_package_release
- publish_release:
<<: *context
requires:
- run_post_build_smoke
Comment thread
mrcasual marked this conversation as resolved.
8 changes: 8 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
WP_ENV_PLUGINS=

GRAVITY_FORMS_LICENSE_KEY=
GRAVITYKIT_LICENSE_KEY=

# E2E_KEEP_DATA=0
# USE_LOCAL_BROWSER=0
# SLOW_MO=0
8 changes: 8 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,12 @@ phpstan-stubs export-ignore
/.github export-ignore
/.idea export-ignore
/assets export-ignore
/src export-ignore
/tests export-ignore
.env.sample export-ignore
Gruntfile.js export-ignore
package.json export-ignore
package-lock.json export-ignore
translations.pot export-ignore
.gktools.json export-ignore
.gktools.env export-ignore
17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,20 @@ vendor_prefixed
!build/strauss.phar
!build/vendor_prefixed/.gitkeep
phpstan.neon

# Environment
.env

# E2E Testing
tests/E2E/setup/.wp-env.json
tests/E2E/setup/.e2e-ports.json
tests/E2E/setup/.state.json
tests/E2E/results/
tests/E2E/report/
tests/E2E/setup/mail-capture/
.playwright-mcp/
playwright-transform-*
playwright_chromiumdev_profile-*

# Claude Code
.claude/
20 changes: 20 additions & 0 deletions .gktools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"build": [
"npm install",
"grunt",
"composer build"
],
"package": {
"prefix": "gf-entries-in-excel",
"includeExtra": ["build"],
"excludeFromExtra": [
"build/composer.json",
"build/composer.lock",
"build/strauss.phar"
]
},
"release": {
"branch": "main",
"mergeTo": "develop"
}
}
58 changes: 58 additions & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
module.exports = function ( grunt ) {
'use strict';

grunt.initConfig( {
addtextdomain: {
options: {
textdomain: 'gk-gravityexport-lite',
updateDomains: []
},
target: {
files: {
src: [
'*.php',
'src/**/*.php',
'!src/Addon/AddonHelperTrait.php',
'!src/Addon/GravityExportAddon.php',
'!src/Field/ProductField.php',
'!src/GravityForms/Field/DownloadFile.php',
'!src/Repository/FieldsRepository.php',
'public/**/*.php'
]
}
}
},

exec: {
makepot: {
cmd: function () {
var fileComments = [
'Copyright (C) ' + new Date().getFullYear() + ' GravityKit',
'This file is distributed under the GPLv2 or later',
];

var headers = {
'Last-Translator': 'GravityKit <support@gravitykit.com>',
'Language-Team': 'GravityKit <support@gravitykit.com>',
'Language': 'en_US',
'Plural-Forms': 'nplurals=2; plural=(n != 1);',
'Report-Msgid-Bugs-To': 'https://www.gravitykit.com/support',
};

var command = 'wp i18n make-pot --exclude=build,tests,vendor,assets . translations.pot';

command += ' --file-comment="' + fileComments.join( '\n' ) + '"';

command += ' --headers=\'' + JSON.stringify( headers ) + '\'';

return command;
}
}
}
} );

grunt.loadNpmTasks( 'grunt-exec' );
grunt.loadNpmTasks( 'grunt-wp-i18n' );

grunt.registerTask( 'default', [ 'addtextdomain', 'exec:makepot' ] );
};
9 changes: 7 additions & 2 deletions gfexcel.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
/**
* Plugin Name: GravityExport Lite
* Version: 2.6.0
* Version: 2.7.0
* Plugin URI: https://gfexcel.com
* Description: Export all Gravity Forms entries to Excel (.xlsx) or CSV via a secret shareable URL.
* Author: GravityKit
Expand All @@ -28,13 +28,18 @@
}

if ( ! defined( 'GFEXCEL_PLUGIN_VERSION' ) ) {
define( 'GFEXCEL_PLUGIN_VERSION', '2.6.0' );
define( 'GFEXCEL_PLUGIN_VERSION', '2.7.0' );
}

if ( ! defined( 'GFEXCEL_MIN_PHP_VERSION' ) ) {
define( 'GFEXCEL_MIN_PHP_VERSION', '7.2' );
}

if ( ! defined( 'GFEXCEL_ATTACHMENT_NOTIFICATIONS_API_VERSION' ) ) {
// Capability marker: attaching the single-entry export to multiple notifications is supported.
define( 'GFEXCEL_ATTACHMENT_NOTIFICATIONS_API_VERSION', 1 );
}

$src_folder = __DIR__ . '/build/vendor_prefixed/gravitykit/gravityexport-lite-src';
if ( ! is_readable( $src_folder ) ) {
$src_folder = __DIR__ . '/src';
Expand Down
Binary file added languages/gk-gravityexport-lite-ar.mo
Binary file not shown.
Loading
Loading