Skip to content

Pin actions and extension sources to immutable references - #79

Merged
abnegate merged 2 commits into
mainfrom
fix/pin-sources-to-immutable-references
Aug 7, 2026
Merged

Pin actions and extension sources to immutable references#79
abnegate merged 2 commits into
mainfrom
fix/pin-sources-to-immutable-references

Conversation

@abnegate

@abnegate abnegate commented Aug 7, 2026

Copy link
Copy Markdown
Member

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:

Action Was Now
actions/checkout v6.0.2 3d3c42e v7.0.1
docker/login-action v4 dbcb813 v4.6.0
plexsystems/container-structure-test-action v0.1.0 c0a028a v0.3.0
aquasecurity/trivy-action 0.35.0 ed142fd v0.36.0
github/codeql-action/upload-sarif v4 5595cca v4.37.6
yuichielectric/dive-action 0.0.4 c2bf577 0.0.4 (already latest)

Extension sources pinned by commit and checksum

Each git extension carries a PHP_*_COMMIT next 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 a PHP_PROTOBUF_CHECKSUM; its PECL tarball is downloaded and sha256sum -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.yaml has 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 build succeeded locally. All 17 extensions load, and every tests.yaml assertion passes against the built image — the Swoole assertion moved to 6.2.2 to match. The xdebug target builds too.

Follow-ups, not in this PR

#75 needs a matching change before it merges. The weekly updater it introduces parses PHP_*_VERSION out of the Dockerfile and rejects any declaration it does not recognise, so once this lands on main that updater will fail on the new PHP_*_COMMIT / PHP_PROTOBUF_CHECKSUM declarations. 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 on main yet.

The published image ships Xdebug. Dockerfile ends with FROM final AS xdebug and build-and-push.yml builds with no --target, so Docker picks the last stage — confirmed locally, php -m on a default build lists xdebug. Pre-existing on main, and changing it changes what consumers of appwrite/base receive, so it is tracked separately.

🤖 Generated with Claude Code

@abnegate
abnegate changed the base branch from agent/php-dependency-automation to main August 7, 2026 02:20
@greptile-apps

greptile-apps Bot commented Aug 7, 2026

Copy link
Copy Markdown

Greptile Summary

Pins GitHub Actions and PHP extension sources to immutable references while updating the base image, extensions, and corresponding structure-test expectation.

  • Replaces mutable action tags with full commit SHAs.
  • Fetches Git-based PHP extensions by commit and verifies the Protobuf PECL tarball by checksum.
  • Updates extension versions and the expected Swoole version.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
Dockerfile Pins extension sources to commits or a verified checksum, updates dependencies, and preserves the existing build-stage structure.
.github/workflows/build-and-push.yml Pins checkout and Docker login actions to immutable release commits.
.github/workflows/dive.yml Pins checkout and Dive actions without changing workflow behavior.
.github/workflows/structure-test.yml Pins checkout and container structure test actions to immutable release commits.
.github/workflows/trivy.yml Pins the checkout, Trivy, and SARIF upload actions without changing scan configuration.
tests.yaml Updates the expected Swoole version to match the newly pinned extension release.

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
abnegate force-pushed the fix/pin-sources-to-immutable-references branch from 500923e to 305e2ef Compare August 7, 2026 02:23
@abnegate
abnegate merged commit d5776be into main Aug 7, 2026
11 checks passed
@abnegate
abnegate deleted the fix/pin-sources-to-immutable-references branch August 7, 2026 02:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant