Skip to content

Commit e6f631b

Browse files
Tsvetan StoychevTsvetan Stoychev
authored andcommitted
Add resilient release artifact testing
1 parent b9f4a9d commit e6f631b

17 files changed

Lines changed: 566 additions & 64 deletions

‎.github/workflows/ci.yml‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,42 @@ jobs:
123123
env:
124124
WP_TESTS_DIR: /tmp/wordpress-tests-lib
125125
run: ./vendor/bin/phpunit --configuration phpunit-with-integration.xml
126+
127+
release-artifact:
128+
name: Release ZIP smoke test
129+
runs-on: ubuntu-latest
130+
needs:
131+
- translations
132+
- unit
133+
- integration
134+
135+
steps:
136+
- name: Checkout
137+
uses: actions/checkout@v5
138+
139+
- name: Setup release PHP
140+
uses: shivammathur/setup-php@v2
141+
with:
142+
php-version: '7.4'
143+
tools: composer:v2
144+
coverage: none
145+
146+
- name: Install release tools
147+
run: |
148+
sudo apt-get update
149+
sudo apt-get install -y rsync zip unzip
150+
151+
- name: Build and inspect release artifact
152+
run: sh tools/build-release.sh
153+
154+
- name: Install and test packaged plugin
155+
run: sh tools/smoke-test-release.sh release/basicrum.zip
156+
157+
- name: Upload release artifact
158+
uses: actions/upload-artifact@v4
159+
with:
160+
name: basicrum-release
161+
path: |
162+
release/basicrum.zip
163+
release/basicrum.zip.sha256
164+
if-no-files-found: error

‎.github/workflows/prerelease.yml‎

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,27 @@ jobs:
1313
- name: Checkout
1414
uses: actions/checkout@v5
1515

16-
- name: Setup PHP
16+
- name: Setup release PHP
1717
uses: shivammathur/setup-php@v2
1818
with:
1919
php-version: '7.4'
2020
tools: composer:v2
2121
coverage: none
2222

23-
- name: Install runtime dependencies
24-
working-directory: plugins/basicrum
25-
run: composer install --no-dev --no-interaction --prefer-dist
26-
27-
- name: Generate plugin artifact
23+
- name: Install release tools
2824
run: |
29-
set -e
3025
sudo apt-get update
31-
sudo apt-get install -y rsync zip
26+
sudo apt-get install -y rsync zip unzip
3227
33-
mkdir -p release/basicrum
34-
rsync -rc --exclude-from="$GITHUB_WORKSPACE/plugins/basicrum/.distignore" "$GITHUB_WORKSPACE/plugins/basicrum/" release/basicrum/ --delete --delete-excluded
28+
- name: Build and inspect release artifact
29+
run: sh tools/build-release.sh
3530

36-
cd "$GITHUB_WORKSPACE/release"
37-
zip -r "$GITHUB_WORKSPACE/basicrum.zip" basicrum
31+
- name: Install and test packaged plugin
32+
run: sh tools/smoke-test-release.sh release/basicrum.zip
3833

39-
- name: Upload release asset
34+
- name: Upload release assets
4035
uses: softprops/action-gh-release@v2
4136
with:
42-
files: basicrum.zip
37+
files: |
38+
release/basicrum.zip
39+
release/basicrum.zip.sha256

‎.github/workflows/release.yml‎

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,27 @@ jobs:
1313
- name: Checkout
1414
uses: actions/checkout@v5
1515

16-
- name: Setup PHP
16+
- name: Setup release PHP
1717
uses: shivammathur/setup-php@v2
1818
with:
1919
php-version: '7.4'
2020
tools: composer:v2
2121
coverage: none
2222

23-
- name: Install runtime dependencies
24-
working-directory: plugins/basicrum
25-
run: composer install --no-dev --no-interaction --prefer-dist
26-
27-
- name: Generate plugin artifact
23+
- name: Install release tools
2824
run: |
29-
set -e
3025
sudo apt-get update
31-
sudo apt-get install -y rsync zip
26+
sudo apt-get install -y rsync zip unzip
3227
33-
mkdir -p release/basicrum
34-
rsync -rc --exclude-from="$GITHUB_WORKSPACE/plugins/basicrum/.distignore" "$GITHUB_WORKSPACE/plugins/basicrum/" release/basicrum/ --delete --delete-excluded
28+
- name: Build and inspect release artifact
29+
run: sh tools/build-release.sh
3530

36-
cd "$GITHUB_WORKSPACE/release"
37-
zip -r "$GITHUB_WORKSPACE/basicrum.zip" basicrum
31+
- name: Install and test packaged plugin
32+
run: sh tools/smoke-test-release.sh release/basicrum.zip
3833

39-
- name: Upload release asset
34+
- name: Upload release assets
4035
uses: softprops/action-gh-release@v2
4136
with:
42-
files: basicrum.zip
37+
files: |
38+
release/basicrum.zip
39+
release/basicrum.zip.sha256

