Skip to content

Commit 04a45bd

Browse files
committed
Revamp CI; fix leak and build failure
1 parent 508acf8 commit 04a45bd

7 files changed

Lines changed: 168 additions & 55 deletions

File tree

.github/docker-image-shas.yml

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22
# Maps image tags to their multi-arch OCI index digests (amd64 + arm64).
33
# Regenerate with: .github/scripts/update-docker-shas.sh
44

5-
datadog/dd-appsec-php-ci:
6-
php-8.0-debug: "sha256:900ceae7487db1e3652de2880c181e572fdf053673bcda8ff47abf664ff74d39"
7-
php-8.0-release-zts: "sha256:b6243199f6aea0792a97583c9036f0b191ad9efb96ea337632fbaca76289a4da"
8-
php-8.1-debug: "sha256:1a1e5b44cf043e59768c65fd7c94aaefdacde5fa96d83102d35db11ad86f24c6"
9-
php-8.1-release-zts: "sha256:5b8a269b4228d9191420059daef820b660110be0aca6776557924172fd1ff0c8"
10-
php-8.2-debug: "sha256:52ad14560672fc8c5130f5758bbee3fa401bc1d35b412f4a230c6258143291a5"
11-
php-8.2-release-zts: "sha256:cb143d915b394f16a2d78018765705460f3d1b788fdd2a90ef50fad5f8f5918c"
12-
php-8.3-debug: "sha256:bb6df08160126374d3d9247428928aa19a9c2b2429c98356650199b85ae20212"
13-
php-8.3-release-zts: "sha256:e58e25a017f75df82691d408b8cb70453875ff36718e295ee8c6653a0f117331"
14-
php-8.4-debug: "sha256:15045688f6986f4625b1507a7f4be6104e7bbb88caf877f1611463b929f2bca2"
15-
php-8.4-release-zts: "sha256:8e0ac25a3306b4b9f692c593b8a509cc789c2e001ce52682928065a92c880136"
16-
php-8.5-debug: "sha256:bd0170331b34fb469e29d00b19b20fb88b726160f76df274a1bdc3a27ac18d30"
17-
php-8.5-release-zts: "sha256:e071b2095da55bd24686209422f43a01c65acfc6021f04156d9fb43fd3d4d426"
5+
ghcr.io/cataphract/php-minimal:
6+
8.0-debug: "sha256:d46c15e648497cf55bb6b4806c726c58714f5b63fcb1096e4a8ec433ec17c835"
7+
8.0-release-zts: "sha256:bcbaab72e7c0e704d7bdef01e8f91e1bc0636e6e98c0ab68cc2fc417e7a98a66"
8+
8.1-debug: "sha256:dbdb437df0a4acbbd11e020461f7cef2f0e949f46f9ca841c5f058012ec7cc98"
9+
8.1-release-zts: "sha256:2b330ce54679f29e09ea77c984cd409618142cc20cab48b5a114cc1e5b09257c"
10+
8.2-debug: "sha256:efecf1cdbd09511aec12897a03682934243498c5bb2ba37874ae2100c1498011"
11+
8.2-release-zts: "sha256:d67d1c370abdc5e629a2bec1ff4d308f0ccb7d3cbc7ecc3c7eee851cd6c2efaa"
12+
8.3-debug: "sha256:1b8e6ba17c837a4035f6981dd38f9f447be57a3d558ca8f18071c8390a62ce6c"
13+
8.3-release: "sha256:23abac21af8c95ccd6cd6a8b5fbb2d1dd67e122fc7630bbbfcc7b75e6a6fcc96"
14+
8.3-release-zts: "sha256:158060357f81b495a5420b1f9d488abd61d59306946b352e4fbfc4011b7a2d89"
15+
8.4-debug: "sha256:c863e2a60f144856f56d50ed1080bbe0377ca99760195f170c762ad46f0466e5"
16+
8.4-release-zts: "sha256:6451c7104d874f8c4f7e0305e5baaecebbd74672a036c02de2cbb9d1a10c8906"
17+
8.5-debug: "sha256:014a16949dd0da0581cda6768bd7751f66b6ada3becdc949aeb5b8e1efb3c5cf"
18+
8.5-release-zts: "sha256:dadd96c4740bc9606f2985be51fb0b85d768132f93786c4ae52940552f3cbdc6"

.github/scripts/build-and-test.sh

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,79 @@
11
#!/usr/bin/env bash
22
# Build the extension and run the test suite.
3-
# Expected to run inside a datadog/dd-appsec-php-ci container from the repo root.
3+
# Expected to run inside a php-minimal (Alpine) container or Ubuntu from the repo root.
4+
# Env vars:
5+
# LIBARCHIVE_VERSION "system" (default) or a version tag like "v3.7.0".
6+
# "system" installs the distro package; a version tag
7+
# builds libarchive from source into .libarchive-cache/
8+
# inside the workspace (cached by the CI workflow).
49
set -euo pipefail
510

