implement building for ARM platforms

This commit is contained in:
2026-05-12 16:48:41 +03:30
parent f9e5b65d39
commit 21edc39155
4 changed files with 300 additions and 133 deletions

View File

@@ -6,7 +6,11 @@ name: Build and Release Module
nginx_versions: nginx_versions:
description: "Space-separated Nginx versions to build against" description: "Space-separated Nginx versions to build against"
required: true required: true
default: "1.22.1 1.24.0 1.26.3 1.28.0" default: "1.22.1 1.24.0 1.26.3 1.28.0 1.30.0"
target_arches:
description: "Space-separated targets: linux-x86_64 linux-arm64 linux-armv7"
required: true
default: "linux-x86_64 linux-arm64 linux-armv7"
version_bump: version_bump:
description: "Semantic version part to increment from the latest v* tag" description: "Semantic version part to increment from the latest v* tag"
required: true required: true
@@ -17,7 +21,7 @@ name: Build and Release Module
- minor - minor
- major - major
push_image: push_image:
description: "Push Docker image to GHCR using the new tag" description: "Push multi-platform Docker image to GHCR using the new tag"
type: boolean type: boolean
required: true required: true
default: true default: true
@@ -27,8 +31,10 @@ permissions:
packages: write packages: write
env: env:
DEFAULT_NGINX_VERSIONS: "1.22.1 1.24.0 1.26.3 1.28.0" DEFAULT_NGINX_VERSIONS: "1.22.1 1.24.0 1.26.3 1.28.0 1.30.0"
DEFAULT_TARGET_ARCHES: "linux-x86_64 linux-arm64 linux-armv7"
MODULE_NAME: ngx_http_monitoring_module MODULE_NAME: ngx_http_monitoring_module
RELEASE_BUILD_IMAGE: ubuntu:22.04
NGINX_CONFIGURE_ARGS: >- NGINX_CONFIGURE_ARGS: >-
--with-compat --with-compat
--with-http_ssl_module --with-http_ssl_module
@@ -41,6 +47,7 @@ jobs:
release: release:
name: Build module and publish release name: Build module and publish release
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
timeout-minutes: 120
steps: steps:
- name: Check out repository - name: Check out repository
@@ -112,11 +119,124 @@ jobs:
echo "Latest tag: $latest_tag" echo "Latest tag: $latest_tag"
echo "Next tag: $next_tag" echo "Next tag: $next_tag"
- name: Install build dependencies - name: Normalize target architectures
id: targets
shell: bash
env:
INPUT_TARGET_ARCHES: ${{ github.event.inputs.target_arches }}
run: | run: |
set -euo pipefail set -euo pipefail
sudo apt-get update
sudo apt-get install -y --no-install-recommends \ raw_targets="${INPUT_TARGET_ARCHES:-$DEFAULT_TARGET_ARCHES}"
normalized_targets=""
docker_platforms=""
add_target() {
local target_arch="$1"
local docker_platform="$2"
case " $normalized_targets " in
*" $target_arch "*)
return
;;
esac
normalized_targets="${normalized_targets}${normalized_targets:+ }${target_arch}"
docker_platforms="${docker_platforms}${docker_platforms:+,}${docker_platform}"
}
for raw_target in $raw_targets; do
case "$raw_target" in
linux-x86_64|x86_64|amd64|linux-amd64)
add_target "linux-x86_64" "linux/amd64"
;;
linux-arm64|linux-aarch64|arm64|aarch64)
add_target "linux-arm64" "linux/arm64"
;;
linux-armv7|linux-armhf|armv7|armhf)
add_target "linux-armv7" "linux/arm/v7"
;;
*)
echo "Unsupported target_arches entry: $raw_target" >&2
echo "Supported entries: linux-x86_64 linux-arm64 linux-armv7" >&2
exit 1
;;
esac
done
if [[ -z "$normalized_targets" ]]; then
echo "No release target architectures were selected" >&2
exit 1
fi
{
printf 'target_arches=%s\n' "$normalized_targets"
printf 'docker_platforms=%s\n' "$docker_platforms"
} >> "$GITHUB_OUTPUT"
echo "Release targets: $normalized_targets"
echo "Docker platforms: $docker_platforms"
- name: Set up QEMU for ARM builds
uses: docker/setup-qemu-action@v3
with:
platforms: arm64,arm
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build release packages
shell: bash
env:
INPUT_NGINX_VERSIONS: ${{ github.event.inputs.nginx_versions }}
NORMALIZED_TARGET_ARCHES: ${{ steps.targets.outputs.target_arches }}
run: |
set -euo pipefail
versions="${INPUT_NGINX_VERSIONS:-$DEFAULT_NGINX_VERSIONS}"
mkdir -p "$GITHUB_WORKSPACE/dist" "$GITHUB_WORKSPACE/.release-work"
for target_arch in $NORMALIZED_TARGET_ARCHES; do
case "$target_arch" in
linux-x86_64)
docker_platform="linux/amd64"
;;
linux-arm64)
docker_platform="linux/arm64"
;;
linux-armv7)
docker_platform="linux/arm/v7"
;;
*)
echo "Unexpected normalized target: $target_arch" >&2
exit 1
;;
esac
echo "::group::Build ${target_arch} release packages"
docker run --rm \
--platform "$docker_platform" \
-e BUILD_NGINX_VERSIONS="$versions" \
-e DOCKER_PLATFORM="$docker_platform" \
-e GITHUB_REF \
-e GITHUB_SHA \
-e LATEST_TAG \
-e MODULE_NAME \
-e NEXT_TAG \
-e NEXT_VERSION \
-e NGINX_CONFIGURE_ARGS \
-e RELEASE_BUILD_IMAGE \
-e TARGET_ARCH="$target_arch" \
-v "$GITHUB_WORKSPACE:/work" \
-w /work \
"$RELEASE_BUILD_IMAGE" \
bash -s <<'BUILD_SCRIPT'
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y --no-install-recommends \
build-essential \ build-essential \
ca-certificates \ ca-certificates \
curl \ curl \
@@ -124,25 +244,25 @@ jobs:
libpcre2-dev \ libpcre2-dev \
libssl-dev \ libssl-dev \
zlib1g-dev zlib1g-dev
rm -rf /var/lib/apt/lists/*
- name: Build release packages target_workdir="/work/.release-work/${TARGET_ARCH}"
shell: bash mkdir -p "$target_workdir" /work/dist
env:
INPUT_NGINX_VERSIONS: ${{ github.event.inputs.nginx_versions }}
run: |
set -euo pipefail
versions="${INPUT_NGINX_VERSIONS:-$DEFAULT_NGINX_VERSIONS}" for nginx_version in $BUILD_NGINX_VERSIONS; do
mkdir -p "$GITHUB_WORKSPACE/dist" "$GITHUB_WORKSPACE/.release-work" echo "::group::Nginx ${nginx_version} (${TARGET_ARCH})"
for nginx_version in $versions; do archive="nginx-${nginx_version}.tar.gz"
workdir="$GITHUB_WORKSPACE/.release-work/nginx-$nginx_version" archive_path="${target_workdir}/${archive}"
archive="nginx-$nginx_version.tar.gz" workdir="${target_workdir}/nginx-${nginx_version}"
curl -fsSLo "$GITHUB_WORKSPACE/.release-work/$archive" \ if [[ ! -f "$archive_path" ]]; then
"https://nginx.org/download/$archive" curl -fsSLo "$archive_path" \
tar -xzf "$GITHUB_WORKSPACE/.release-work/$archive" \ "https://nginx.org/download/${archive}"
-C "$GITHUB_WORKSPACE/.release-work" fi
rm -rf "$workdir"
tar -xzf "$archive_path" -C "$target_workdir"
cd "$workdir" cd "$workdir"
./configure \ ./configure \
@@ -160,22 +280,22 @@ jobs:
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \ --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
--http-scgi-temp-path=/var/cache/nginx/scgi_temp \ --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
$NGINX_CONFIGURE_ARGS \ $NGINX_CONFIGURE_ARGS \
--add-dynamic-module="$GITHUB_WORKSPACE" --add-dynamic-module=/work
make -j"$(nproc)" modules make -j"$(nproc)" modules
package="${MODULE_NAME}-${NEXT_VERSION}-${NEXT_TAG}-nginx-${nginx_version}-linux-x86_64" package="${MODULE_NAME}-${NEXT_TAG}-nginx-${nginx_version}-${TARGET_ARCH}"
package_dir="$GITHUB_WORKSPACE/dist/$package" package_dir="/work/dist/$package"
mkdir -p "$package_dir/modules" "$package_dir/examples" "$package_dir/docs" mkdir -p "$package_dir/modules" "$package_dir/examples" "$package_dir/docs"
cp "objs/${MODULE_NAME}.so" "$package_dir/modules/${MODULE_NAME}.so" cp "objs/${MODULE_NAME}.so" "$package_dir/modules/${MODULE_NAME}.so"
strip --strip-unneeded "$package_dir/modules/${MODULE_NAME}.so" || true strip --strip-unneeded "$package_dir/modules/${MODULE_NAME}.so" || true
cp "$GITHUB_WORKSPACE/examples/nginx.conf" "$package_dir/examples/nginx.conf" cp /work/examples/nginx.conf "$package_dir/examples/nginx.conf"
cp "$GITHUB_WORKSPACE/examples/monitoring-site.conf" "$package_dir/examples/monitoring-site.conf" cp /work/examples/monitoring-site.conf "$package_dir/examples/monitoring-site.conf"
cp "$GITHUB_WORKSPACE/README.md" "$package_dir/README.md" cp /work/README.md "$package_dir/README.md"
cp "$GITHUB_WORKSPACE/docs/API.md" "$package_dir/docs/API.md" cp /work/docs/API.md "$package_dir/docs/API.md"
cp "$GITHUB_WORKSPACE/docs/CONFIGURATION.md" "$package_dir/docs/CONFIGURATION.md" cp /work/docs/CONFIGURATION.md "$package_dir/docs/CONFIGURATION.md"
cp "$GITHUB_WORKSPACE/docs/PERFORMANCE.md" "$package_dir/docs/PERFORMANCE.md" cp /work/docs/PERFORMANCE.md "$package_dir/docs/PERFORMANCE.md"
{ {
printf 'module=%s\n' "$MODULE_NAME" printf 'module=%s\n' "$MODULE_NAME"
@@ -183,7 +303,10 @@ jobs:
printf 'release_tag=%s\n' "$NEXT_TAG" printf 'release_tag=%s\n' "$NEXT_TAG"
printf 'previous_tag=%s\n' "$LATEST_TAG" printf 'previous_tag=%s\n' "$LATEST_TAG"
printf 'nginx_version=%s\n' "$nginx_version" printf 'nginx_version=%s\n' "$nginx_version"
printf 'target=linux-x86_64\n' printf 'target=%s\n' "$TARGET_ARCH"
printf 'docker_platform=%s\n' "$DOCKER_PLATFORM"
printf 'build_image=%s\n' "$RELEASE_BUILD_IMAGE"
printf 'build_machine=%s\n' "$(uname -m)"
printf 'runner=ubuntu-22.04\n' printf 'runner=ubuntu-22.04\n'
printf 'git_ref=%s\n' "$GITHUB_REF" printf 'git_ref=%s\n' "$GITHUB_REF"
printf 'git_sha=%s\n' "$GITHUB_SHA" printf 'git_sha=%s\n' "$GITHUB_SHA"
@@ -194,7 +317,8 @@ jobs:
{ {
printf '# %s for Nginx %s\n\n' "$MODULE_NAME" "$nginx_version" printf '# %s for Nginx %s\n\n' "$MODULE_NAME" "$nginx_version"
printf 'Release: `%s`\n\n' "$NEXT_TAG" printf 'Release: `%s`\n\n' "$NEXT_TAG"
printf 'This package contains a prebuilt Linux x86_64 dynamic module:\n\n' printf 'Target: `%s` (`%s`)\n\n' "$TARGET_ARCH" "$DOCKER_PLATFORM"
printf 'This package contains a prebuilt Linux dynamic module:\n\n'
printf '```text\n' printf '```text\n'
printf 'modules/%s.so\n' "$MODULE_NAME" printf 'modules/%s.so\n' "$MODULE_NAME"
printf '```\n\n' printf '```\n\n'
@@ -202,8 +326,8 @@ jobs:
printf '```nginx\n' printf '```nginx\n'
printf 'load_module modules/%s.so;\n' "$MODULE_NAME" printf 'load_module modules/%s.so;\n' "$MODULE_NAME"
printf '```\n\n' printf '```\n\n'
printf 'This binary is built with `--with-compat` against Nginx %s on Ubuntu 22.04. ' "$nginx_version" printf 'This binary is built with `--with-compat` against Nginx %s on Ubuntu 22.04 for %s. ' "$nginx_version" "$TARGET_ARCH"
printf 'For safest production use, run the same Nginx version and a compatible Linux/glibc environment. ' printf 'For safest production use, run the same Nginx version, CPU architecture, and a compatible Linux/glibc environment. '
printf 'If your Nginx package has a materially different module ABI, rebuild from source with this repository.\n' printf 'If your Nginx package has a materially different module ABI, rebuild from source with this repository.\n'
} > "$package_dir/INSTALL.md" } > "$package_dir/INSTALL.md"
@@ -213,9 +337,13 @@ jobs:
file "modules/${MODULE_NAME}.so" > FILE.txt file "modules/${MODULE_NAME}.so" > FILE.txt
) )
tar -czf "$GITHUB_WORKSPACE/dist/$package.tar.gz" \ tar -czf "/work/dist/$package.tar.gz" -C /work/dist "$package"
-C "$GITHUB_WORKSPACE/dist" "$package"
rm -rf "$package_dir" rm -rf "$package_dir"
echo "::endgroup::"
done
BUILD_SCRIPT
echo "::endgroup::"
done done
( (
@@ -226,14 +354,14 @@ jobs:
{ {
printf '# ngx_http_monitoring_module %s\n\n' "$NEXT_TAG" printf '# ngx_http_monitoring_module %s\n\n' "$NEXT_TAG"
printf 'Previous tag: `%s`\n\n' "$LATEST_TAG" printf 'Previous tag: `%s`\n\n' "$LATEST_TAG"
printf 'Prebuilt Linux x86_64 dynamic module packages are attached.\n\n' printf 'Prebuilt Linux dynamic module packages are attached for targets: `%s`.\n\n' "$NORMALIZED_TARGET_ARCHES"
printf 'Each tarball is built against the Nginx version in its filename and includes:\n\n' printf 'Each tarball is built against the Nginx version and target architecture in its filename and includes:\n\n'
printf -- '- `modules/%s.so`\n' "$MODULE_NAME" printf -- '- `modules/%s.so`\n' "$MODULE_NAME"
printf -- '- `INSTALL.md`\n' printf -- '- `INSTALL.md`\n'
printf -- '- `METADATA.txt`\n' printf -- '- `METADATA.txt`\n'
printf -- '- `SHA256SUMS`\n' printf -- '- `SHA256SUMS`\n'
printf -- '- example configuration and API docs\n\n' printf -- '- example configuration and API docs\n\n'
printf 'Nginx dynamic modules are ABI-sensitive. Use the package matching your Nginx version and rebuild locally if your Nginx distribution uses incompatible build options.\n' printf 'Nginx dynamic modules are ABI-sensitive. Use the package matching your Nginx version and CPU architecture, and rebuild locally if your Nginx distribution uses incompatible build options.\n'
} > "$GITHUB_WORKSPACE/dist/RELEASE_NOTES.md" } > "$GITHUB_WORKSPACE/dist/RELEASE_NOTES.md"
- name: Upload build artifacts - name: Upload build artifacts
@@ -264,21 +392,31 @@ jobs:
--title "$NEXT_TAG" \ --title "$NEXT_TAG" \
--notes-file dist/RELEASE_NOTES.md --notes-file dist/RELEASE_NOTES.md
- name: Build and push Docker image - name: Compute Docker image name
if: github.event.inputs.push_image == 'true' if: github.event.inputs.push_image == 'true'
env: id: image
GH_TOKEN: ${{ github.token }}
shell: bash shell: bash
run: | run: |
set -euo pipefail set -euo pipefail
image_repo="$(echo "ghcr.io/${GITHUB_REPOSITORY}" | tr '[:upper:]' '[:lower:]')" image_repo="$(echo "ghcr.io/${GITHUB_REPOSITORY}" | tr '[:upper:]' '[:lower:]')"
printf 'repo=%s\n' "$image_repo" >> "$GITHUB_OUTPUT"
docker build \ - name: Log in to GHCR
-f dockerized/Dockerfile \ if: github.event.inputs.push_image == 'true'
-t "$image_repo:$NEXT_TAG" \ uses: docker/login-action@v3
-t "$image_repo:latest" \ with:
. registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}
echo "$GH_TOKEN" | docker login ghcr.io -u "$GITHUB_ACTOR" --password-stdin - name: Build and push Docker image
docker push "$image_repo:$NEXT_TAG" if: github.event.inputs.push_image == 'true'
docker push "$image_repo:latest" uses: docker/build-push-action@v6
with:
context: .
file: dockerized/Dockerfile
platforms: ${{ steps.targets.outputs.docker_platforms }}
push: true
tags: |
${{ steps.image.outputs.repo }}:${{ steps.version.outputs.next_tag }}
${{ steps.image.outputs.repo }}:latest

View File

@@ -13,6 +13,7 @@ permissions:
contents: read contents: read
env: env:
TEST_BUILD_IMAGE: ubuntu:22.04
NGINX_CONFIGURE_ARGS: >- NGINX_CONFIGURE_ARGS: >-
--with-compat --with-compat
--with-http_ssl_module --with-http_ssl_module
@@ -23,9 +24,9 @@ env:
jobs: jobs:
build-and-configure: build-and-configure:
name: Nginx ${{ matrix.nginx-version }} name: Nginx ${{ matrix.nginx-version }} (${{ matrix.target.name }})
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
timeout-minutes: 30 timeout-minutes: 90
strategy: strategy:
fail-fast: false fail-fast: false
@@ -35,16 +36,48 @@ jobs:
- "1.24.0" - "1.24.0"
- "1.26.3" - "1.26.3"
- "1.28.0" - "1.28.0"
- "1.30.0"
target:
- name: linux-x86_64
platform: linux/amd64
- name: linux-arm64
platform: linux/arm64
- name: linux-armv7
platform: linux/arm/v7
steps: steps:
- name: Check out repository - name: Check out repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Install build dependencies - name: Set up QEMU for ARM tests
uses: docker/setup-qemu-action@v3
with:
platforms: arm64,arm
- name: Build, configure, and test routes
shell: bash
env:
NGINX_VERSION: ${{ matrix.nginx-version }}
TARGET_ARCH: ${{ matrix.target.name }}
DOCKER_PLATFORM: ${{ matrix.target.platform }}
run: | run: |
set -euo pipefail set -euo pipefail
sudo apt-get update
sudo apt-get install -y --no-install-recommends \ docker run --rm \
--platform "$DOCKER_PLATFORM" \
-e NGINX_VERSION \
-e TARGET_ARCH \
-e NGINX_CONFIGURE_ARGS \
-v "$GITHUB_WORKSPACE:/work" \
-w /work \
"$TEST_BUILD_IMAGE" \
bash -s <<'CI_SCRIPT'
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y --no-install-recommends \
build-essential \ build-essential \
ca-certificates \ ca-certificates \
curl \ curl \
@@ -53,26 +86,32 @@ jobs:
libpcre2-dev \ libpcre2-dev \
libssl-dev \ libssl-dev \
zlib1g-dev zlib1g-dev
rm -rf /var/lib/apt/lists/*
- name: Download Nginx source build_jobs="$(nproc)"
shell: bash if [[ "$TARGET_ARCH" != "linux-x86_64" && "$build_jobs" -gt 2 ]]; then
env: build_jobs=2
NGINX_VERSION: ${{ matrix.nginx-version }} fi
run: |
set -euo pipefail
mkdir -p "$GITHUB_WORKSPACE/.ci-nginx"
curl -fsSLo "$GITHUB_WORKSPACE/.ci-nginx/nginx-${NGINX_VERSION}.tar.gz" \
"https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz"
tar -xzf "$GITHUB_WORKSPACE/.ci-nginx/nginx-${NGINX_VERSION}.tar.gz" \
-C "$GITHUB_WORKSPACE/.ci-nginx"
- name: Configure Nginx with module nginx_root="/work/.ci-nginx/${TARGET_ARCH}"
shell: bash runtime_root="/work/.ci-runtime/${TARGET_ARCH}/nginx-${NGINX_VERSION}"
env: archive="nginx-${NGINX_VERSION}.tar.gz"
NGINX_VERSION: ${{ matrix.nginx-version }} archive_path="${nginx_root}/${archive}"
run: | nginx_src="${nginx_root}/nginx-${NGINX_VERSION}"
set -euo pipefail module_path="${nginx_src}/objs/ngx_http_monitoring_module.so"
cd "$GITHUB_WORKSPACE/.ci-nginx/nginx-${NGINX_VERSION}" config_path="${runtime_root}/nginx.conf"
base_url="http://127.0.0.1:18080"
mkdir -p "$nginx_root"
if [[ ! -f "$archive_path" ]]; then
curl -fsSLo "$archive_path" \
"https://nginx.org/download/${archive}"
fi
rm -rf "$nginx_src" "$runtime_root"
tar -xzf "$archive_path" -C "$nginx_root"
cd "$nginx_src"
./configure \ ./configure \
--prefix=/usr/local/nginx \ --prefix=/usr/local/nginx \
--sbin-path=/usr/local/sbin/nginx \ --sbin-path=/usr/local/sbin/nginx \
@@ -88,58 +127,39 @@ jobs:
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \ --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
--http-scgi-temp-path=/var/cache/nginx/scgi_temp \ --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
$NGINX_CONFIGURE_ARGS \ $NGINX_CONFIGURE_ARGS \
--add-dynamic-module="$GITHUB_WORKSPACE" --add-dynamic-module=/work
- name: Build Nginx binary and dynamic module make -j"$build_jobs"
shell: bash make -j"$build_jobs" modules
env:
NGINX_VERSION: ${{ matrix.nginx-version }}
run: |
set -euo pipefail
cd "$GITHUB_WORKSPACE/.ci-nginx/nginx-${NGINX_VERSION}"
make -j"$(nproc)"
make -j"$(nproc)" modules
test -x objs/nginx test -x objs/nginx
test -f objs/ngx_http_monitoring_module.so test -f "$module_path"
file objs/nginx file objs/nginx
file objs/ngx_http_monitoring_module.so file "$module_path"
- name: Validate generated Nginx configuration
shell: bash
env:
NGINX_VERSION: ${{ matrix.nginx-version }}
run: |
set -euo pipefail
nginx_src="$GITHUB_WORKSPACE/.ci-nginx/nginx-${NGINX_VERSION}"
run_root="$GITHUB_WORKSPACE/.ci-runtime/nginx-${NGINX_VERSION}"
module_path="$nginx_src/objs/ngx_http_monitoring_module.so"
config_path="$run_root/nginx.conf"
mkdir -p \ mkdir -p \
"$run_root/logs" \ "$runtime_root/logs" \
"$run_root/temp/client_body" \ "$runtime_root/temp/client_body" \
"$run_root/temp/proxy" \ "$runtime_root/temp/proxy" \
"$run_root/temp/fastcgi" \ "$runtime_root/temp/fastcgi" \
"$run_root/temp/uwsgi" \ "$runtime_root/temp/uwsgi" \
"$run_root/temp/scgi" "$runtime_root/temp/scgi"
{ {
printf 'load_module %s;\n\n' "$module_path" printf 'load_module %s;\n\n' "$module_path"
printf 'worker_processes 1;\n' printf 'worker_processes 1;\n'
printf 'error_log %s/logs/error.log info;\n' "$run_root" printf 'error_log %s/logs/error.log info;\n' "$runtime_root"
printf 'pid %s/logs/nginx.pid;\n\n' "$run_root" printf 'pid %s/logs/nginx.pid;\n\n' "$runtime_root"
printf 'events {\n' printf 'events {\n'
printf ' worker_connections 1024;\n' printf ' worker_connections 1024;\n'
printf '}\n\n' printf '}\n\n'
printf 'http {\n' printf 'http {\n'
printf ' access_log off;\n' printf ' access_log off;\n'
printf ' default_type application/octet-stream;\n' printf ' default_type application/octet-stream;\n'
printf ' client_body_temp_path %s/temp/client_body;\n' "$run_root" printf ' client_body_temp_path %s/temp/client_body;\n' "$runtime_root"
printf ' proxy_temp_path %s/temp/proxy;\n' "$run_root" printf ' proxy_temp_path %s/temp/proxy;\n' "$runtime_root"
printf ' fastcgi_temp_path %s/temp/fastcgi;\n' "$run_root" printf ' fastcgi_temp_path %s/temp/fastcgi;\n' "$runtime_root"
printf ' uwsgi_temp_path %s/temp/uwsgi;\n' "$run_root" printf ' uwsgi_temp_path %s/temp/uwsgi;\n' "$runtime_root"
printf ' scgi_temp_path %s/temp/scgi;\n\n' "$run_root" printf ' scgi_temp_path %s/temp/scgi;\n\n' "$runtime_root"
printf ' monitor_refresh_interval 1s;\n' printf ' monitor_refresh_interval 1s;\n'
printf ' monitor_history 1m;\n' printf ' monitor_history 1m;\n'
printf ' monitor_resolution 1s;\n' printf ' monitor_resolution 1s;\n'
@@ -169,22 +189,14 @@ jobs:
printf '}\n' printf '}\n'
} > "$config_path" } > "$config_path"
"$nginx_src/objs/nginx" -t -p "$run_root" -c "$config_path" "$nginx_src/objs/nginx" -t -p "$runtime_root" -c "$config_path"
- name: Run Nginx and test monitoring routes cleanup() {
shell: bash "$nginx_src/objs/nginx" -p "$runtime_root" -c "$config_path" -s quit || true
env: }
NGINX_VERSION: ${{ matrix.nginx-version }} trap cleanup EXIT
run: |
set -euo pipefail
nginx_src="$GITHUB_WORKSPACE/.ci-nginx/nginx-${NGINX_VERSION}" "$nginx_src/objs/nginx" -p "$runtime_root" -c "$config_path"
run_root="$GITHUB_WORKSPACE/.ci-runtime/nginx-${NGINX_VERSION}"
config_path="$run_root/nginx.conf"
base_url="http://127.0.0.1:18080"
"$nginx_src/objs/nginx" -p "$run_root" -c "$config_path"
trap '"$nginx_src/objs/nginx" -p "$run_root" -c "$config_path" -s quit || true' EXIT
for attempt in $(seq 1 50); do for attempt in $(seq 1 50); do
if curl -fsS "$base_url/" >/dev/null; then if curl -fsS "$base_url/" >/dev/null; then
@@ -242,13 +254,14 @@ jobs:
sse_output="$(timeout 5s curl -fsS -N "$base_url/monitor/live" || true)" sse_output="$(timeout 5s curl -fsS -N "$base_url/monitor/live" || true)"
printf '%s' "$sse_output" | grep -q '^event: metrics' printf '%s' "$sse_output" | grep -q '^event: metrics'
printf '%s' "$sse_output" | grep -q '^data: {' printf '%s' "$sse_output" | grep -q '^data: {'
CI_SCRIPT
- name: Upload failed nginx logs - name: Upload failed nginx logs
if: failure() if: failure()
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: nginx-${{ matrix.nginx-version }}-test-logs name: nginx-${{ matrix.nginx-version }}-${{ matrix.target.name }}-test-logs
path: | path: |
.ci-runtime/nginx-${{ matrix.nginx-version }}/logs/*.log .ci-runtime/${{ matrix.target.name }}/nginx-${{ matrix.nginx-version }}/logs/*.log
.ci-runtime/nginx-${{ matrix.nginx-version }}/nginx.conf .ci-runtime/${{ matrix.target.name }}/nginx-${{ matrix.nginx-version }}/nginx.conf
if-no-files-found: ignore if-no-files-found: ignore

View File

@@ -57,11 +57,11 @@ A reusable Codex skill for clients and agents is available at `skills/ngx-http-m
## GitHub Releases ## GitHub Releases
The repository includes a manual GitHub Actions workflow at `.github/workflows/release.yml` that computes the next `vMAJOR.MINOR.PATCH` tag, builds Linux x86_64 dynamic module tarballs, pushes the tag, and publishes the release. See `docs/RELEASES.md` for release asset format and compatibility notes. The repository includes a manual GitHub Actions workflow at `.github/workflows/release.yml` that computes the next `vMAJOR.MINOR.PATCH` tag, builds Linux x86_64, ARM64, and ARMv7 dynamic module tarballs, pushes the tag, and publishes the release. See `docs/RELEASES.md` for release asset format and compatibility notes.
## CI Tests ## CI Tests
`.github/workflows/test.yml` runs on pushes and pull requests. It builds Nginx and the dynamic module against common Nginx versions, runs `nginx -t`, starts the built server, and checks the dashboard, JSON API, health, Prometheus, and SSE routes. `.github/workflows/test.yml` runs on pushes and pull requests. It builds Nginx and the dynamic module against common Nginx versions on x86_64, ARM64, and ARMv7, runs `nginx -t`, starts the built server, and checks the dashboard, JSON API, health, Prometheus, and SSE routes.
## Load The Module ## Load The Module

View File

@@ -1,6 +1,6 @@
# Release Builds # Release Builds
The GitHub Actions workflow in `.github/workflows/release.yml` builds ready-to-use Linux x86_64 dynamic module packages. The GitHub Actions workflow in `.github/workflows/release.yml` builds ready-to-use Linux dynamic module packages for x86_64 and ARM targets.
## Manual Release Only ## Manual Release Only
@@ -9,8 +9,9 @@ The workflow runs only through GitHub Actions `workflow_dispatch`. It does not r
Open the workflow in GitHub Actions and choose: Open the workflow in GitHub Actions and choose:
- `nginx_versions`: space-separated versions, for example `1.24.0 1.26.3 1.28.0` - `nginx_versions`: space-separated versions, for example `1.24.0 1.26.3 1.28.0`
- `target_arches`: space-separated targets, default `linux-x86_64 linux-arm64 linux-armv7`
- `version_bump`: `patch`, `minor`, or `major` - `version_bump`: `patch`, `minor`, or `major`
- `push_image`: whether to push the Docker image to GHCR - `push_image`: whether to push the multi-platform Docker image to GHCR
The workflow fetches existing `vMAJOR.MINOR.PATCH` tags, computes the next semantic version, creates an annotated tag, pushes it, and publishes the GitHub release. The workflow fetches existing `vMAJOR.MINOR.PATCH` tags, computes the next semantic version, creates an annotated tag, pushes it, and publishes the GitHub release.
@@ -27,14 +28,27 @@ no existing tag + patch = v0.0.1
By default, the workflow builds packages for: By default, the workflow builds packages for:
- Nginx 1.22.1
- Nginx 1.24.0 - Nginx 1.24.0
- Nginx 1.26.3 - Nginx 1.26.3
- Nginx 1.28.0 - Nginx 1.28.0
- Nginx 1.30.0
## Built CPU Targets
By default, the workflow builds module packages for:
- `linux-x86_64`
- `linux-arm64`
- `linux-armv7`
Aliases such as `amd64`, `arm64`, `aarch64`, `armv7`, and `armhf` are normalized by the workflow.
Each release asset is named like: Each release asset is named like:
```text ```text
ngx_http_monitoring_module-1.0.0-v1.0.0-nginx-1.28.0-linux-x86_64.tar.gz ngx_http_monitoring_module-v1.0.0-nginx-1.28.0-linux-x86_64.tar.gz
ngx_http_monitoring_module-v1.0.0-nginx-1.28.0-linux-arm64.tar.gz
``` ```
Each package contains: Each package contains:
@@ -55,6 +69,8 @@ ghcr.io/<owner>/<repo>:<tag>
ghcr.io/<owner>/<repo>:latest ghcr.io/<owner>/<repo>:latest
``` ```
The image is built with Docker Buildx for the same normalized target platforms requested by `target_arches`.
## Compatibility Warning ## Compatibility Warning
Nginx dynamic modules are ABI-sensitive. The release packages are built with `--with-compat` on Ubuntu 22.04 against the Nginx version in the filename. Use the matching Nginx version and a compatible Linux/glibc runtime. Rebuild locally when using a vendor Nginx package with materially different module ABI or hardening options. Nginx dynamic modules are ABI-sensitive. The release packages are built with `--with-compat` on Ubuntu 22.04 against the Nginx version and CPU architecture in the filename. Use the matching Nginx version, CPU architecture, and a compatible Linux/glibc runtime. Rebuild locally when using a vendor Nginx package with materially different module ABI or hardening options.