implement building for ARM platforms
This commit is contained in:
238
.github/workflows/release.yml
vendored
238
.github/workflows/release.yml
vendored
@@ -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
|
||||||
|
|||||||
167
.github/workflows/test.yml
vendored
167
.github/workflows/test.yml
vendored
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
Reference in New Issue
Block a user