6-
# Install libarchive development headers if not already present.
7-
if ! pkg-config --exists libarchive 2>/dev/null; then
8-
apt-get update -qq
9-
apt-get install -y -qq libarchive-dev
11+
LIBARCHIVE_VERSION="${LIBARCHIVE_VERSION:-system}"
12+
13+
# ── Install / build libarchive ────────────────────────────────────────────────
14+
15+
if [ "$LIBARCHIVE_VERSION" = "system" ]; then
16+
if command -v apk >/dev/null 2>&1; then
17+
apk add --no-cache libarchive-dev
18+
else
19+
# Non-root Ubuntu runner: use sudo.
20+
_sudo=""
21+
[ "$(id -u)" != "0" ] && _sudo="sudo"
22+
$_sudo apt-get update -qq
23+
$_sudo apt-get install -y -qq libarchive-dev
24+
fi
25+
CONFIGURE_LIBARCHIVE="--with-libarchive"
26+
else
27+
# Build libarchive from source at the requested version.
28+
# The workflow caches ${GITHUB_WORKSPACE}/.libarchive-cache so subsequent
29+
# runs restore it and skip the build.
30+
LA_VERSION_NUM="${LIBARCHIVE_VERSION#v}"
31+
LA_PREFIX="${GITHUB_WORKSPACE}/.libarchive-cache"
32+
33+
if [ ! -f "${LA_PREFIX}/lib/libarchive.so" ] && [ ! -f "${LA_PREFIX}/lib/libarchive.a" ]; then
34+
if command -v apk >/dev/null 2>&1; then
35+
apk add --no-cache cmake build-base curl zlib-dev bzip2-dev xz-dev zstd-dev lz4-dev openssl-dev
36+
else
37+
_sudo=""
38+
[ "$(id -u)" != "0" ] && _sudo="sudo"
39+
$_sudo apt-get update -qq
40+
$_sudo apt-get install -y -qq cmake build-essential curl zlib1g-dev libbz2-dev liblzma-dev libzstd-dev liblz4-dev libssl-dev
41+
fi
42+
43+
BUILD_DIR="$(mktemp -d)"
44+
curl -fsSL "https://github.com/libarchive/libarchive/releases/download/${LIBARCHIVE_VERSION}/libarchive-${LA_VERSION_NUM}.tar.gz" \
45+
| tar xz -C "$BUILD_DIR"
46+
cmake -S "${BUILD_DIR}/libarchive-${LA_VERSION_NUM}" \
47+
-B "${BUILD_DIR}/build" \
48+
-DCMAKE_INSTALL_PREFIX="${LA_PREFIX}" \
49+
-DCMAKE_BUILD_TYPE=Release \
50+
-DENABLE_TEST=OFF
51+
cmake --build "${BUILD_DIR}/build" -j"$(nproc)"
52+
cmake --install "${BUILD_DIR}/build"
53+
rm -rf "$BUILD_DIR"
54+
fi
55+
56+
export LD_LIBRARY_PATH="${LA_PREFIX}/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
57+
CONFIGURE_LIBARCHIVE="--with-libarchive=${LA_PREFIX}"
1058
fi
1159

12-
# Clean up artifacts from any previous build so stale objects don't survive a
13-
# PHP-version switch (safe in CI where the workspace is always fresh).
60+
# ── Build ─────────────────────────────────────────────────────────────────────
61+
62+
# Clean up all generated files so stale objects from a previous PHP version or
63+
# build variant don't silently survive into this build.
1464
if [ -f Makefile ]; then
1565
make -f Makefile distclean
1666
fi
67+
# Remove any leftover object files even if Makefile is gone.
68+
find . -name '*.lo' -o -name '*.o' | xargs rm -f 2>/dev/null || true
69+
find . -name '.libs' -type d | xargs rm -rf 2>/dev/null || true
1770

1871
phpize
19-
./configure --with-php-config="$(which php-config)" --with-libarchive
72+
./configure --with-php-config="$(which php-config)" "$CONFIGURE_LIBARCHIVE"
2073
make -f Makefile -j"$(nproc)"
2174

75+
# ── Test ──────────────────────────────────────────────────────────────────────
76+
2277
# The generated Makefile silences and ignores errors on the `if` commands;
2378
# undo that so test failures surface properly.
2479
sed -i 's/-@if/@if/' Makefile

