Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
115 changes: 115 additions & 0 deletions doc/core-update.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# WordPress Core Update & Rollback

`Updater::update()` (in
`vendor/instawp/connect-helpers/src/Updater.php`) handles both forward
core updates and rollbacks to the version installed before the most
recent core upgrade.

It is invoked from the authenticated REST endpoint
`POST /wp-json/instawp-connect/v2/manage/update`
(see `class-instawp-rest-api-manage.php → perform_update()`), which
instantiates `Updater` with the request payload and calls `update()`.

## REST payload shape

The endpoint accepts an array of update entries. Each entry must
include `type` and `slug`. For core, `slug` is `wordpress`.

```json
[
{ "type": "core", "slug": "wordpress", "version": "6.9.4" }
]
```

### Forward update

| Field | Required | Notes |
|-----------|----------|-----------------------------------------------|
| `type` | yes | Must be `core` |
| `slug` | yes | `wordpress` |
| `version` | yes | Exact target WP version to install |

### Rollback

Set either `allow_downgrade: true` or `action: "rollback"`. The caller
must also pass the exact `version` it wants to roll back to — that
version is verified against the plugin's snapshot before anything is
installed.

```json
[
{
"type": "core",
"slug": "wordpress",
"version": "6.8.2",
"action": "rollback"
}
]
```

| Field | Required | Notes |
|-------------------|----------|-----------------------------------------------------------|
| `type` | yes | `core` |
| `slug` | yes | `wordpress` |
| `version` | yes | Must equal the snapshot recorded before the last upgrade |
| `allow_downgrade` | one of | Boolean flag — enables the rollback path |
| `action` | one of | String `"rollback"` — alternative to `allow_downgrade` |

## Plugin-owned snapshot

`Updater::LAST_CORE_VERSION_OPTION` (`wp_options` key
`instawp_last_core_version`) durably stores the version the site was on
immediately before its most recent core upgrade driven by this plugin.
Shape:

```php
[
'version' => '6.8.2', // version BEFORE the last upgrade
'next' => '6.9.4', // version that upgrade installed
'updated_at' => 1715520000,
]
```

The snapshot is written by `core_updater()` right before
`Core_Upgrader::upgrade()` runs, so the plugin always owns the truth
about what a valid rollback target is — independent of what the caller
claims.

`autoload` is set to `false`; the option is only read during upgrade
flows.

## Rollback flow (`core_downgrade()`)

1. Read the snapshot via `get_last_core_version_snapshot()`. If no
snapshot exists, the request is rejected.
2. Compare `args.version` against `snapshot.version`. Mismatch →
reject; the caller cannot pick an arbitrary version to "roll back"
to.
3. HEAD-check the WordPress.org package URL for the target version so
a missing/410'd archive is caught before any install attempt.
4. Hook `site_transient_update_core` to rewrite the offer so
`find_core_update()` returns the rollback target instead of the
newest available version.
5. **Delegate to `core_updater()`** — install/orchestration logic lives
in one place. Strictly DRY: rollback and forward update share the
same `Core_Upgrader` path.
6. Filters are removed in a `finally`-equivalent block whether the
install succeeds or fails, so the transient is never left rewritten.

## Forward update flow (`core_updater()`)

1. Resolve target via `find_core_update( 'latest' )` (or rewritten
offer when invoked from rollback).
2. Write the pre-upgrade snapshot:
`set_last_core_version_snapshot( current, next )`.
3. Run `Core_Upgrader::upgrade()`.
4. Report success with `new_version = success ? args.version : old_version`.

## Caller responsibilities

