Skip to content

Commit 0e85216

Browse files
committed
chore: add release packaging workflow
1 parent b7f0634 commit 0e85216

10 files changed

Lines changed: 192 additions & 2 deletions

File tree

.distignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
.git/
22
.github/
3+
dist/
34
docs/
5+
scripts/
46
tests/
57
vendor/
68
.phpunit.cache/

.github/workflows/ci.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,8 @@ jobs:
2424
- name: Run tests
2525
run: php tests/run.php
2626

27+
- name: Validate readme metadata
28+
run: php tests/validate-readme.php
29+
2730
- name: Lint PHP files
2831
run: find . -path ./vendor -prune -o -name '*.php' -print0 | xargs -0 -n1 php -l

.github/workflows/release.yml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*.*.*'
7+
workflow_dispatch:
8+
9+
jobs:
10+
build-release-zip:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: write
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v5
17+
18+
- name: Setup PHP
19+
uses: shivammathur/setup-php@v2
20+
with:
21+
php-version: '8.3'
22+
coverage: none
23+
24+
- name: Run tests
25+
run: php tests/run.php
26+
27+
- name: Validate readme metadata
28+
run: php tests/validate-readme.php
29+
30+
- name: Lint PHP files
31+
run: find . -path ./vendor -prune -o -name '*.php' -print0 | xargs -0 -n1 php -l
32+
33+
- name: Build plugin ZIP
34+
run: bash scripts/build-release.sh
35+
36+
- name: Upload build artifact
37+
uses: actions/upload-artifact@v4
38+
with:
39+
name: cron-inspector-lite
40+
path: dist/cron-inspector-lite.zip
41+
42+
- name: Publish GitHub release asset
43+
if: startsWith(github.ref, 'refs/tags/')
44+
uses: softprops/action-gh-release@v2
45+
with:
46+
files: dist/cron-inspector-lite.zip
47+
generate_release_notes: true

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/vendor/
22
/.phpunit.cache/
3+
/dist/
34
*.log
45
.DS_Store

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Changelog
2+
3+
All notable changes to Cron Inspector Lite will be documented in this file.
4+
5+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project uses semantic versioning for GitHub releases.
6+
7+
## [0.1.0] - 2026-06-02
8+
9+
### Added
10+
11+
- Read-only admin page under **Tools → Cron Inspector**.
12+
- Scheduled WP-Cron event list with hook, next run time, schedule, interval, and flags.
13+
- Duplicate hook detection for support/debugging workflows.
14+
- Unusually frequent recurring hook detection for intervals shorter than one hour.
15+
- Overdue event counting.
16+
- Copyable plain-text support report.
17+
- Translation template for the `cron-inspector-lite` text domain.
18+
- Local PHP test runner and GitHub Actions CI.
19+
20+
### Notes
21+
22+
- Version 0.1.0 does not delete, reschedule, or mutate cron events.
23+
- The plugin does not send data to external services.

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,17 @@ This plugin is read-only in the initial version. It lists scheduled WP-Cron even
2222

2323
```bash
2424
php tests/run.php
25+
php tests/validate-readme.php
2526
find . -path ./vendor -prune -o -name '*.php' -print0 | xargs -0 -n1 php -l
27+
bash scripts/build-release.sh
2628
```
2729

30+
The release package is written to `dist/cron-inspector-lite.zip`.
31+
32+
## Changelog
33+
34+
See [CHANGELOG.md](CHANGELOG.md).
35+
2836
## License
2937

3038
GPL-2.0-or-later