‎Makefile‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ TEST_DB_PASS = root
1212
TEST_DB_HOST = db
1313
WP_TEST_VERSION ?= latest
1414

15-
.PHONY: help build up down restart logs shell composer-install wp-install lint lint-fix lint-php translations integration-setup integration test package clean
15+
.PHONY: help build up down restart logs shell composer-install wp-install lint lint-fix lint-php translations integration-setup integration test package package-verify package-smoke clean
1616

1717
help:
1818
@echo "Targets:"
@@ -32,7 +32,9 @@ help:
3232
@echo " integration-setup Install WordPress test suite inside containers"
3333
@echo " integration Run integration tests"
3434
@echo " test Run unit and integration tests"
35-
@echo " package Build release zip via prerelease workflow logic"
35+
@echo " package Build and inspect the release ZIP and checksum"
36+
@echo " package-verify Inspect the existing release ZIP and checksum"
37+
@echo " package-smoke Install and test the release ZIP in clean WordPress"
3638

3739
build:
3840
$(COMPOSE) build $(PHP_SERVICE)
@@ -84,9 +86,14 @@ integration:
8486
test: unit integration
8587

8688
package:
87-
$(COMPOSE) run --rm $(PHP_SERVICE) bash -lc 'mkdir -p /tmp/release/basicrum && rsync -rc --exclude-from=/workspace/.distignore /workspace/ /tmp/release/basicrum/ --delete --delete-excluded && cd /tmp/release && zip -r /workspace/basicrum.zip basicrum'
89+
$(COMPOSE) run --rm --no-deps -w /repo $(PHP_SERVICE) sh /tools/build-release.sh /repo/$(PLUGIN_DIR) /repo/release
90+
91+
package-verify:
92+
$(COMPOSE) run --rm --no-deps -w /repo $(PHP_SERVICE) sh /tools/verify-release.sh /repo/release/basicrum.zip
93+
94+
package-smoke: package
95+
sh tools/smoke-test-release.sh release/basicrum.zip
8896

8997
clean:
9098
$(COMPOSE) down -v
91-
rm -f basicrum.zip
9299
rm -rf release

