Fix rollback for symlink-based PHP deployments #36

Open
opened 2026-09-07 22:13:00 +00:00 by Xeplosion · 1 comment
Owner

What happened?

The shared rollback workflow assumes that the deployed application can be restored using Git operations against the deployed directory.

Managed PHP deployments use a release-directory model where deployed versions live in separate release directories and the active application is selected through a current symlink.

As a result, the generic Git-based rollback process does not correctly restore the previous PHP release.

Steps to reproduce

  1. Deploy a PHP repository using the managed symlink/release-directory deployment strategy.
  2. Complete at least two successful deployments so a previous release exists.
  3. Trigger the shared rollback workflow manually, or trigger an automatic rollback after failed deployment validation.
  4. Observe that rollback attempts to use the generic Git-working-tree behavior.
  5. Verify that the active current symlink is not correctly restored to the previous known-good release.

Expected behavior

Rollback should restore the previous valid deployment using the strategy appropriate to the stack.

For a symlink-based PHP deployment, rollback should:

  1. identify the active release;
  2. identify the previous valid release;
  3. safely repoint current to the previous release;
  4. perform any required stack/service reload;
  5. run the configured health validation;
  6. report success only when the restored deployment passes validation.

The shared rollback workflow should orchestrate rollback without embedding assumptions that every stack deploys from a Git working tree.

Environment / affected version

  • Repository: .forgejo
  • Component: shared rollback workflow
  • Managed template: PHP
  • Deployment strategy: versioned release directories with an active current symlink
  • Affected paths: manual rollback and automatic rollback after failed deployment validation

Affected branch(es)

  • main — shared/canonical rollback orchestration
  • template-php — PHP-specific rollback implementation

Additional context

A stack-specific rollback script is preferred over placing PHP-specific deployment logic directly inside the shared workflow.

Reporter checklist

  • I searched for an existing issue covering this problem
  • I included enough information to investigate or reproduce the problem
  • I did not include credentials, secrets, or other sensitive information

Workflow lifecycle

Triage

  • Kind/ classification confirmed
  • Issue validity reviewed and appropriate Reviewed/ label assigned
  • Priority/ assigned when appropriate
  • Implementation branch referenced on the issue through Forgejo when applicable
  • Information requirements resolved; no Status/Needs More Info remains
  • Status/Needs Triage removed before leaving Triage

Backlog

  • Issue is confirmed valid and accepted into the project backlog

To Do

  • Scope and expected outcome are sufficiently defined
  • Known prerequisites, dependencies, and required decisions are resolved or understood
  • Work has been deliberately selected as upcoming work

In Progress

  • Assignee or active owner identified when appropriate
  • Forgejo timer started when time tracking provides meaningful value
  • Relevant implementation, research, or work notes recorded as needed
  • Forgejo timer stopped when active work ends, pauses, or becomes blocked

Review Gate

  • Review requirement assessed based on complexity, criticality, reversibility, and impact
  • If review is required: moved to In Review and appropriate testing / validation performed
  • If review is required: review comment records what was reviewed, how it was validated, findings, and outcome
  • If review is not required: rationale is evident from the low-risk nature of the change

Completed

  • Acceptance criteria / intended outcome satisfied
  • Related PRs, commits, documentation, or external changes linked where applicable
  • Final resolution comment explains what changed, how the issue was resolved, and how it was verified
  • Follow-up work split into separate issues where appropriate
  • Any Forgejo timer is stopped and recorded time is final
  • Issue moved to Completed and closed
