Compare commits
1 Commits
claude/ci-
...
claude/dep
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4946ec9c33 |
36
.distignore
36
.distignore
@@ -1,36 +0,0 @@
|
|||||||
# Files excluded from the production zip.
|
|
||||||
# Used by the GitHub Actions deploy workflow (rsync --exclude-from).
|
|
||||||
# Keep in sync with .gitignore for dev-only artifacts.
|
|
||||||
|
|
||||||
.git
|
|
||||||
.github
|
|
||||||
.distignore
|
|
||||||
.gitignore
|
|
||||||
.phpcs.xml
|
|
||||||
.editorconfig
|
|
||||||
|
|
||||||
# Development & testing
|
|
||||||
tests/
|
|
||||||
phpunit.xml
|
|
||||||
phpunit.xml.dist
|
|
||||||
composer.json
|
|
||||||
composer.lock
|
|
||||||
vendor/
|
|
||||||
|
|
||||||
# Documentation (lives in repo, not in deployed plugin)
|
|
||||||
ARCHITECTURE.md
|
|
||||||
CONVENTIONS.md
|
|
||||||
CHANGELOG.md
|
|
||||||
CODE_OF_CONDUCT.md
|
|
||||||
CONTRIBUTING.md
|
|
||||||
|
|
||||||
# CI/CD tooling
|
|
||||||
scripts/
|
|
||||||
node_modules/
|
|
||||||
package.json
|
|
||||||
package-lock.json
|
|
||||||
|
|
||||||
# OS artifacts
|
|
||||||
.DS_Store
|
|
||||||
Thumbs.db
|
|
||||||
*.log
|
|
||||||
17
.github/workflows/ci.yml
vendored
17
.github/workflows/ci.yml
vendored
@@ -109,20 +109,3 @@ jobs:
|
|||||||
run: composer install --no-progress --no-interaction --prefer-dist
|
run: composer install --no-progress --no-interaction --prefer-dist
|
||||||
- name: Run PHPUnit (Brain Monkey — no WP install required)
|
- name: Run PHPUnit (Brain Monkey — no WP install required)
|
||||||
run: vendor/bin/phpunit --testdox
|
run: vendor/bin/phpunit --testdox
|
||||||
|
|
||||||
check-constants:
|
|
||||||
name: Check PRAUTOBLOGGER_* constants
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Setup PHP 8.1
|
|
||||||
uses: shivammathur/setup-php@v2
|
|
||||||
with:
|
|
||||||
php-version: '8.1'
|
|
||||||
coverage: none
|
|
||||||
- name: Check PRAUTOBLOGGER_* constants
|
|
||||||
# Fails if any PRAUTOBLOGGER_* constant referenced in the shipped
|
|
||||||
# plugin PHP is neither defined in prautoblogger.php nor guarded
|
|
||||||
# by defined() at the reference site. Prevents the v0.19.0 incident
|
|
||||||
# class (constant deleted from bootstrap, test fallback masks the gap).
|
|
||||||
run: php scripts/check-constants.php
|
|
||||||
|
|||||||
13
CHANGELOG.md
13
CHANGELOG.md
@@ -5,10 +5,15 @@ All notable changes to PRAutoBlogger will be documented in this file.
|
|||||||
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project uses [Semantic Versioning](https://semver.org/).
|
and this project uses [Semantic Versioning](https://semver.org/).
|
||||||
|
|
||||||
## [Unreleased - Internal]
|
## [0.20.2] - 2026-06-13
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
- **`scripts/deploy.sh`** — belonged to the retired zip/REST deploy receiver flow
|
||||||
|
(`/wp-json/prautoblogger-deploy/v1/*`); the live pipeline is the shared rsync workflow
|
||||||
|
(`peptiderepo/peptide-e2e/.github/workflows/deploy-app.yml@main`).
|
||||||
|
- **`.distignore`** — used by `scripts/deploy.sh` to build the production zip; no longer
|
||||||
|
consumed by any workflow (the shared rsync pipeline uses hardcoded `--exclude` flags).
|
||||||
|
|
||||||
### Internal
|
|
||||||
- CI constants guard (`scripts/check-constants.php`): new required CI step (`Check PRAUTOBLOGGER_* constants`) fails the build when any `PRAUTOBLOGGER_*` constant referenced in shipped plugin PHP is neither defined in `prautoblogger.php` nor `defined()`-guarded at the reference site. Prevents a recurrence of the v0.19.0 admin-500 regression class.
|
|
||||||
|
|
||||||
## [0.20.1] - 2026-06-12
|
## [0.20.1] - 2026-06-12
|
||||||
|
|
||||||
@@ -1225,4 +1230,4 @@ swap with no user-visible change in article quality.
|
|||||||
- AJAX-powered "Generate Now" and "Test Connections" buttons.
|
- AJAX-powered "Generate Now" and "Test Connections" buttons.
|
||||||
- Custom database tables for source data, analysis results, generation logs, and content scores.
|
- Custom database tables for source data, analysis results, generation logs, and content scores.
|
||||||
- Clean uninstall handler removing all plugin data.
|
- Clean uninstall handler removing all plugin data.
|
||||||
- ARCHITECTURE.md and CONVENTIONS.md for AI-readable codebase documentation.
|
- ARCHITECTURE.md and CONVENTIONS.md for AI-readable codebase documentation.
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
* Plugin Name: PRAutoBlogger
|
* Plugin Name: PRAutoBlogger
|
||||||
* Plugin URI: https://peptiderepo.com/prautoblogger
|
* Plugin URI: https://peptiderepo.com/prautoblogger
|
||||||
* Description: Monitors social media for trending topics, generates SEO-friendly blog posts using AI, and publishes them on a daily schedule with full cost tracking and self-improvement metrics.
|
* Description: Monitors social media for trending topics, generates SEO-friendly blog posts using AI, and publishes them on a daily schedule with full cost tracking and self-improvement metrics.
|
||||||
* Version: 0.20.1
|
* Version: 0.20.2
|
||||||
* Requires at least: 6.0
|
* Requires at least: 6.0
|
||||||
* Requires PHP: 7.4
|
* Requires PHP: 7.4
|
||||||
* Author: PeptideRepo
|
* Author: PeptideRepo
|
||||||
@@ -35,7 +35,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
| Defined here so every file in the plugin can reference paths, versions,
|
| Defined here so every file in the plugin can reference paths, versions,
|
||||||
| and limits without magic strings.
|
| and limits without magic strings.
|
||||||
*/
|
*/
|
||||||
define( 'PRAUTOBLOGGER_VERSION', '0.20.1' );
|
define( 'PRAUTOBLOGGER_VERSION', '0.20.2' );
|
||||||
define( 'PRAUTOBLOGGER_DB_VERSION', '1.3.0' );
|
define( 'PRAUTOBLOGGER_DB_VERSION', '1.3.0' );
|
||||||
define( 'PRAUTOBLOGGER_DEFAULT_RUN_CEILING_USD', 0.50 );
|
define( 'PRAUTOBLOGGER_DEFAULT_RUN_CEILING_USD', 0.50 );
|
||||||
define( 'PRAUTOBLOGGER_DEFAULT_REQUEST_JSON_RETENTION_DAYS', 14 );
|
define( 'PRAUTOBLOGGER_DEFAULT_REQUEST_JSON_RETENTION_DAYS', 14 );
|
||||||
|
|||||||
@@ -1,212 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* CI guard: every PRAUTOBLOGGER_* constant referenced in the shipped plugin PHP
|
|
||||||
* must be either (a) defined in prautoblogger.php, or (b) protected by a
|
|
||||||
* defined() guard at the reference site.
|
|
||||||
*
|
|
||||||
* Purpose: prevent the class of regression that caused the v0.19.0 admin-500
|
|
||||||
* incident — a constant deleted from prautoblogger.php while tests/bootstrap.php
|
|
||||||
* kept a fallback copy, masking the gap until prod boot.
|
|
||||||
*
|
|
||||||
* Usage (from repo root):
|
|
||||||
* php scripts/check-constants.php [--verbose]
|
|
||||||
*
|
|
||||||
* Exit 0 = all clear. Exit 1 = unguarded undefined constants found.
|
|
||||||
*
|
|
||||||
* Include/exclude summary (relative to repo root):
|
|
||||||
* Defined-set source prautoblogger.php only
|
|
||||||
* Scanned for refs prautoblogger.php, includes/, templates/, uninstall.php
|
|
||||||
* Excluded from refs tests/ vendor/ .github/ .git/ node_modules/
|
|
||||||
* Excluded from defs everything except prautoblogger.php
|
|
||||||
*
|
|
||||||
* Guard window: a bare constant use is considered guarded if a defined() call
|
|
||||||
* for the same constant appears within GUARD_WINDOW lines above it in the same
|
|
||||||
* file (covers if/elseif blocks and multi-line && chains).
|
|
||||||
*
|
|
||||||
* @package PRAutoBlogger
|
|
||||||
*/
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
// How many lines above the bare use to look for a defined() guard.
|
|
||||||
const CONSTANTS_GUARD_WINDOW = 4;
|
|
||||||
|
|
||||||
// Source of truth for define()d constants -- test-bootstrap fallbacks excluded.
|
|
||||||
const CONSTANTS_BOOTSTRAP_FILE = 'prautoblogger.php';
|
|
||||||
|
|
||||||
// Directories skipped when walking the shipped tree for references.
|
|
||||||
const CONSTANTS_EXCLUDE_DIRS = ['tests', 'vendor', '.github', '.git', 'node_modules'];
|
|
||||||
|
|
||||||
// Entry points for the reference scan (files and dirs relative to repo root).
|
|
||||||
const CONSTANTS_SCAN_ROOTS = [
|
|
||||||
'prautoblogger.php',
|
|
||||||
'uninstall.php',
|
|
||||||
'includes',
|
|
||||||
'templates',
|
|
||||||
];
|
|
||||||
|
|
||||||
$verbose = in_array( '--verbose', $argv ?? [], true );
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// 1. Build the defined set from prautoblogger.php only.
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
if ( ! file_exists( CONSTANTS_BOOTSTRAP_FILE ) ) {
|
|
||||||
fwrite( STDERR, "ERROR: bootstrap file not found -- run from repo root.\n" );
|
|
||||||
fwrite( STDERR, ' Expected: ' . CONSTANTS_BOOTSTRAP_FILE . "\n" );
|
|
||||||
exit( 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
$bootstrap_src = (string) file_get_contents( CONSTANTS_BOOTSTRAP_FILE );
|
|
||||||
|
|
||||||
preg_match_all(
|
|
||||||
"/define\s*\(\s*'(PRAUTOBLOGGER_[A-Z0-9_]+)'/",
|
|
||||||
$bootstrap_src,
|
|
||||||
$def_matches
|
|
||||||
);
|
|
||||||
|
|
||||||
/** @var array<string, int> $defined_set constant name => 1 */
|
|
||||||
$defined_set = array_flip( $def_matches[1] ?? [] );
|
|
||||||
|
|
||||||
if ( $verbose ) {
|
|
||||||
echo 'Defined in ' . CONSTANTS_BOOTSTRAP_FILE . ' (' . count( $defined_set ) . "):\n";
|
|
||||||
foreach ( array_keys( $defined_set ) as $constant_name ) {
|
|
||||||
echo " {$constant_name}\n";
|
|
||||||
}
|
|
||||||
echo "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// 2. Collect shipped PHP files to scan.
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursively collect *.php paths under a directory, skipping excluded dirs.
|
|
||||||
*
|
|
||||||
* @param string $dir Directory to walk.
|
|
||||||
* @param string[] $files Accumulator (modified by reference).
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function constants_collect_php_files( string $dir, array &$files ): void {
|
|
||||||
$dir_iter = new DirectoryIterator( $dir );
|
|
||||||
foreach ( $dir_iter as $entry ) {
|
|
||||||
if ( $entry->isDot() ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$basename = $entry->getBasename();
|
|
||||||
if ( $entry->isDir() ) {
|
|
||||||
if ( ! in_array( $basename, CONSTANTS_EXCLUDE_DIRS, true ) ) {
|
|
||||||
constants_collect_php_files( $entry->getPathname(), $files );
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( $entry->isFile() && $entry->getExtension() === 'php' ) {
|
|
||||||
$files[] = $entry->getPathname();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @var string[] $php_files */
|
|
||||||
$php_files = [];
|
|
||||||
|
|
||||||
foreach ( CONSTANTS_SCAN_ROOTS as $root ) {
|
|
||||||
if ( ! file_exists( $root ) ) {
|
|
||||||
// Template dir may not exist in very early checkouts -- skip silently.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( is_file( $root ) ) {
|
|
||||||
$php_files[] = $root;
|
|
||||||
} else {
|
|
||||||
constants_collect_php_files( $root, $php_files );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sort( $php_files );
|
|
||||||
|
|
||||||
if ( $verbose ) {
|
|
||||||
echo 'Scanning ' . count( $php_files ) . " PHP files\n\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// 3. Scan each file for bare PRAUTOBLOGGER_* references.
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/** @var array<int, array{string, int, string, string}> $errors */
|
|
||||||
$errors = [];
|
|
||||||
|
|
||||||
foreach ( $php_files as $php_path ) {
|
|
||||||
$raw = file_get_contents( $php_path );
|
|
||||||
if ( $raw === false ) {
|
|
||||||
fwrite( STDERR, "WARNING: cannot read {$php_path} -- skipping\n" );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$lines = explode( "\n", $raw );
|
|
||||||
|
|
||||||
foreach ( $lines as $idx => $raw_line ) {
|
|
||||||
// Fast pre-check: skip lines with no PRAUTOBLOGGER_ token.
|
|
||||||
if ( strpos( $raw_line, 'PRAUTOBLOGGER_' ) === false ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip pure comment lines (docblock * lines, // comments, # lines).
|
|
||||||
$trimmed = ltrim( $raw_line );
|
|
||||||
if (
|
|
||||||
str_starts_with( $trimmed, '*' ) ||
|
|
||||||
str_starts_with( $trimmed, '//' ) ||
|
|
||||||
str_starts_with( $trimmed, '#' )
|
|
||||||
) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract all constant names from this line.
|
|
||||||
if ( ! preg_match_all( '/PRAUTOBLOGGER_[A-Z0-9_]+/', $raw_line, $match ) ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ( $match[0] as $name ) {
|
|
||||||
// Skip if this line is itself a define() call for this name.
|
|
||||||
if ( preg_match( "/define\s*\(\s*'" . preg_quote( $name, '/' ) . "'/", $raw_line ) ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip if the constant is production-defined in prautoblogger.php.
|
|
||||||
if ( isset( $defined_set[ $name ] ) ) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for a defined() guard in the preceding GUARD_WINDOW lines
|
|
||||||
// (inclusive of the current line to catch same-line chained &&).
|
|
||||||
$window_start = max( 0, $idx - CONSTANTS_GUARD_WINDOW );
|
|
||||||
$guarded = false;
|
|
||||||
for ( $w = $window_start; $w <= $idx; $w++ ) {
|
|
||||||
if ( preg_match( "/defined\s*\(\s*'" . preg_quote( $name, '/' ) . "'/", $lines[ $w ] ) ) {
|
|
||||||
$guarded = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! $guarded ) {
|
|
||||||
$errors[] = [ $php_path, $idx + 1, $name, $raw_line ];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// 4. Report results.
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
if ( $errors !== [] ) {
|
|
||||||
fwrite( STDERR, "\nFAIL -- Unguarded undefined PRAUTOBLOGGER_* constants:\n\n" );
|
|
||||||
foreach ( $errors as [ $php_path, $lineno, $name, $line_text ] ) {
|
|
||||||
fwrite( STDERR, " {$php_path}:{$lineno}: {$name}\n" );
|
|
||||||
fwrite( STDERR, ' ' . trim( $line_text ) . "\n" );
|
|
||||||
}
|
|
||||||
fwrite( STDERR, "\nTo fix: add define( '" . $errors[0][2] . "', ... ) to prautoblogger.php,\n" );
|
|
||||||
fwrite( STDERR, "or guard the reference with if ( defined( '" . $errors[0][2] . "' ) ) { ... }\n\n" );
|
|
||||||
exit( 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "OK -- All PRAUTOBLOGGER_* constants are production-defined or defined()-guarded.\n";
|
|
||||||
exit( 0 );
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# ============================================================================
|
|
||||||
# PRAutoBlogger Manual Deploy Script
|
|
||||||
#
|
|
||||||
# Packages the plugin into a clean zip and deploys it to WordPress via the
|
|
||||||
# deploy-receiver REST endpoint. Use this for hotfixes or local deploys when
|
|
||||||
# you don't want to go through the full GitHub Actions pipeline.
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# ./scripts/deploy.sh
|
|
||||||
#
|
|
||||||
# Environment variables (set in .env or export before running):
|
|
||||||
# DEPLOY_URL — Full URL to the deploy endpoint
|
|
||||||
# DEPLOY_KEY — The deploy authentication token
|
|
||||||
#
|
|
||||||
# If not set, the script will look for a .env file in the project root.
|
|
||||||
#
|
|
||||||
# @see .github/workflows/deploy.yml — Automated pipeline (same deploy step).
|
|
||||||
# @see ARCHITECTURE.md — Deploy architecture (Code Snippets snippet #8 on server).
|
|
||||||
# ============================================================================
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
||||||
|
|
||||||
# Colors for output.
|
|
||||||
RED='\033[0;31m'
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
YELLOW='\033[1;33m'
|
|
||||||
NC='\033[0m'
|
|
||||||
|
|
||||||
info() { echo -e "${GREEN}[deploy]${NC} $*"; }
|
|
||||||
warn() { echo -e "${YELLOW}[deploy]${NC} $*"; }
|
|
||||||
error() { echo -e "${RED}[deploy]${NC} $*" >&2; }
|
|
||||||
|
|
||||||
# ── Load environment ────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
if [[ -f "$PROJECT_ROOT/.env" ]]; then
|
|
||||||
# shellcheck source=/dev/null
|
|
||||||
source "$PROJECT_ROOT/.env"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z "${DEPLOY_URL:-}" ]]; then
|
|
||||||
error "DEPLOY_URL not set. Export it or add to .env"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z "${DEPLOY_KEY:-}" ]]; then
|
|
||||||
error "DEPLOY_KEY not set. Export it or add to .env"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ── Read version ────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
VERSION=$(grep -oP 'Version:\s*\K[0-9]+\.[0-9]+\.[0-9]+' "$PROJECT_ROOT/prautoblogger.php" || echo "0.0.0")
|
|
||||||
info "PRAutoBlogger v${VERSION}"
|
|
||||||
|
|
||||||
# ── PHP lint check ──────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
info "Running PHP syntax check..."
|
|
||||||
LINT_ERRORS=0
|
|
||||||
while IFS= read -r -d '' file; do
|
|
||||||
if ! php -l "$file" > /dev/null 2>&1; then
|
|
||||||
error "Syntax error in: $file"
|
|
||||||
php -l "$file"
|
|
||||||
LINT_ERRORS=$((LINT_ERRORS + 1))
|
|
||||||
fi
|
|
||||||
done < <(find "$PROJECT_ROOT" -name '*.php' -not -path '*/vendor/*' -not -path '*/tests/*' -not -path '*/.github/*' -print0)
|
|
||||||
|
|
||||||
if [[ $LINT_ERRORS -gt 0 ]]; then
|
|
||||||
error "$LINT_ERRORS file(s) have syntax errors. Aborting deploy."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
info "Lint passed."
|
|
||||||
|
|
||||||
# ── Package ─────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
BUILD_DIR=$(mktemp -d)
|
|
||||||
PLUGIN_DIR="$BUILD_DIR/prautoblogger"
|
|
||||||
ZIP_PATH="$BUILD_DIR/prautoblogger-${VERSION}.zip"
|
|
||||||
|
|
||||||
info "Packaging plugin..."
|
|
||||||
|
|
||||||
mkdir -p "$PLUGIN_DIR"
|
|
||||||
|
|
||||||
# Copy production files, excluding dev artifacts.
|
|
||||||
rsync -a \
|
|
||||||
--exclude='.git' \
|
|
||||||
--exclude='.github' \
|
|
||||||
--exclude='.gitignore' \
|
|
||||||
--exclude='.distignore' \
|
|
||||||
--exclude='.env' \
|
|
||||||
--exclude='.env.local' \
|
|
||||||
--exclude='tests/' \
|
|
||||||
--exclude='scripts/' \
|
|
||||||
--exclude='vendor/' \
|
|
||||||
--exclude='node_modules/' \
|
|
||||||
--exclude='composer.json' \
|
|
||||||
--exclude='composer.lock' \
|
|
||||||
--exclude='phpunit.xml' \
|
|
||||||
--exclude='phpunit.xml.dist' \
|
|
||||||
--exclude='.phpcs.xml' \
|
|
||||||
--exclude='ARCHITECTURE.md' \
|
|
||||||
--exclude='CONVENTIONS.md' \
|
|
||||||
--exclude='CHANGELOG.md' \
|
|
||||||
--exclude='build/' \
|
|
||||||
--exclude='*.log' \
|
|
||||||
--exclude='.DS_Store' \
|
|
||||||
"$PROJECT_ROOT/" "$PLUGIN_DIR/"
|
|
||||||
|
|
||||||
cd "$BUILD_DIR"
|
|
||||||
zip -rq "$ZIP_PATH" prautoblogger/
|
|
||||||
|
|
||||||
ZIP_SIZE=$(du -h "$ZIP_PATH" | cut -f1)
|
|
||||||
info "Built ${ZIP_PATH} (${ZIP_SIZE})"
|
|
||||||
|
|
||||||
# ── Pre-deploy health check ────────────────────────────────────────────────
|
|
||||||
|
|
||||||
STATUS_URL="${DEPLOY_URL%/deploy}/status"
|
|
||||||
info "Checking deploy endpoint health..."
|
|
||||||
STATUS_RESPONSE=$(curl -sS -w "\n%{http_code}" \
|
|
||||||
-H "X-Deploy-Key: ${DEPLOY_KEY}" \
|
|
||||||
"${STATUS_URL}" 2>&1) || true
|
|
||||||
|
|
||||||
STATUS_HTTP=$(echo "$STATUS_RESPONSE" | tail -1)
|
|
||||||
if [[ "$STATUS_HTTP" == "200" ]]; then
|
|
||||||
STATUS_BODY=$(echo "$STATUS_RESPONSE" | head -n -1)
|
|
||||||
info "Endpoint healthy: ${STATUS_BODY}"
|
|
||||||
else
|
|
||||||
warn "Health check returned HTTP ${STATUS_HTTP} — proceeding anyway."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ── Deploy ──────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
info "Deploying to ${DEPLOY_URL}..."
|
|
||||||
|
|
||||||
RESPONSE=$(curl -sS -w "\n%{http_code}" \
|
|
||||||
-X POST "${DEPLOY_URL}" \
|
|
||||||
-H "X-Deploy-Key: ${DEPLOY_KEY}" \
|
|
||||||
-F "plugin=@${ZIP_PATH}" \
|
|
||||||
--max-time 120)
|
|
||||||
|
|
||||||
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
|
||||||
BODY=$(echo "$RESPONSE" | head -n -1)
|
|
||||||
|
|
||||||
if [[ "$HTTP_CODE" -eq 200 ]]; then
|
|
||||||
info "Deployment successful!"
|
|
||||||
echo "$BODY" | python3 -m json.tool 2>/dev/null || echo "$BODY"
|
|
||||||
else
|
|
||||||
error "Deployment FAILED (HTTP ${HTTP_CODE}):"
|
|
||||||
echo "$BODY" | python3 -m json.tool 2>/dev/null || echo "$BODY"
|
|
||||||
rm -rf "$BUILD_DIR"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ── Cleanup ─────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
rm -rf "$BUILD_DIR"
|
|
||||||
info "Done. PRAutoBlogger v${VERSION} is live."
|
|
||||||
Reference in New Issue
Block a user