.github/scripts/update-docker-shas.sh

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,33 @@
55
# Justfile and tests.yml read from docker-image-shas.yml directly — no patching needed.
66
set -euo pipefail
77

8-
IMAGE="datadog/dd-appsec-php-ci"
8+
IMAGE="ghcr.io/cataphract/php-minimal"
99
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
1010
LOCK_FILE="$SCRIPT_DIR/../docker-image-shas.yml"
1111

1212
TAGS=(
13-
php-8.0-debug php-8.0-release-zts
14-
php-8.1-debug php-8.1-release-zts
15-
php-8.2-debug php-8.2-release-zts
16-
php-8.3-debug php-8.3-release-zts
17-
php-8.4-debug php-8.4-release-zts
18-
php-8.5-debug php-8.5-release-zts
13+
8.0-debug 8.0-release-zts
14+
8.1-debug 8.1-release-zts
15+
8.2-debug 8.2-release-zts
16+
8.3-debug 8.3-release 8.3-release-zts
17+
8.4-debug 8.4-release-zts
18+
8.5-debug 8.5-release-zts
1919
)
2020

2121
get_index_digest() {
22-
# The top-level "digest" field in the Hub tags API is the manifest-list
23-
# (OCI index) digest, not a per-platform image digest.
24-
curl -fsSL "https://hub.docker.com/v2/repositories/${IMAGE}/tags/$1" \
25-
| python3 -c "import sys,json; print(json.load(sys.stdin)['digest'])"
22+
local tag="$1" digest attempt
23+
for attempt in 1 2 3; do
24+
digest=$(docker buildx imagetools inspect "${IMAGE}:${tag}" \
25+
| awk '/^Digest:/ { print $2; exit }')
26+
if [[ -n "$digest" ]]; then
27+
echo "$digest"
28+
return 0
29+
fi
30+
echo "Attempt $attempt failed for $tag, retrying..." >&2
31+
sleep $((attempt * 5))
32+
done
33+
echo "ERROR: could not fetch digest for $tag after 3 attempts" >&2
34+
return 1
2635
}
2736

2837
# Collect all digests first so we fail fast before touching any file.

.github/workflows/tests.yml

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,30 @@ jobs:
3232
import yaml, json, os
3333
with open('.github/docker-image-shas.yml') as f:
3434
data = yaml.safe_load(f)
35-
image = 'datadog/dd-appsec-php-ci'
35+
image = 'ghcr.io/cataphract/php-minimal'
3636
includes = []
3737
for tag, sha in data[image].items():
38-
# tag: "php-8.0-debug" or "php-8.0-release-zts"
39-
ver, variant = tag[len('php-'):].split('-', 1)
40-
includes.append({'php': ver, 'variant': variant, 'image_sha': sha})
38+
# tag: "8.0-debug" or "8.0-release-zts"; skip non-test variants
39+
ver, variant = tag.split('-', 1)
40+
if variant not in ('debug', 'release-zts'):
41+
continue
42+
includes.append({'php': ver, 'variant': variant, 'image_sha': sha,
43+
'libarchive_version': 'system'})
44+
# Extra jobs testing specific libarchive versions (use PHP 8.4 debug)
45+
sha_8_4_debug = data[image]['8.4-debug']
46+
for la_ver in ['v3.5.0', 'v3.7.0', 'v3.8.6']:
47+
includes.append({'php': '8.4', 'variant': 'debug', 'image_sha': sha_8_4_debug,
48+
'libarchive_version': la_ver})
4149
with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
4250
f.write('matrix=' + json.dumps({'include': includes}) + '\n')
4351
EOF
4452
4553
linux:
46-
name: PHP ${{ matrix.php }} (${{ matrix.variant }})
54+
name: PHP ${{ matrix.php }} (${{ matrix.variant }}, libarchive ${{ matrix.libarchive_version }})
4755
needs: generate-matrix
4856
runs-on: ubuntu-latest
4957
container:
50-
image: datadog/dd-appsec-php-ci@${{ matrix.image_sha }}
58+
image: ghcr.io/cataphract/php-minimal@${{ matrix.image_sha }}
5159
options: --user root
5260
strategy:
5361
fail-fast: false
@@ -57,12 +65,52 @@ jobs:
5765
- name: Checkout
5866
uses: actions/checkout@v4
5967

