Ubuntu 26.04
This commit is contained in:
@@ -1,3 +1,21 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# build-and-publish (multi-distro matrix)
|
||||||
|
#
|
||||||
|
# Builds twiy as a Debian .deb for each target distro in parallel:
|
||||||
|
# - trixie (Debian 13) -> uploaded to NEXUS_REPO_TRIXIE
|
||||||
|
# - raccoon (Ubuntu 26.04 LTS) -> uploaded to NEXUS_REPO_RACCOON
|
||||||
|
#
|
||||||
|
# Each matrix job runs DIRECTLY INSIDE a container of the target distro
|
||||||
|
# (Gitea Actions `container:` directive, not nested docker-in-docker).
|
||||||
|
# act_runner mounts the workspace into the container, so apt/ldd/dpkg-deb
|
||||||
|
# all see the target distro's libraries — no host contamination.
|
||||||
|
#
|
||||||
|
# Required repository secrets (set up by the API provisioning script):
|
||||||
|
# NEXUS_URL (shared)
|
||||||
|
# NEXUS_USER_TRIXIE, NEXUS_PASS_TRIXIE, NEXUS_REPO_TRIXIE
|
||||||
|
# NEXUS_USER_RACCOON, NEXUS_PASS_RACCOON, NEXUS_REPO_RACCOON
|
||||||
|
# Each NEXUS_USER_* is a least-privilege user scoped to ONE apt-hosted repo.
|
||||||
|
# =============================================================================
|
||||||
name: build-and-publish
|
name: build-and-publish
|
||||||
|
|
||||||
on:
|
on:
|
||||||
@@ -9,6 +27,7 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
strategy:
|
strategy:
|
||||||
|
# If trixie fails, still finish raccoon (and vice versa) — surface both.
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
target: [trixie, raccoon]
|
target: [trixie, raccoon]
|
||||||
@@ -16,108 +35,124 @@ jobs:
|
|||||||
- target: trixie
|
- target: trixie
|
||||||
image: debian:13
|
image: debian:13
|
||||||
nexus_repo_secret: NEXUS_REPO_TRIXIE
|
nexus_repo_secret: NEXUS_REPO_TRIXIE
|
||||||
|
nexus_user_secret: NEXUS_USER_TRIXIE
|
||||||
|
nexus_pass_secret: NEXUS_PASS_TRIXIE
|
||||||
- target: raccoon
|
- target: raccoon
|
||||||
image: ubuntu:26.04
|
image: ubuntu:26.04
|
||||||
nexus_repo_secret: NEXUS_REPO_RACCOON
|
nexus_repo_secret: NEXUS_REPO_RACCOON
|
||||||
|
nexus_user_secret: NEXUS_USER_RACCOON
|
||||||
|
nexus_pass_secret: NEXUS_PASS_RACCOON
|
||||||
|
|
||||||
|
# Run all steps directly inside the target distro's container. Gitea's
|
||||||
|
# act_runner mounts the workspace and injects node so actions/checkout
|
||||||
|
# works. No nested docker calls needed.
|
||||||
|
container:
|
||||||
|
image: ${{ matrix.image }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
# The default debian/ubuntu images lack git + ca-certificates, which
|
||||||
|
# actions/checkout needs. Cheaper to install just those two here than
|
||||||
|
# to bake a custom image.
|
||||||
|
- name: Bootstrap checkout deps
|
||||||
|
run: |
|
||||||
|
apt-get update -qq
|
||||||
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
git ca-certificates
|
||||||
|
|
||||||
- name: Checkout source
|
- name: Checkout source
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Build nginx and assemble .deb inside ${{ matrix.image }}
|
- name: Build nginx and assemble .deb (${{ matrix.target }})
|
||||||
id: pkg
|
id: pkg
|
||||||
env:
|
env:
|
||||||
TARGET: ${{ matrix.target }}
|
TARGET: ${{ matrix.target }}
|
||||||
IMAGE: ${{ matrix.image }}
|
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
mkdir -p dist
|
# /.dockerenv tells build/${TARGET}.sh's postfix step to skip systemctl
|
||||||
sudo docker run --rm \
|
touch /.dockerenv
|
||||||
-v "$PWD:/repo" \
|
bash build/${TARGET}.sh new
|
||||||
-w /repo \
|
bash build/${TARGET}.sh build
|
||||||
-e TARGET="$TARGET" \
|
bash build/${TARGET}.sh postfix
|
||||||
"$IMAGE" \
|
|
||||||
bash -euxc '
|
|
||||||
touch /.dockerenv
|
|
||||||
bash build/${TARGET}.sh new
|
|
||||||
bash build/${TARGET}.sh build
|
|
||||||
bash build/${TARGET}.sh postfix
|
|
||||||
|
|
||||||
PKG_NAME="twiy"
|
PKG_NAME="twiy"
|
||||||
NGINX_VER="$(nginx -v 2>&1 | awk -F/ "{print \$2}")"
|
NGINX_VER="$(nginx -v 2>&1 | awk -F/ '{print $2}')"
|
||||||
VERSION="${NGINX_VER}-${GITHUB_RUN_NUMBER:-1}~${TARGET}"
|
# Append CI run number AND target so each rebuild is a strictly-
|
||||||
ARCH="amd64"
|
# greater Debian revision. Without this, `apt upgrade twiy` would
|
||||||
PKG_DIR="/opt/${PKG_NAME}_${VERSION}_${ARCH}"
|
# be a no-op when upstream nginx hasnt moved, so packaging fixes
|
||||||
DEB_DIR="${PKG_DIR}/DEBIAN"
|
# wouldnt reach users who already have the package installed.
|
||||||
mkdir -p "${PKG_DIR}/usr/sbin" "${PKG_DIR}/nginx" \
|
# The ~target suffix keeps trixie/raccoon versions distinct in
|
||||||
"${PKG_DIR}/etc/systemd/system" "${PKG_DIR}/var/log/nginx" \
|
# case any introspection ever compares them.
|
||||||
"${PKG_DIR}/usr/lib" "${PKG_DIR}/usr/local/lib" \
|
VERSION="${NGINX_VER}-${GITHUB_RUN_NUMBER:-1}~${TARGET}"
|
||||||
"${PKG_DIR}/hostdata/default/public_html" \
|
ARCH="amd64"
|
||||||
"${PKG_DIR}/usr/nginx_lua" \
|
PKG_DIR="/opt/${PKG_NAME}_${VERSION}_${ARCH}"
|
||||||
"${PKG_DIR}/usr/local/nginx/client_body_temp" \
|
DEB_DIR="${PKG_DIR}/DEBIAN"
|
||||||
"${PKG_DIR}/usr/local/nginx/proxy_temp" \
|
|
||||||
"${PKG_DIR}/usr/local/nginx/fastcgi_temp" \
|
|
||||||
"${PKG_DIR}/usr/local/nginx/uwsgi_temp" \
|
|
||||||
"${PKG_DIR}/usr/local/nginx/scgi_temp"
|
|
||||||
|
|
||||||
cp /usr/sbin/nginx "${PKG_DIR}/usr/sbin/"
|
# The *_temp dirs under /usr/local/nginx are nginx's compiled-in
|
||||||
cp -R /nginx/* "${PKG_DIR}/nginx/" || true
|
# defaults for client_body / proxy / fastcgi / uwsgi / scgi temp
|
||||||
cp /etc/systemd/system/nginx.service "${PKG_DIR}/etc/systemd/system/"
|
# storage (no --http-*-temp-path was passed to ./configure). They
|
||||||
cp -R /hostdata/default "${PKG_DIR}/hostdata/" || true
|
# must exist before `nginx -t` runs, so we ship them empty in the
|
||||||
cp -R /usr/nginx_lua "${PKG_DIR}/usr/" || true
|
# .deb and the postinst chowns them to the nginx user.
|
||||||
for lib in $(ldd /usr/sbin/nginx | grep "=> /" | awk "{print \$3}"); do
|
mkdir -p "${PKG_DIR}/usr/sbin" "${PKG_DIR}/nginx" \
|
||||||
cp "$lib" "${PKG_DIR}/usr/lib/" || true
|
"${PKG_DIR}/etc/systemd/system" "${PKG_DIR}/var/log/nginx" \
|
||||||
done
|
"${PKG_DIR}/usr/lib" "${PKG_DIR}/usr/local/lib" \
|
||||||
# ---- DEBIAN/control --------------------------------------------
|
"${PKG_DIR}/hostdata/default/public_html" \
|
||||||
mkdir -p "${DEB_DIR}"
|
"${PKG_DIR}/usr/nginx_lua" \
|
||||||
cat > "${DEB_DIR}/control" <<EOF
|
"${PKG_DIR}/usr/local/nginx/client_body_temp" \
|
||||||
Package: ${PKG_NAME}
|
"${PKG_DIR}/usr/local/nginx/proxy_temp" \
|
||||||
Version: ${VERSION}
|
"${PKG_DIR}/usr/local/nginx/fastcgi_temp" \
|
||||||
Section: base
|
"${PKG_DIR}/usr/local/nginx/uwsgi_temp" \
|
||||||
Priority: optional
|
"${PKG_DIR}/usr/local/nginx/scgi_temp"
|
||||||
Architecture: ${ARCH}
|
|
||||||
Depends: libjemalloc2
|
|
||||||
Maintainer: Julio <me@julio.al>
|
|
||||||
Description: Nginx L7 DDoS Protection (The-World-Is-Yours), built by RAWeb CI for ${TARGET}.
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# ---- DEBIAN/postinst -------------------------------------------
|
cp /usr/sbin/nginx "${PKG_DIR}/usr/sbin/"
|
||||||
cat > "${DEB_DIR}/postinst" <<"EOFPOSTINST"
|
cp -R /nginx/* "${PKG_DIR}/nginx/" || true
|
||||||
#!/bin/bash
|
cp /etc/systemd/system/nginx.service "${PKG_DIR}/etc/systemd/system/"
|
||||||
# Idempotent: safe on first install, upgrade, and reinstall.
|
cp -R /hostdata/default "${PKG_DIR}/hostdata/" || true
|
||||||
useradd -r -d /usr/local/nginx -s /bin/false nginx 2>/dev/null || true
|
cp -R /usr/nginx_lua "${PKG_DIR}/usr/" || true
|
||||||
install -d -o nginx -g nginx -m 0755 \
|
|
||||||
/usr/local/nginx \
|
|
||||||
/usr/local/nginx/client_body_temp \
|
|
||||||
/usr/local/nginx/proxy_temp \
|
|
||||||
/usr/local/nginx/fastcgi_temp \
|
|
||||||
/usr/local/nginx/uwsgi_temp \
|
|
||||||
/usr/local/nginx/scgi_temp \
|
|
||||||
/var/log/nginx
|
|
||||||
chown -R nginx:nginx /var/log/nginx /nginx /usr/local/nginx 2>/dev/null || true
|
|
||||||
systemctl daemon-reload 2>/dev/null || true
|
|
||||||
systemctl enable nginx.service 2>/dev/null || true
|
|
||||||
systemctl restart nginx.service 2>/dev/null || true
|
|
||||||
exit 0
|
|
||||||
EOFPOSTINST
|
|
||||||
chmod 755 "${DEB_DIR}/postinst"
|
|
||||||
|
|
||||||
dpkg-deb --build "${PKG_DIR}"
|
# Bundle every shared library nginx links against. ldd resolves
|
||||||
cp "${PKG_DIR}.deb" /repo/dist/
|
# against THIS container's libraries (not the runner host) so the
|
||||||
|
# .deb gets the correct per-distro libs.
|
||||||
|
for lib in $(ldd /usr/sbin/nginx | grep '=> /' | awk '{print $3}'); do
|
||||||
|
cp "$lib" "${PKG_DIR}/usr/lib/" || true
|
||||||
|
done
|
||||||
|
|
||||||
# Hand ownership back to the runner UID so the host job can read.
|
# ---- DEBIAN/control --------------------------------------------
|
||||||
chown $(stat -c "%u:%g" /repo) /repo/dist/$(basename "${PKG_DIR}.deb")
|
mkdir -p "${DEB_DIR}"
|
||||||
|
cat > "${DEB_DIR}/control" <<EOF
|
||||||
|
Package: ${PKG_NAME}
|
||||||
|
Version: ${VERSION}
|
||||||
|
Section: base
|
||||||
|
Priority: optional
|
||||||
|
Architecture: ${ARCH}
|
||||||
|
Depends: libjemalloc2
|
||||||
|
Maintainer: Julio <me@julio.al>
|
||||||
|
Description: Nginx L7 DDoS Protection (The-World-Is-Yours), built by RAWeb CI for ${TARGET}.
|
||||||
|
EOF
|
||||||
|
|
||||||
# Stash version for the publish step.
|
# ---- DEBIAN/postinst -------------------------------------------
|
||||||
echo "${PKG_NAME}_${VERSION}_${ARCH}.deb" > /repo/dist/${TARGET}.name
|
cat > "${DEB_DIR}/postinst" <<'EOFPOSTINST'
|
||||||
echo "${VERSION}" > /repo/dist/${TARGET}.version
|
#!/bin/bash
|
||||||
echo "${PKG_NAME}" > /repo/dist/${TARGET}.pkg
|
# Idempotent: safe on first install, upgrade, and reinstall.
|
||||||
'
|
useradd -r -d /usr/local/nginx -s /bin/false nginx 2>/dev/null || true
|
||||||
|
install -d -o nginx -g nginx -m 0755 \
|
||||||
|
/usr/local/nginx \
|
||||||
|
/usr/local/nginx/client_body_temp \
|
||||||
|
/usr/local/nginx/proxy_temp \
|
||||||
|
/usr/local/nginx/fastcgi_temp \
|
||||||
|
/usr/local/nginx/uwsgi_temp \
|
||||||
|
/usr/local/nginx/scgi_temp \
|
||||||
|
/var/log/nginx
|
||||||
|
chown -R nginx:nginx /var/log/nginx /nginx /usr/local/nginx 2>/dev/null || true
|
||||||
|
systemctl daemon-reload 2>/dev/null || true
|
||||||
|
systemctl enable nginx.service 2>/dev/null || true
|
||||||
|
systemctl restart nginx.service 2>/dev/null || true
|
||||||
|
exit 0
|
||||||
|
EOFPOSTINST
|
||||||
|
chmod 755 "${DEB_DIR}/postinst"
|
||||||
|
|
||||||
|
dpkg-deb --build "${PKG_DIR}"
|
||||||
|
DEB_FILE="${PKG_DIR}.deb"
|
||||||
|
|
||||||
# Surface the artifact paths for the next step.
|
|
||||||
DEB_FILE="$PWD/dist/$(cat dist/${TARGET}.name)"
|
|
||||||
PKG_NAME="$(cat dist/${TARGET}.pkg)"
|
|
||||||
VERSION="$(cat dist/${TARGET}.version)"
|
|
||||||
{
|
{
|
||||||
echo "deb_file=${DEB_FILE}"
|
echo "deb_file=${DEB_FILE}"
|
||||||
echo "version=${VERSION}"
|
echo "version=${VERSION}"
|
||||||
@@ -126,10 +161,15 @@ jobs:
|
|||||||
|
|
||||||
ls -la "${DEB_FILE}"
|
ls -la "${DEB_FILE}"
|
||||||
sha256sum "${DEB_FILE}"
|
sha256sum "${DEB_FILE}"
|
||||||
|
|
||||||
|
# Each matrix target uses its own dedicated Nexus user (ci-trixie /
|
||||||
|
# ci-raccoon) whose role is scoped to that ONE apt-hosted repo.
|
||||||
|
# Verified at provisioning time: each user gets 403 trying to touch
|
||||||
|
# the other repo. Admin credentials are NOT used by CI.
|
||||||
- name: Publish to Nexus (${{ matrix.target }})
|
- name: Publish to Nexus (${{ matrix.target }})
|
||||||
env:
|
env:
|
||||||
NEXUS_USER: ${{ secrets.NEXUS_USER }}
|
NEXUS_USER: ${{ secrets[matrix.nexus_user_secret] }}
|
||||||
NEXUS_PASS: ${{ secrets.NEXUS_PASS }}
|
NEXUS_PASS: ${{ secrets[matrix.nexus_pass_secret] }}
|
||||||
NEXUS_URL: ${{ secrets.NEXUS_URL }}
|
NEXUS_URL: ${{ secrets.NEXUS_URL }}
|
||||||
NEXUS_REPO: ${{ secrets[matrix.nexus_repo_secret] }}
|
NEXUS_REPO: ${{ secrets[matrix.nexus_repo_secret] }}
|
||||||
DEB_FILE: ${{ steps.pkg.outputs.deb_file }}
|
DEB_FILE: ${{ steps.pkg.outputs.deb_file }}
|
||||||
@@ -139,6 +179,11 @@ jobs:
|
|||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
umask 077
|
umask 077
|
||||||
|
|
||||||
|
# Need curl + python3 to talk to Nexus REST. python3 came with the
|
||||||
|
# build deps; curl was installed by `bash build/X.sh new`. Add
|
||||||
|
# explicitly anyway since this step is independent.
|
||||||
|
apt-get install -y -q --no-install-recommends curl python3 ca-certificates >/dev/null
|
||||||
|
|
||||||
SECDIR="$(mktemp -d -p /dev/shm twiy-XXXXXXXX 2>/dev/null \
|
SECDIR="$(mktemp -d -p /dev/shm twiy-XXXXXXXX 2>/dev/null \
|
||||||
|| mktemp -d -t twiy-XXXXXXXX)"
|
|| mktemp -d -t twiy-XXXXXXXX)"
|
||||||
chmod 700 "$SECDIR"
|
chmod 700 "$SECDIR"
|
||||||
@@ -152,6 +197,8 @@ jobs:
|
|||||||
printf 'machine %s login %s password %s\n' \
|
printf 'machine %s login %s password %s\n' \
|
||||||
"$NEXUS_HOST" "$NEXUS_USER" "$NEXUS_PASS" > "$SECDIR/netrc"
|
"$NEXUS_HOST" "$NEXUS_USER" "$NEXUS_PASS" > "$SECDIR/netrc"
|
||||||
unset NEXUS_USER NEXUS_PASS
|
unset NEXUS_USER NEXUS_PASS
|
||||||
|
|
||||||
|
# Replace prior version of this same package in this same repo.
|
||||||
OLD_ID="$(curl -fsS --netrc-file "$SECDIR/netrc" \
|
OLD_ID="$(curl -fsS --netrc-file "$SECDIR/netrc" \
|
||||||
"$NEXUS_URL/service/rest/v1/components?repository=$NEXUS_REPO" \
|
"$NEXUS_URL/service/rest/v1/components?repository=$NEXUS_REPO" \
|
||||||
| PKG_NAME="$PKG_NAME" python3 -c '
|
| PKG_NAME="$PKG_NAME" python3 -c '
|
||||||
|
|||||||
Reference in New Issue
Block a user