From bf99f442baaca781adc75761ccf01db7c9cfefac Mon Sep 17 00:00:00 2001 From: Josh Knapp Date: Tue, 22 Apr 2025 13:35:47 -0700 Subject: [PATCH] Major Update to add auto-update features --- .gitea/workflows/release.yml | 40 ++++++- fw-store-embed.php | 3 +- libs/self-update.php | 199 +++++++++++++++++++++++++++++++++++ 3 files changed, 240 insertions(+), 2 deletions(-) create mode 100644 libs/self-update.php diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index d20d6b7..5762b37 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -14,6 +14,7 @@ jobs: with: username: ${{ secrets.CI_USER }} password: ${{ secrets.CI_TOKEN }} + fetch-depth: 0 # Important: Fetch all history for commit messages - name: Get version id: get_version @@ -24,6 +25,42 @@ jobs: echo "version=$(date +'%Y.%m.%d-%H%M')" >> $GITHUB_OUTPUT fi + # NEW STEP: Generate release notes from commits + - name: Generate release notes + id: release_notes + run: | + # Find the most recent tag + LATEST_TAG=$(git describe --tags --abbrev=0 --always 2>/dev/null || echo "none") + + if [ "$LATEST_TAG" = "none" ]; then + # If no previous tag exists, get all commits + COMMITS=$(git log --pretty=format:"* %s (%h)" --no-merges) + else + # Get commits since the last tag + COMMITS=$(git log --pretty=format:"* %s (%h)" ${LATEST_TAG}..HEAD --no-merges) + fi + + # Escape newlines and special characters for GitHub Actions + COMMITS="${COMMITS//'%'/'%25'}" + COMMITS="${COMMITS//$'\n'/'%0A'}" + COMMITS="${COMMITS//$'\r'/'%0D'}" + + # Create release notes with header + NOTES="## What's New in ${{ steps.get_version.outputs.version }}%0A%0A" + NOTES+="$COMMITS" + + # Output to GitHub Actions + echo "notes<> $GITHUB_OUTPUT + echo "$NOTES" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Update plugin version + run: | + # Replace version placeholder with actual version + sed -i "s/Version: {auto_update_value_on_deploy}/Version: ${{ steps.get_version.outputs.version }}/" fw-store-embed.php + # Verify the change was made + grep "Version:" fw-store-embed.php + - name: Create ZIP archive run: | zip -r fourthwall-store-embed.zip . -x ".git/*" ".gitea/*" @@ -34,5 +71,6 @@ jobs: token: "${{ secrets.REPO_TOKEN }}" title: Fourthwall-store-embed Release ${{ steps.get_version.outputs.version }} tag_name: ${{ steps.get_version.outputs.version }} + body: "${{ steps.release_notes.outputs.notes }}" files: | - fourthwall-store-embed.zip + fourthwall-store-embed.zip \ No newline at end of file diff --git a/fw-store-embed.php b/fw-store-embed.php index 7369ab9..599fbc2 100644 --- a/fw-store-embed.php +++ b/fw-store-embed.php @@ -3,12 +3,13 @@ * Plugin Name: Fourthwall Store Embed * Plugin URL: https://cybercove.io/ * Description: Embed Fourthwall Store in WordPress - * Version: 1.0.0. + * Version: {auto_update_value_on_deploy} * Author: Joshua Knapp * Text Domain: fourthwall_text_domain * */ +include("libs/self-update.php"); include("libs/settings.php"); include("libs/shortcode.php"); function set_fw_store_embed_css() { diff --git a/libs/self-update.php b/libs/self-update.php new file mode 100644 index 0000000..ab99dcc --- /dev/null +++ b/libs/self-update.php @@ -0,0 +1,199 @@ + $current_version, + 'main_plugin_file' => $main_plugin_file, + 'plugin_slug' => $plugin_slug, + 'time' => current_time('mysql') + ]; + + // URL to your Gitea releases API + $gitea_api_url = 'https://repo.anhonesthost.net/api/v1/repos/wp-plugins/fourth-wall-embed-wp/releases/latest'; + + // Use cURL to fetch release data + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $gitea_api_url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_HTTPHEADER, ['Accept: application/json']); + curl_setopt($ch, CURLOPT_USERAGENT, 'WordPress/Fourth-Wall-Plugin-Updater'); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 10); + + $response = curl_exec($ch); + curl_close($ch); + + if ($response) { + $release_info = json_decode($response); + + // Update debug info with latest version + $debug_data['latest_version'] = $release_info->tag_name ?? 'Not found'; + $debug_data['response'] = substr(print_r($release_info, true), 0, 1000); + update_option('fwembed_update_debug', $debug_data); + + // Get latest version from tag name + $latest_version = $release_info->tag_name; + + // Simple version comparison - we want any update to trigger if version is different + if ($current_version != $latest_version) { + // Get the download URL for the ZIP + $download_url = null; + if (isset($release_info->assets) && is_array($release_info->assets)) { + foreach ($release_info->assets as $asset) { + if (isset($asset->name) && strpos($asset->name, '.zip') !== false) { + $download_url = $asset->browser_download_url; + break; + } + } + } + + // Hook into WordPress update system + add_filter('site_transient_update_plugins', function($transient) use ($plugin_slug, $current_version, $latest_version, $download_url) { + // Initialize if needed + if (!is_object($transient)) { + $transient = new stdClass(); + } + if (empty($transient->checked)) { + $transient->checked = []; + } + + // Add our plugin to the checked list + $transient->checked[$plugin_slug] = $current_version; + + if (empty($transient->response)) { + $transient->response = []; + } + + // Add to the update list + $transient->response[$plugin_slug] = (object) [ + 'id' => 'fourthwall-store-embed', + 'slug' => 'fourthwall-store-embed', + 'plugin' => $plugin_slug, + 'new_version' => $latest_version, + 'url' => 'https://repo.anhonesthost.net/wp-plugins/fourth-wall-embed-wp', + 'package' => $download_url, + 'icons' => [], + 'banners' => [], + 'tested' => '6.4.2', + 'requires' => '5.0', + 'compatibility' => new stdClass(), + ]; + + return $transient; + }); + } + } +} +add_action('admin_init', 'fwembed_check_for_updates'); + +// Add admin notice for debugging +add_action('admin_notices', function() { + if (current_user_can('manage_options')) { + $debug = get_option('fwembed_update_debug', []); + echo '