- `version` must be provided for every core update — the caller pins
the exact target, the plugin does not "pick latest" implicitly.
- For rollback, the caller must read the current state (e.g. via the
site's heartbeat / core details endpoint) to know which version is
valid to request, but the plugin will still verify against its own
snapshot before installing.
4 changes: 2 additions & 2 deletions instawp-connect.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* @wordpress-plugin
* Plugin Name: InstaWP Connect
* Description: 1-click WordPress plugin for Staging, Migrations, Management, Sync and Companion plugin for InstaWP.
* Version: 0.1.3.2
* Version: 0.1.3.3
* Author: InstaWP Team
* Author URI: https://instawp.com/
* License: GPL-3.0+
Expand All @@ -28,7 +28,7 @@

global $wpdb;

defined( 'INSTAWP_PLUGIN_VERSION' ) || define( 'INSTAWP_PLUGIN_VERSION', '0.1.3.2' );
defined( 'INSTAWP_PLUGIN_VERSION' ) || define( 'INSTAWP_PLUGIN_VERSION', '0.1.3.3' );
defined( 'INSTAWP_API_DOMAIN_PROD' ) || define( 'INSTAWP_API_DOMAIN_PROD', 'https://app.instawp.io' );

defined( 'INSTAWP_PLUGIN_URL' ) || define( 'INSTAWP_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
Expand Down
5 changes: 4 additions & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Tags: clone, migrate, staging, backup, restore
Requires at least: 5.6
Tested up to: 6.9
Requires PHP: 7.0
Stable tag: 0.1.3.2
Stable tag: 0.1.3.3
License: GPLv3 or later
License URI: https://www.gnu.org/licenses/gpl-3.0.en.html

Expand Down Expand Up @@ -99,6 +99,9 @@ You can report security bugs through the Patchstack Vulnerability Disclosure Pro
== Changelog ==


= 0.1.3.3 - Beta =
- Added: WordPress core rollback support — the plugin now snapshots the current core version before every core upgrade and can roll back to that recorded version on request.

= 0.1.3.2 - 12 May 2026 =
- Security: Migration files on the destination site now use unguessable hashed filenames for stronger privacy.
- Improved: Each push migration automatically cleans up leftover artifact files at start for a cleaner destination site.
Expand Down
38 changes: 19 additions & 19 deletions vendor/composer/installed.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@
"source": {
"type": "git",
"url": "https://github.com/InstaWP/connect-helpers.git",
"reference": "d86499211ea400619409c64243f1103d723873c0"
"reference": "e88699574d7a7defb2690de7cf17d42e7ef9c9b2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/InstaWP/connect-helpers/zipball/d86499211ea400619409c64243f1103d723873c0",
"reference": "d86499211ea400619409c64243f1103d723873c0",
"url": "https://api.github.com/repos/InstaWP/connect-helpers/zipball/e88699574d7a7defb2690de7cf17d42e7ef9c9b2",
"reference": "e88699574d7a7defb2690de7cf17d42e7ef9c9b2",
"shasum": ""
},
"require": {
"php": ">= 5.6",
"wp-cli/wp-config-transformer": "^1.3"
},
"time": "2026-03-30T12:37:16+00:00",
"time": "2026-05-13T13:23:13+00:00",
"default-branch": true,
"type": "library",
"installation-source": "dist",
Expand Down Expand Up @@ -47,7 +47,7 @@
],
"description": "CLI Package for InstaWP Remote Features",
"support": {
"source": "https://github.com/InstaWP/connect-helpers/tree/1.1.0",
"source": "https://github.com/InstaWP/connect-helpers/tree/main",
"issues": "https://github.com/InstaWP/connect-helpers/issues"
},
"install-path": "../instawp/connect-helpers"
Expand Down Expand Up @@ -177,17 +177,17 @@
},
{
"name": "phpseclib/phpseclib",
"version": "3.0.50",
"version_normalized": "3.0.50.0",
"version": "3.0.52",
"version_normalized": "3.0.52.0",
"source": {
"type": "git",
"url": "https://github.com/phpseclib/phpseclib.git",
"reference": "aa6ad8321ed103dc3624fb600a25b66ebf78ec7b"
"reference": "2adaefc83df2ec548558307690f376dd7d4f4fce"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/aa6ad8321ed103dc3624fb600a25b66ebf78ec7b",
"reference": "aa6ad8321ed103dc3624fb600a25b66ebf78ec7b",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/2adaefc83df2ec548558307690f376dd7d4f4fce",
"reference": "2adaefc83df2ec548558307690f376dd7d4f4fce",
"shasum": ""
},
"require": {
Expand All @@ -205,7 +205,7 @@
"ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
"ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations."
},
"time": "2026-03-19T02:57:58+00:00",
"time": "2026-04-27T07:02:15+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
Expand Down Expand Up @@ -270,7 +270,7 @@
],
"support": {
"issues": "https://github.com/phpseclib/phpseclib/issues",
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.50"
"source": "https://github.com/phpseclib/phpseclib/tree/3.0.52"
},
"funding": [
{
Expand Down Expand Up @@ -336,17 +336,17 @@
},
{
"name": "wp-cli/wp-config-transformer",
"version": "v1.4.5",
"version_normalized": "1.4.5.0",
"version": "v1.4.6",
"version_normalized": "1.4.6.0",
"source": {
"type": "git",
"url": "https://github.com/wp-cli/wp-config-transformer.git",
"reference": "8f5e66c717a7371dfb6559086880bee528aee858"
"reference": "1ef18784990b85b35202c2d68dbbc4a8fe6615b6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/wp-cli/wp-config-transformer/zipball/8f5e66c717a7371dfb6559086880bee528aee858",
"reference": "8f5e66c717a7371dfb6559086880bee528aee858",
"url": "https://api.github.com/repos/wp-cli/wp-config-transformer/zipball/1ef18784990b85b35202c2d68dbbc4a8fe6615b6",
"reference": "1ef18784990b85b35202c2d68dbbc4a8fe6615b6",
"shasum": ""
},
"require": {
Expand All @@ -355,7 +355,7 @@
"require-dev": {
"wp-cli/wp-cli-tests": "^4.0 || ^5.0"
},
"time": "2026-03-20T07:28:10+00:00",
"time": "2026-04-10T07:32:03+00:00",
"type": "library",
"extra": {
"branch-alias": {
Expand All @@ -382,7 +382,7 @@
"homepage": "https://github.com/wp-cli/wp-config-transformer",
"support": {
"issues": "https://github.com/wp-cli/wp-config-transformer/issues",
"source": "https://github.com/wp-cli/wp-config-transformer/tree/v1.4.5"
"source": "https://github.com/wp-cli/wp-config-transformer/tree/v1.4.6"
},
"install-path": "../wp-cli/wp-config-transformer"
}
Expand Down
26 changes: 13 additions & 13 deletions vendor/composer/installed.php
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
<?php return array(
'root' => array(
'name' => 'instawp/connect',
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
'reference' => '938e2e37a2f9badba7adac588b26452beecf0e26',
'pretty_version' => '1.0.0+no-version-set',
'version' => '1.0.0.0',
'reference' => null,
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev' => true,
),
'versions' => array(
'instawp/connect' => array(
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
'reference' => '938e2e37a2f9badba7adac588b26452beecf0e26',
'pretty_version' => '1.0.0+no-version-set',
'version' => '1.0.0.0',
'reference' => null,
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
Expand All @@ -22,7 +22,7 @@
'instawp/connect-helpers' => array(
'pretty_version' => 'dev-main',
'version' => 'dev-main',
'reference' => 'd86499211ea400619409c64243f1103d723873c0',
'reference' => 'e88699574d7a7defb2690de7cf17d42e7ef9c9b2',
'type' => 'library',
'install_path' => __DIR__ . '/../instawp/connect-helpers',
'aliases' => array(
Expand All @@ -49,9 +49,9 @@
'dev_requirement' => false,
),
'phpseclib/phpseclib' => array(
'pretty_version' => '3.0.50',
'version' => '3.0.50.0',
'reference' => 'aa6ad8321ed103dc3624fb600a25b66ebf78ec7b',
'pretty_version' => '3.0.52',
'version' => '3.0.52.0',
'reference' => '2adaefc83df2ec548558307690f376dd7d4f4fce',
'type' => 'library',
'install_path' => __DIR__ . '/../phpseclib/phpseclib',
'aliases' => array(),
Expand All @@ -67,9 +67,9 @@
'dev_requirement' => false,
),
'wp-cli/wp-config-transformer' => array(
'pretty_version' => 'v1.4.5',
'version' => '1.4.5.0',
'reference' => '8f5e66c717a7371dfb6559086880bee528aee858',
'pretty_version' => 'v1.4.6',
'version' => '1.4.6.0',
'reference' => '1ef18784990b85b35202c2d68dbbc4a8fe6615b6',
'type' => 'library',
'install_path' => __DIR__ . '/../wp-cli/wp-config-transformer',
'aliases' => array(),
Expand Down
6 changes: 6 additions & 0 deletions vendor/instawp/connect-helpers/changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
v1.1.1
======
- Added: WordPress core rollback support.
- Added: Pre-upgrade core version snapshot for verified rollback targets.
- Improved: Core update verification logic.

v1.1.0
======
- Fixed: Improved response details
Expand Down
2 changes: 1 addition & 1 deletion vendor/instawp/connect-helpers/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "instawp/connect-helpers",
"description": "CLI Package for InstaWP Remote Features",
"type": "library",
"version": "1.0.8",
"version": "1.1.1",
"license": "MIT",
"authors": [
{
Expand Down
2 changes: 1 addition & 1 deletion vendor/instawp/connect-helpers/connect-helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*
* @wordpress-plugin
* Plugin Name: InstaWP Connect Helpers
* Version: 1.1.0
* Version: 1.1.1
* Plugin URI: https://instawp.com
* Description: Helpers Package for InstaWP Remote Features.
* Author: InstaWP
Expand Down
Loading
Loading