composer.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
},
1111
"scripts": {
1212
"test": "php tests/run.php",
13-
"lint": "find . -path ./vendor -prune -o -name '*.php' -print0 | xargs -0 -n1 php -l"
13+
"validate-readme": "php tests/validate-readme.php",
14+
"lint": "find . -path ./vendor -prune -o -name '*.php' -print0 | xargs -0 -n1 php -l",
15+
"build-release": "bash scripts/build-release.sh"
1416
},
1517
"require": {
1618
"php": ">=7.4"

docs/wporg-publishing-checklist.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ Plugin slug target: `cron-inspector-lite`
88
- Public GitHub repository exists.
99
- Plugin has been tested on the staging site `peepso.nariyanto.id`.
1010
- Plugin is read-only and does not delete or mutate cron events.
11-
- CI runs PHP tests and PHP syntax checks.
11+
- CI runs PHP tests, readme metadata validation, and PHP syntax checks.
12+
- Release workflow builds `dist/cron-inspector-lite.zip` for GitHub release assets.
1213
- A screenshot from the staging site is available in `docs/screenshots/` for GitHub documentation.
1314
- Translation template exists at `languages/cron-inspector-lite.pot`.
1415

scripts/build-release.sh

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5+
PLUGIN_SLUG="cron-inspector-lite"
6+
DIST_DIR="$ROOT_DIR/dist"
7+
BUILD_DIR="$DIST_DIR/build"
8+
PACKAGE_DIR="$BUILD_DIR/$PLUGIN_SLUG"
9+
ZIP_PATH="$DIST_DIR/$PLUGIN_SLUG.zip"
10+
11+
rm -rf "$BUILD_DIR" "$ZIP_PATH"
12+
mkdir -p "$PACKAGE_DIR" "$DIST_DIR"
13+
14+
copy_file() {
15+
local src="$1"
16+
local dest="$PACKAGE_DIR/$src"
17+
mkdir -p "$(dirname "$dest")"
18+
cp "$ROOT_DIR/$src" "$dest"
19+
}
20+
21+
copy_file "cron-inspector-lite.php"
22+
copy_file "readme.txt"
23+
copy_file "CHANGELOG.md"
24+
copy_file "languages/cron-inspector-lite.pot"
25+
copy_file "src/AdminPage.php"
26+
copy_file "src/CronEventInspector.php"
27+
28+
python3 - "$BUILD_DIR" "$ZIP_PATH" "$PLUGIN_SLUG" <<'PY'
29+
import sys
30+
import zipfile
31+
from pathlib import Path
32+
33+
build_dir = Path(sys.argv[1])
34+
zip_path = Path(sys.argv[2])
35+
plugin_slug = sys.argv[3]
36+
37+
with zipfile.ZipFile(zip_path, 'w', compression=zipfile.ZIP_DEFLATED) as archive:
38+
for path in sorted((build_dir / plugin_slug).rglob('*')):
39+
if path.is_file():
40+
archive.write(path, path.relative_to(build_dir))
41+
PY
42+
43+
printf 'Built %s\n' "$ZIP_PATH"

tests/validate-readme.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
$root = dirname(__DIR__);
6+
$readme = file_get_contents($root . '/readme.txt');
7+
$plugin = file_get_contents($root . '/cron-inspector-lite.php');
8+
9+
if (false === $readme || false === $plugin) {
10+
fwrite(STDERR, "Unable to read plugin metadata files.\n");
11+
exit(1);
12+
}
13+
14+
$failures = [];
15+
16+
$required_readme_patterns = [
17+
'/^=== Cron Inspector Lite ===$/m' => 'readme plugin title',
18+
'/^Contributors:\s*nariyanto$/m' => 'readme contributors',
19+
'/^Requires at least:\s*6\.0$/m' => 'minimum WordPress version',
20+
'/^Requires PHP:\s*7\.4$/m' => 'minimum PHP version',
21+
'/^Stable tag:\s*0\.1\.0$/m' => 'stable tag',
22+
'/^License:\s*GPLv2 or later$/m' => 'license',
23+
'/== Changelog ==/' => 'changelog section',
24+
'/= 0\.1\.0 =/' => '0.1.0 changelog entry',
25+
];
26+
27+
foreach ($required_readme_patterns as $pattern => $label) {
28+
if (1 !== preg_match($pattern, $readme)) {
29+
$failures[] = "Missing or invalid {$label}.";
30+
}
31+
}
32+
33+
$required_plugin_patterns = [
34+
'/Plugin Name:\s*Cron Inspector Lite/' => 'plugin name',
35+
'/Version:\s*0\.1\.0/' => 'plugin version',
36+
'/Text Domain:\s*cron-inspector-lite/' => 'text domain',
37+
'/Domain Path:\s*\/languages/' => 'domain path',
38+
'/Requires at least:\s*6\.0/' => 'plugin minimum WordPress version',
39+
'/Requires PHP:\s*7\.4/' => 'plugin minimum PHP version',
40+
'/License:\s*GPL-2\.0-or-later/' => 'plugin license',
41+
];
42+
43+
foreach ($required_plugin_patterns as $pattern => $label) {
44+
if (1 !== preg_match($pattern, $plugin)) {
45+
$failures[] = "Missing or invalid {$label}.";
46+
}
47+
}
48+
49+
if (str_contains($readme, 'wp-cron-inspector-lite')) {
50+
$failures[] = 'readme.txt still contains old plugin slug/name text.';
51+
}
52+
53+
if ($failures) {
54+
foreach ($failures as $failure) {
55+
fwrite(STDERR, "FAIL: {$failure}\n");
56+
}
57+
exit(1);
58+
}
59+
60+
echo "Readme and plugin metadata validation passed.\n";

0 commit comments

Comments
 (0)