### What happened? The shared rollback workflow assumes that the deployed application can be restored using Git operations against the deployed directory. Managed PHP deployments use a release-directory model where deployed versions live in separate release directories and the active application is selected through a `current` symlink. As a result, the generic Git-based rollback process does not correctly restore the previous PHP release. ### Steps to reproduce 1. Deploy a PHP repository using the managed symlink/release-directory deployment strategy. 2. Complete at least two successful deployments so a previous release exists. 3. Trigger the shared rollback workflow manually, or trigger an automatic rollback after failed deployment validation. 4. Observe that rollback attempts to use the generic Git-working-tree behavior. 5. Verify that the active `current` symlink is not correctly restored to the previous known-good release. ### Expected behavior Rollback should restore the previous valid deployment using the strategy appropriate to the stack. For a symlink-based PHP deployment, rollback should: 1. identify the active release; 2. identify the previous valid release; 3. safely repoint `current` to the previous release; 4. perform any required stack/service reload; 5. run the configured health validation; 6. report success only when the restored deployment passes validation. The shared rollback workflow should orchestrate rollback without embedding assumptions that every stack deploys from a Git working tree. ### Environment / affected version * Repository: `.forgejo` * Component: shared rollback workflow * Managed template: PHP * Deployment strategy: versioned release directories with an active `current` symlink * Affected paths: manual rollback and automatic rollback after failed deployment validation ### Affected branch(es) * `main` — shared/canonical rollback orchestration * `template-php` — PHP-specific rollback implementation ### Additional context A stack-specific rollback script is preferred over placing PHP-specific deployment logic directly inside the shared workflow. ### Reporter checklist - [x] I searched for an existing issue covering this problem - [x] I included enough information to investigate or reproduce the problem - [x] I did not include credentials, secrets, or other sensitive information ### Workflow lifecycle ### Triage - [ ] `Kind/` classification confirmed - [ ] Issue validity reviewed and appropriate `Reviewed/` label assigned - [ ] `Priority/` assigned when appropriate - [ ] Implementation branch referenced on the issue through Forgejo when applicable - [ ] Information requirements resolved; no `Status/Needs More Info` remains - [ ] `Status/Needs Triage` removed before leaving Triage ### Backlog - [ ] Issue is confirmed valid and accepted into the project backlog ### To Do - [ ] Scope and expected outcome are sufficiently defined - [ ] Known prerequisites, dependencies, and required decisions are resolved or understood - [ ] Work has been deliberately selected as upcoming work ### In Progress - [ ] Assignee or active owner identified when appropriate - [ ] Forgejo timer started when time tracking provides meaningful value - [ ] Relevant implementation, research, or work notes recorded as needed - [ ] Forgejo timer stopped when active work ends, pauses, or becomes blocked ### Review Gate - [ ] Review requirement assessed based on complexity, criticality, reversibility, and impact - [ ] If review is required: moved to **In Review** and appropriate testing / validation performed - [ ] If review is required: review comment records what was reviewed, how it was validated, findings, and outcome - [ ] If review is not required: rationale is evident from the low-risk nature of the change ### Completed - [ ] Acceptance criteria / intended outcome satisfied - [ ] Related PRs, commits, documentation, or external changes linked where applicable - [ ] Final resolution comment explains what changed, how the issue was resolved, and how it was verified - [ ] Follow-up work split into separate issues where appropriate - [ ] Any Forgejo timer is stopped and recorded time is final - [ ] Issue moved to **Completed** and closed
Author
Owner

Investigation / implementation checklist

Confirm current behavior

  • Review the current shared rollback workflow.
  • Identify every Git-working-tree assumption.
  • Review the current PHP deployment implementation.
  • Confirm how release directories are named and retained.
  • Confirm how the active current symlink is updated.

Define the rollback contract

  • Decide how the shared workflow delegates stack-specific rollback.
  • Define the expected stack rollback interface.
  • Define success and failure exit behavior.
  • Define behavior when no previous valid release exists.
  • Define post-rollback validation requirements.

Implement PHP rollback

  • Identify the active release.
  • Identify the previous valid release.
  • Reject incomplete or invalid candidate releases.
  • Update the current symlink safely.
  • Perform required service reload/restart behavior.
  • Preserve the failed release for diagnosis where appropriate.
  • Avoid deleting release history as part of normal rollback.

Regression validation

  • Test manual rollback.
  • Test automatic rollback after failed deployment.
  • Verify current points at the expected release.
  • Verify the restored application passes health checks.
  • Test behavior when no previous release exists.
  • Test rollback failure handling.
  • Confirm existing non-PHP rollback behavior still works.
  • Validate through the workflow-validation repository when available.

Follow-up

  • Document the stack-specific rollback contract.
  • Update PHP template documentation as needed.
  • Review whether any other stack needs a custom rollback implementation.
  • Split unrelated stack-specific work into separate issues.
### Investigation / implementation checklist #### Confirm current behavior * [ ] Review the current shared rollback workflow. * [ ] Identify every Git-working-tree assumption. * [ ] Review the current PHP deployment implementation. * [ ] Confirm how release directories are named and retained. * [ ] Confirm how the active `current` symlink is updated. #### Define the rollback contract * [ ] Decide how the shared workflow delegates stack-specific rollback. * [ ] Define the expected stack rollback interface. * [ ] Define success and failure exit behavior. * [ ] Define behavior when no previous valid release exists. * [ ] Define post-rollback validation requirements. #### Implement PHP rollback * [ ] Identify the active release. * [ ] Identify the previous valid release. * [ ] Reject incomplete or invalid candidate releases. * [ ] Update the `current` symlink safely. * [ ] Perform required service reload/restart behavior. * [ ] Preserve the failed release for diagnosis where appropriate. * [ ] Avoid deleting release history as part of normal rollback. #### Regression validation * [ ] Test manual rollback. * [ ] Test automatic rollback after failed deployment. * [ ] Verify `current` points at the expected release. * [ ] Verify the restored application passes health checks. * [ ] Test behavior when no previous release exists. * [ ] Test rollback failure handling. * [ ] Confirm existing non-PHP rollback behavior still works. * [ ] Validate through the workflow-validation repository when available. #### Follow-up * [ ] Document the stack-specific rollback contract. * [ ] Update PHP template documentation as needed. * [ ] Review whether any other stack needs a custom rollback implementation. * [ ] Split unrelated stack-specific work into separate issues.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
XeplosionTechnologies/.forgejo#36
No description provided.