‎README.md‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ make integration
2424
make lint
2525
make translations
2626
make package
27+
make package-smoke
2728
```
2829

2930
### Local WordPress
@@ -46,3 +47,22 @@ so HTTP beacon URLs are automatically upgraded to HTTPS.
4647
The WordPress plugin itself lives in `plugins/basicrum/`.
4748

4849
If you want to work with Composer directly instead of using `make`, run commands from that directory.
50+
51+
## Release Artifact
52+
53+
`make package` builds `release/basicrum.zip`, generates
54+
`release/basicrum.zip.sha256`, and verifies that the archive contains the
55+
required runtime files without tests or other development files. The build runs
56+
`composer install --no-dev --classmap-authoritative` in a temporary directory,
57+
so the ZIP contains a fresh, optimized production autoloader without modifying
58+
the development checkout.
59+
60+
Run `make package-smoke` before a release. It installs the generated ZIP into a
61+
fresh, isolated WordPress instance, activates it with WP-CLI, enables tracking,
62+
and requests both the Basicrum administration page and the frontend. The test
63+
also checks that the frontend loader is present and that neither request nor the
64+
WordPress logs contain PHP warnings or fatal errors.
65+
66+
CI runs this same build and smoke-test path and retains both the ZIP and its
67+
SHA-256 checksum as workflow artifacts. Release and pre-release workflows attach
68+
both files to the GitHub release.

‎checklist.md‎

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,21 +55,21 @@ Acceptance criteria:
5555

5656
## 4. Make installation and release artifacts resilient
5757

58-
- [ ] Handle a missing `vendor/autoload.php` without an uncaught PHP fatal error.
59-
- [ ] Provide a clear administrator-facing error or use a plugin-owned autoloading
58+
- [x] Handle a missing `vendor/autoload.php` without an uncaught PHP fatal error.
59+
- [x] Provide a clear administrator-facing error or use a plugin-owned autoloading
6060
strategy that does not require a generated `vendor` directory.
61-
- [ ] Move release packaging into one reusable script used by local builds and CI.
62-
- [ ] Build the exact release ZIP during CI.
63-
- [ ] Inspect the ZIP for required runtime files and excluded development files.
64-
- [ ] Install the ZIP into a clean WordPress instance.
65-
- [ ] Activate the packaged plugin through WP-CLI.
66-
- [ ] Render an admin request and a frontend request after activation.
67-
- [ ] Verify the frontend contains the expected loader when the plugin is enabled.
68-
- [ ] Generate and publish a SHA-256 checksum for release artifacts.
61+
- [x] Move release packaging into one reusable script used by local builds and CI.
62+
- [x] Build the exact release ZIP during CI.
63+
- [x] Inspect the ZIP for required runtime files and excluded development files.
64+
- [x] Install the ZIP into a clean WordPress instance.
65+
- [x] Activate the packaged plugin through WP-CLI.
66+
- [x] Render an admin request and a frontend request after activation.
67+
- [x] Verify the frontend contains the expected loader when the plugin is enabled.
68+
- [x] Generate and publish a SHA-256 checksum for release artifacts.
6969

7070
Acceptance criteria:
7171

72-
- [ ] The generated ZIP, rather than the source checkout, installs, activates, and
72+
- [x] The generated ZIP, rather than the source checkout, installs, activates, and
7373
serves requests without warnings or fatal errors.
7474

7575
## 5. Expand the compatibility matrix
@@ -156,5 +156,5 @@ Acceptance criteria:
156156
- [ ] Static analysis passes.
157157
- [ ] Composer validation and audit pass.
158158
- [ ] Generated asset checks pass.
159-
- [ ] The packaged ZIP smoke test passes.
159+
- [x] The packaged ZIP smoke test passes.
160160
- [ ] Version and repository convention checks pass.

‎docker-compose.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ services:
7171
working_dir: /workspace
7272
volumes:
7373
- ./plugins/basicrum:/workspace
74+
- ./:/repo
7475
- ./tools:/tools:ro
7576
- wp_tests_lib:/tmp/wordpress-tests-lib
7677
- wp_core:/tmp/wordpress

‎docker/release-smoke.yml‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
services:
2+
db:
3+
image: mysql:8.0
4+
command: --default-authentication-plugin=mysql_native_password
5+
environment:
6+
MYSQL_DATABASE: wordpress
7+
MYSQL_USER: wordpress
8+
MYSQL_PASSWORD: wordpress
9+
MYSQL_ROOT_PASSWORD: root
10+
healthcheck:
11+
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-proot"]
12+
interval: 5s
13+
timeout: 5s
14+
retries: 20
15+
16+
wordpress:
17+
image: wordpress:6.8-php8.2-apache
18+
depends_on:
19+
db:
20+
condition: service_healthy
21+
environment:
22+
WORDPRESS_DB_HOST: db:3306
23+
WORDPRESS_DB_NAME: wordpress
24+
WORDPRESS_DB_USER: wordpress
25+
WORDPRESS_DB_PASSWORD: wordpress
26+
ports:
27+
- "127.0.0.1::80"
28+
volumes:
29+
- wordpress_data:/var/www/html
30+
31+
wpcli:
32+
image: wordpress:cli-2.12.0-php8.2
33+
user: "33:33"
34+
depends_on:
35+
db:
36+
condition: service_healthy
37+
environment:
38+
WORDPRESS_DB_HOST: db:3306
39+
WORDPRESS_DB_NAME: wordpress
40+
WORDPRESS_DB_USER: wordpress
41+
WORDPRESS_DB_PASSWORD: wordpress
42+
volumes:
43+
- wordpress_data:/var/www/html
44+
- "${BASICRUM_RELEASE_ZIP}:/artifacts/basicrum.zip:ro"
45+
46+
volumes:
47+
wordpress_data:

‎plugins/basicrum/.distignore‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
/.vscode
55
/tests
66
/vendor/bin
7+
/vendor/**/.github
8+
/.distignore
79

810
.phpunit.result.cache
911
composer.json

‎plugins/basicrum/basicrum.php‎

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,28 @@
2323
define( 'BASICRUM_PLUGIN_FILE', __FILE__ );
2424
define( 'BASICRUM_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
2525

26-
// Load Composer autoloader.
27-
if ( file_exists( BASICRUM_PLUGIN_DIR . 'vendor/autoload.php' ) ) {
28-
require_once BASICRUM_PLUGIN_DIR . 'vendor/autoload.php';
26+
// Load the optimized Composer autoloader included in release packages.
27+
$basicrum_autoloader = BASICRUM_PLUGIN_DIR . 'vendor/autoload.php';
28+
29+
if ( ! is_readable( $basicrum_autoloader ) ) {
30+
$basicrum_missing_autoloader_notice = static function () {
31+
if ( ! current_user_can( 'activate_plugins' ) ) {
32+
return;
33+
}
34+
35+
printf(
36+
'<div class="notice notice-error"><p>%s</p></div>',
37+
esc_html__( 'Basicrum could not start because its Composer dependencies are missing. Reinstall the plugin from an official release ZIP.', 'basicrum' )
38+
);
39+
};
40+
41+
add_action( 'admin_notices', $basicrum_missing_autoloader_notice );
42+
add_action( 'network_admin_notices', $basicrum_missing_autoloader_notice );
43+
return;
2944
}
3045

46+
require_once $basicrum_autoloader;
47+
3148
// Bootstrap the plugin.
3249
$basicrum_plugin = new \Basicrum\WP\Plugin();
3350
$basicrum_plugin->register();

0 commit comments

Comments
 (0)