Pin actions and extension sources to immutable references - #79
Merged
Conversation
Greptile SummaryPins GitHub Actions and PHP extension sources to immutable references while updating the base image, extensions, and corresponding structure-test expectation.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains. Important Files Changed
Reviews (2): Last reviewed commit: "(fix): pin extension sources by commit a..." | Re-trigger Greptile |
A version tag is a mutable pointer: whoever controls an action's repository can repoint v7.0.1 at arbitrary code, and every workflow here runs with the DockerHub push credentials in scope. Pinning by commit SHA makes the resolved code immutable, and the trailing version comment keeps the Dependabot "actions" group able to rewrite both together. Takes each action to its current release while pinning, superseding the open Dependabot bump (#77): checkout 6.0.2 -> 7.0.1, login-action 4 -> 4.6.0, container-structure-test-action 0.1.0 -> 0.3.0, trivy-action 0.35.0 -> 0.36.0, codeql-action 4 -> 4.37.6.
Extensions were built from `git clone --branch <tag>` and `pecl install <package>-<version>`, both of which resolve through a mutable pointer — an upstream tag can be deleted and recreated on a different commit, and the build would silently compile it into an image that runs as the base for every Appwrite service. Each git extension now carries a PHP_*_COMMIT alongside its version and is fetched by that SHA directly (`git init` + `git fetch --depth 1 <url> <sha>`), so the tag is never consulted; protobuf carries a PHP_PROTOBUF_CHECKSUM and its PECL tarball is verified with sha256sum before install. Submodules stay transitively pinned through the parent commit's gitlinks. The version is kept beside each reference so the release it was resolved from stays readable, and so tests.yaml has something to assert against. Everything moves to its latest compatible release in the same pass, since a stale pin is now genuinely frozen: base image digest, brotli 0.18.3 -> 0.20.0, lz4 0.6.0 -> 0.7.0, mongodb 2.2.1 -> 2.3.3, protobuf 5.34.0 -> 5.35.1, scrypt 2.0.1 -> 2.0.2, swoole 6.2.0 -> 6.2.2, xdebug 3.5.1 -> 3.5.3, zstd 0.15.2 -> 0.17.0.
abnegate
force-pushed
the
fix/pin-sources-to-immutable-references
branch
from
August 7, 2026 02:23
500923e to
305e2ef
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Supersedes #77.
Why
Everything this image is built from resolved through a mutable pointer. Actions were referenced by version tag, and extensions by
git clone --branch <tag>/pecl install <package>-<version>. Whoever controls an upstream repository can delete a tag and recreate it on a different commit, and nothing here would notice — the workflows run with DockerHub push credentials in scope, and the extensions get compiled into the base image every Appwrite service runs on.Actions pinned to commit SHAs
Every
uses:now resolves to an immutable commit with the trailing version comment Dependabot rewrites alongside the SHA. Each also moved to its current release, which is what #77 was doing:actions/checkout3d3c42ev7.0.1docker/login-actiondbcb813v4.6.0plexsystems/container-structure-test-actionc0a028av0.3.0aquasecurity/trivy-actioned142fdv0.36.0github/codeql-action/upload-sarif5595ccav4.37.6yuichielectric/dive-actionc2bf5770.0.4 (already latest)Extension sources pinned by commit and checksum
Each git extension carries a
PHP_*_COMMITnext to its version and is fetched by that SHA directly —git init+git fetch --depth 1 <url> <sha>+git checkout FETCH_HEAD. The tag is never consulted, so repointing it cannot change what gets compiled. Protobuf carries aPHP_PROTOBUF_CHECKSUM; its PECL tarball is downloaded andsha256sum -c'd before install. Submodules stay pinned transitively through the parent commit's gitlinks.The version stays beside each reference so the release it was resolved from is readable, and so
tests.yamlhas something to assert against.Everything to its latest compatible version
A stale pin is now genuinely frozen, so everything moves in the same pass: base image digest, brotli 0.18.3 → 0.20.0, lz4 0.6.0 → 0.7.0, mongodb 2.2.1 → 2.3.3, protobuf 5.34.0 → 5.35.1, scrypt 2.0.1 → 2.0.2, swoole 6.2.0 → 6.2.2, xdebug 3.5.1 → 3.5.3, zstd 0.15.2 → 0.17.0.
Verification
Full
docker image buildsucceeded locally. All 17 extensions load, and everytests.yamlassertion passes against the built image — the Swoole assertion moved to 6.2.2 to match. Thexdebugtarget builds too.Follow-ups, not in this PR
#75 needs a matching change before it merges. The weekly updater it introduces parses
PHP_*_VERSIONout of the Dockerfile and rejects any declaration it does not recognise, so once this lands onmainthat updater will fail on the newPHP_*_COMMIT/PHP_PROTOBUF_CHECKSUMdeclarations. The updater-side work — resolving a selected release to a commit or tarball checksum and rewriting both pins together — is written and tested, and belongs on #75's branch rather than here, since none of.github/scripts/exists onmainyet.The published image ships Xdebug.
Dockerfileends withFROM final AS xdebugandbuild-and-push.ymlbuilds with no--target, so Docker picks the last stage — confirmed locally,php -mon a default build listsxdebug. Pre-existing onmain, and changing it changes what consumers ofappwrite/basereceive, so it is tracked separately.🤖 Generated with Claude Code