|
| 1 | +--- |
| 2 | +description: Safely update this project's Dockerfile dependencies and tooling in isolated commits |
| 3 | +name: update-project |
| 4 | +--- |
| 5 | + |
| 6 | +# Goal |
| 7 | + |
| 8 | +Perform a full dependency update across all three Dockerfile variants (fpm, apache, frankenphp) in a safe, |
| 9 | +reproducible way. |
| 10 | + |
| 11 | +**Critical rule:** Any version that appears in more than one Dockerfile must be updated across all affected |
| 12 | +Dockerfiles in a single commit. Never update a shared version in only one Dockerfile. |
| 13 | + |
| 14 | +If any step fails, STOP immediately and report the error. |
| 15 | + |
| 16 | +## Phase 1 --- Repository Safety Checks |
| 17 | + |
| 18 | +1. Verify the current branch is `main`. If not, abort and instruct the user to switch to `main` first. |
| 19 | +2. Ensure the working (git) tree is clean: |
| 20 | + - No staged changes |
| 21 | + - No unstaged changes |
| 22 | + - No untracked files |
| 23 | + - If not clean: Abort immediately — inform the user to commit or stash changes. |
| 24 | +3. Synchronize with remote: `git fetch --prune` |
| 25 | +4. Prepare branch `updates`: |
| 26 | + - If branch does not exist → create from `origin/main` |
| 27 | + - If branch exists: |
| 28 | + - If fully merged into `main` → delete locally and recreate from `origin/main`. |
| 29 | + - If behind `main` and has NO unique commits → reset `updates` to `origin/main`. |
| 30 | + - If it contains unique commits → abort and notify user. |
| 31 | +5. Check if the branch does not already exist on the remote. If it does, abort and inform the user to delete |
| 32 | +the remote branch first. |
| 33 | + |
| 34 | +Always branch from latest `origin/main`. |
| 35 | + |
| 36 | +## Phase 2 --- PHP Base Image Updates |
| 37 | + |
| 38 | +The three Dockerfiles use different base images but all track the same PHP 8.4.x patch series: |
| 39 | + |
| 40 | +- `fpm/Dockerfile`: `FROM php:<version>-fpm-trixie` |
| 41 | +- `apache/Dockerfile`: `FROM php:<version>-apache-trixie` |
| 42 | +- `frankenphp/Dockerfile`: `FROM dunglas/frankenphp:<frankenphp-version>-php<php-version>-trixie` |
| 43 | + |
| 44 | +1. Check Docker Hub for the latest `php:8.4.x-fpm-trixie` tag. Only consider patch updates within the |
| 45 | +`8.4.x` series — do not update to a different minor or major PHP version. |
| 46 | +2. Check Docker Hub for the latest `dunglas/frankenphp` tag that matches the pattern |
| 47 | +`x.x.x-php8.4.x-trixie`. Only consider updates that keep the PHP 8.4.x series. |
| 48 | +3. Update the `FROM` lines in all three Dockerfiles if newer versions are available. |
| 49 | +4. Check `git status`. Commit all three Dockerfiles together in a single commit if there are any changes. |
| 50 | + Commit message: `chore(deps): Update PHP base image versions`. |
| 51 | +5. If there are no changes, skip the commit and move on. |
| 52 | + |
| 53 | +Abort on any failure. |
| 54 | + |
| 55 | +## Phase 3 --- Pie Tool Update |
| 56 | + |
| 57 | +All three Dockerfiles pin the same Pie version via: |
| 58 | + |
| 59 | +``` |
| 60 | +COPY --from=ghcr.io/php/pie:<version>-bin /pie /usr/bin/pie |
| 61 | +``` |
| 62 | + |
| 63 | +1. Check the GitHub Releases API for the latest release of `php/pie`. |
| 64 | +2. If a newer version is available, update the `ghcr.io/php/pie:<version>-bin` reference in all three |
| 65 | +Dockerfiles. |
| 66 | +3. Check `git status`. Commit all three Dockerfiles together in a single commit if there are any changes. |
| 67 | + Commit message: `chore(deps): Update Pie version`. |
| 68 | +4. If there are no changes, skip the commit and move on. |
| 69 | + |
| 70 | +Abort on any failure. |
| 71 | + |
| 72 | +## Phase 4 --- PHP Runtime Extension Updates |
| 73 | + |
| 74 | +All three Dockerfiles share the same versions for the following PHP extensions (runtime stage ARGs): |
| 75 | + |
| 76 | +- `PHP_EVENT_VERSION` — `osmanov/pecl-event` on Packagist |
| 77 | +- `PHP_IGBINARY_VERSION` — `igbinary/igbinary` on Packagist |
| 78 | +- `PHP_REDIS_VERSION` — `phpredis/phpredis` on Packagist |
| 79 | +- `PHP_AMQP_VERSION` — `php-amqp/php-amqp` on Packagist |
| 80 | + |
| 81 | +Process each extension individually and in order: |
| 82 | + |
| 83 | +1. Query the Packagist API for the latest stable release of the extension. |
| 84 | +2. If a newer version is available, update the corresponding `ARG` in all three Dockerfiles. |
| 85 | +3. Commit all three Dockerfiles together in a single commit. |
| 86 | + Commit message: `chore(deps): Update <package-name> to <new-version>`. |
| 87 | + For example: `chore(deps): Update phpredis/phpredis to 6.4.0`. |
| 88 | +4. If there is no update for this extension, skip the commit and move on to the next extension. |
| 89 | + |
| 90 | +Repeat for every extension. Each updated extension gets its own commit. |
| 91 | + |
| 92 | +Abort on any failure. |
| 93 | + |
| 94 | +## Phase 5 --- Builder Stage Tool Updates |
| 95 | + |
| 96 | +All three Dockerfiles share the same versions for the following builder-stage tools: |
| 97 | + |
| 98 | +- `PHIVE_VERSION` — check the GitHub Releases API for `phar-io/phive` |
| 99 | +- `COMPOSER_VERSION` — check `https://getcomposer.org/download/` or the GitHub Releases API for |
| 100 | +`composer/composer` |
| 101 | +- `XDEBUG_VERSION` — `xdebug/xdebug` on Packagist |
| 102 | +- `PCOV_VERSION` — `pecl/pcov` on Packagist |
| 103 | + |
| 104 | +Process each tool individually and in order: |
| 105 | + |
| 106 | +1. Look up the latest stable release of the tool. |
| 107 | +2. If a newer version is available, update the corresponding `ARG` in all three Dockerfiles. |
| 108 | +3. Commit all three Dockerfiles together in a single commit. |
| 109 | + Commit message: `chore(deps): Update <tool-name> to <new-version>`. |
| 110 | + For example: `chore(deps): Update Composer to 2.10.0`. |
| 111 | +4. If there is no update for this tool, skip the commit and move on to the next tool. |
| 112 | + |
| 113 | +Repeat for every tool. Each updated tool gets its own commit. |
| 114 | + |
| 115 | +Abort on any failure. |
| 116 | + |
| 117 | +## Phase 6 --- Node.js Major Version Update |
| 118 | + |
| 119 | +All three Dockerfiles pin `ARG NODE_MAJOR=<version>` for the `builder_nodejs` stage. |
| 120 | + |
| 121 | +1. Check the Node.js release schedule at `https://nodejs.org/en/about/previous-releases` to find the |
| 122 | +current Active LTS major version. |
| 123 | +2. Only update `NODE_MAJOR` if a newer **Active LTS** major version is available. Do not update to a |
| 124 | +Current (non-LTS) release. |
| 125 | +3. If a newer Active LTS major is available, update `NODE_MAJOR` in all three Dockerfiles. |
| 126 | +4. Check `git status`. Commit all three Dockerfiles together in a single commit if there are any changes. |
| 127 | + Commit message: `chore(deps): Update Node.js major version to <version>`. |
| 128 | +5. If there are no changes, skip the commit and move on. |
| 129 | + |
| 130 | +Abort on any failure. |
| 131 | + |
| 132 | +## Phase 7 --- Hadolint Version Update |
| 133 | + |
| 134 | +The `Taskfile.dist.yml` pins the Hadolint Docker image version via the `HADOLINT_TAG_VERSION` variable. |
| 135 | + |
| 136 | +1. Check the GitHub Releases API for the latest release of `hadolint/hadolint`. |
| 137 | +2. If a newer version is available, update `HADOLINT_TAG_VERSION` in `Taskfile.dist.yml`. |
| 138 | +3. Check `git status`. Commit if there are any changes. |
| 139 | + Commit message: `chore(deps): Update Hadolint version`. |
| 140 | +4. If there are no changes, skip the commit and move on. |
| 141 | + |
| 142 | +Abort on any failure. |
| 143 | + |
| 144 | +## Phase 8 --- GitHub Actions Updates |
| 145 | + |
| 146 | +1. Scan the following files for pinned `uses:` action references: |
| 147 | + - `.github/workflows/*.yml` |
| 148 | +2. For each external action (e.g. `specsnl/github-actions/.github/workflows/build-php.yml@1.1.1`), use |
| 149 | +the GitHub Releases API to find the latest release tag. Check every action individually — do not assume |
| 150 | +a version is already current. |
| 151 | + - If the reference uses a floating major-version tag (e.g. `@v6`) and that major version is already |
| 152 | + the latest, leave it as-is. |
| 153 | + - If the reference is pinned to a specific semver tag (e.g. `@1.1.1`, `@v2.5.0`) and a newer version |
| 154 | + exists, update it to the latest release tag. |
| 155 | + - If the reference is pinned to a commit SHA, leave it as-is. |
| 156 | +3. Update any outdated action versions in-place across all scanned files. |
| 157 | +4. Check `git status`. Commit separately if there are any changes. |
| 158 | + Commit message: `chore(deps): Update GitHub Actions versions`. |
| 159 | +5. If there are no changes, skip the commit and move on. |
| 160 | + |
| 161 | +Abort on any failure. |
| 162 | + |
| 163 | +## Phase 9 --- License Year Update |
| 164 | + |
| 165 | +1. Check if the `LICENSE` file contains a year range (e.g. `2020-2025`) or a single year (e.g. `2024`). |
| 166 | +2. If the current year (2026) is not already the end year: |
| 167 | + - Single year (e.g. `2024`) → update to `2026`. |
| 168 | + - Year range (e.g. `2020-2025`) → update the end year to `2026`. |
| 169 | +3. Commit separately if there are any changes. |
| 170 | + Commit message: `chore: Update copyright year`. |
| 171 | +4. If there are no changes, skip the commit and move on. |
| 172 | + |
| 173 | +------------------------------------------------------------------------ |
| 174 | + |
| 175 | +## Final State |
| 176 | + |
| 177 | +Abort if there are no changes after all update steps, and inform the user that everything is already up |
| 178 | +to date. |
| 179 | + |
| 180 | +- There could be up to 14 commits on the `updates` branch: |
| 181 | + 1. PHP base image versions |
| 182 | + 2. Pie tool version |
| 183 | + 3. PHP runtime extension: osmanov/pecl-event |
| 184 | + 4. PHP runtime extension: igbinary/igbinary |
| 185 | + 5. PHP runtime extension: phpredis/phpredis |
| 186 | + 6. PHP runtime extension: php-amqp/php-amqp |
| 187 | + 7. Builder tool: Phive |
| 188 | + 8. Builder tool: Composer |
| 189 | + 9. Builder tool: Xdebug |
| 190 | + 10. Builder tool: pcov |
| 191 | + 11. Node.js major version |
| 192 | + 12. Hadolint version |
| 193 | + 13. GitHub Actions versions |
| 194 | + 14. Copyright year |
| 195 | +- Branch: `updates` |
| 196 | +- Based on latest `origin/main`. |
| 197 | +- The working tree should be clean. |
| 198 | +- Push the branch to the remote and create a pull request for review and merging targeting `origin/main`. |
| 199 | + The title should be `chore: Update dependencies`. |
| 200 | +- Add a Pull Request description that lists the changes based on the commits that were made. Stick to the |
| 201 | + commit messages but remove the "chore" prefix. For example: |
| 202 | + |
| 203 | +```md |
| 204 | +Updated the following dependencies: |
| 205 | + |
| 206 | +- Updated PHP base image versions |
| 207 | +- Updated Pie version |
| 208 | +- Updated PHP runtime extension versions |
| 209 | +- Updated builder stage tool versions |
| 210 | +- Updated GitHub Actions versions |
| 211 | +``` |
0 commit comments