Update Debug: Current: ' . + esc_html($debug['current_version'] ?? 'N/A') . ', Latest: ' . + esc_html($debug['latest_version'] ?? 'N/A') . '

'; + + // Detailed debug info with query param + if (isset($_GET['fwembed_debug'])) { + echo '
' . esc_html(print_r($debug, true)) . '
'; + } + + echo '
'; + } +}); + + +// Add plugin information for the details popup/changelog +add_filter('plugins_api', function($result, $action, $args) { + // Only handle requests for our plugin + $plugin_slug = 'fourthwall-store-embed'; // The slug is directory name + + if ($action !== 'plugin_information' || !isset($args->slug) || $args->slug !== $plugin_slug) { + return $result; + } + + // Get latest release info from Gitea API + $gitea_api_url = 'https://repo.anhonesthost.net/api/v1/repos/wp-plugins/fourth-wall-embed-wp/releases/latest'; + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $gitea_api_url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_HTTPHEADER, ['Accept: application/json']); + curl_setopt($ch, CURLOPT_USERAGENT, 'WordPress/Fourth-Wall-Plugin-Updater'); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 10); + + $response = curl_exec($ch); + curl_close($ch); + + if (!$response) { + return $result; // Keep default result if API call fails + } + + $release_info = json_decode($response); + + // Build plugin info object + $plugin_info = new stdClass(); + $plugin_info->name = 'Fourthwall Store Embed'; + $plugin_info->slug = $plugin_slug; + $plugin_info->version = $release_info->tag_name; + $plugin_info->author = 'Joshua Knapp'; + $plugin_info->homepage = 'https://repo.anhonesthost.net/wp-plugins/fourth-wall-embed-wp'; + $plugin_info->requires = '5.0'; + $plugin_info->tested = '6.8'; + $plugin_info->downloaded = 10; + $plugin_info->last_updated = $release_info->published_at; + + // Format the release notes + $changelog = !empty($release_info->body) ? $release_info->body : 'No changelog provided for this release.'; + + // Handle empty changelog + if (empty(trim($changelog))) { + $changelog = "Version " . $release_info->tag_name . "\n\n" . + "Released on " . date('F j, Y', strtotime($release_info->published_at)) . "\n\n" . + "* Updated plugin files"; + } + + // Format sections for display + $plugin_info->sections = [ + 'description' => '

Embed Fourthwall Store in WordPress.

', + 'changelog' => '
' . esc_html($changelog) . '
', + 'installation' => '

Upload the plugin to your WordPress site and activate it.

' + ]; + + // Download link + $download_url = null; + if (isset($release_info->assets) && is_array($release_info->assets)) { + foreach ($release_info->assets as $asset) { + if (isset($asset->name) && strpos($asset->name, '.zip') !== false) { + $download_url = $asset->browser_download_url; + break; + } + } + } + $plugin_info->download_link = $download_url; + + return $plugin_info; +}, 10, 3);