68+
- name: Restore libarchive cache
69+
if: matrix.libarchive_version != 'system'
70+
uses: actions/cache@v4
71+
with:
72+
path: .libarchive-cache
73+
key: libarchive-${{ matrix.libarchive_version }}-${{ runner.arch }}
74+
75+
- name: Build and test
76+
env:
77+
LIBARCHIVE_VERSION: ${{ matrix.libarchive_version }}
78+
run: bash .github/scripts/build-and-test.sh
79+
80+
- name: Upload test results
81+
uses: actions/upload-artifact@v4
82+
if: always()
83+
with:
84+
name: test-results-php${{ matrix.php }}-${{ matrix.variant }}-libarchive${{ matrix.libarchive_version }}
85+
path: report.xml
86+
87+
ubuntu:
88+
name: ubuntu (PHP 8.3 release, ${{ matrix.arch }})
89+
runs-on: ${{ matrix.runner }}
90+
strategy:
91+
fail-fast: false
92+
matrix:
93+
include:
94+
- arch: x86_64
95+
runner: ubuntu-latest
96+
- arch: aarch64
97+
runner: ubuntu-24.04-arm
98+
99+
steps:
100+
- name: Checkout
101+
uses: actions/checkout@v4
102+
103+
- name: Install PHP 8.3 and libarchive
104+
run: |
105+
sudo apt-get update -q
106+
sudo apt-get install -y php8.3 php8.3-dev libarchive-dev
107+
60108
- name: Build and test
61109
run: bash .github/scripts/build-and-test.sh
62110

63111
- name: Upload test results
64112
uses: actions/upload-artifact@v4
65113
if: always()
66114
with:
67-
name: test-results-php${{ matrix.php }}-${{ matrix.variant }}
115+
name: test-results-ubuntu-php8.3-release-${{ matrix.arch }}
68116
path: report.xml

Justfile

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@
44

55
# ── Images ────────────────────────────────────────────────────────────────────
66

7-
_base := "datadog/dd-appsec-php-ci@"
8-
9-
image_8_0_debug := _base + `grep 'php-8.0-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
10-
image_8_0_release_zts := _base + `grep 'php-8.0-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
11-
image_8_1_debug := _base + `grep 'php-8.1-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
12-
image_8_1_release_zts := _base + `grep 'php-8.1-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
13-
image_8_2_debug := _base + `grep 'php-8.2-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
14-
image_8_2_release_zts := _base + `grep 'php-8.2-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
15-
image_8_3_debug := _base + `grep 'php-8.3-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
16-
image_8_3_release_zts := _base + `grep 'php-8.3-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
17-
image_8_4_debug := _base + `grep 'php-8.4-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
18-
image_8_4_release_zts := _base + `grep 'php-8.4-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
19-
image_8_5_debug := _base + `grep 'php-8.5-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
20-
image_8_5_release_zts := _base + `grep 'php-8.5-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
7+
_base := "ghcr.io/cataphract/php-minimal@"
8+
9+
image_8_0_debug := _base + `grep '8.0-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
10+
image_8_0_release_zts := _base + `grep '8.0-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
11+
image_8_1_debug := _base + `grep '8.1-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
12+
image_8_1_release_zts := _base + `grep '8.1-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
13+
image_8_2_debug := _base + `grep '8.2-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
14+
image_8_2_release_zts := _base + `grep '8.2-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
15+
image_8_3_debug := _base + `grep '8.3-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
16+
image_8_3_release_zts := _base + `grep '8.3-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
17+
image_8_4_debug := _base + `grep '8.4-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
18+
image_8_4_release_zts := _base + `grep '8.4-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
19+
image_8_5_debug := _base + `grep '8.5-debug:' .github/docker-image-shas.yml | cut -d'"' -f2`
20+
image_8_5_release_zts := _base + `grep '8.5-release-zts:' .github/docker-image-shas.yml | cut -d'"' -f2`
2121

2222
_run := "docker run --rm --entrypoint bash -v \"$PWD:/src:ro\" --tmpfs /overlay:exec,size=1g --cap-add SYS_ADMIN -w /workspace --user root"
2323
_cmd := "-c 'mkdir -p /overlay/upper /overlay/work /workspace && mount -t overlay overlay -o lowerdir=/src,upperdir=/overlay/upper,workdir=/overlay/work /workspace && cd /workspace && .github/scripts/build-and-test.sh'"

libarchive.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ static void arch_oh_free_obj(zend_object *zobj)
214214
obj->filters_count = 0;
215215
}
216216
if (obj->archive) {
217-
archive_read_close(obj->archive);
217+
archive_read_free(obj->archive);
218218
obj->archive = NULL;
219219
}
220220
if (obj->arch_disk) {

php_compat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#pragma once
22

3-
#if PHP_VERSION_ID < 80400
3+
#ifndef RETURN_THIS
44
#define RETURN_THIS() ZVAL_COPY(return_value, getThis()); return
55
#endif
66

0 commit comments

Comments
 (0)