Files
theraw f77d853118
build-and-publish / build (Raccoon, ubuntu:26.04, NEXUS_PASS_RACCOON, NEXUS_REPO_RACCOON, NEXUS_USER_RACCOON, raccoon) (push) Successful in 3m33s
build-and-publish / build (Trixie, debian:13, NEXUS_PASS_TRIXIE, NEXUS_REPO_TRIXIE, NEXUS_USER_TRIXIE, trixie) (push) Successful in 3m19s
package update
2026-06-09 05:11:17 +00:00

188 lines
7.7 KiB
YAML

name: build-and-publish
on:
push:
branches: [master]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
target: [trixie, raccoon]
include:
- target: trixie
image: debian:13
distro_dir: Trixie
nexus_repo_secret: NEXUS_REPO_TRIXIE
nexus_user_secret: NEXUS_USER_TRIXIE
nexus_pass_secret: NEXUS_PASS_TRIXIE
- target: raccoon
image: ubuntu:26.04
distro_dir: Raccoon
nexus_repo_secret: NEXUS_REPO_RACCOON
nexus_user_secret: NEXUS_USER_RACCOON
nexus_pass_secret: NEXUS_PASS_RACCOON
container:
image: ${{ matrix.image }}
steps:
- name: Bootstrap
run: |
apt-get update -qq
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
git ca-certificates nodejs
- name: Checkout
uses: actions/checkout@v4
- name: Build
id: pkg
env:
TARGET: ${{ matrix.target }}
DISTRO_DIR: ${{ matrix.distro_dir }}
run: |
set -euo pipefail
REPO_ROOT="$PWD" # captured before any cd in the build script
touch /.dockerenv
bash build/${TARGET}.sh new
bash build/${TARGET}.sh build
bash build/${TARGET}.sh postfix
NGINX_VER="$(nginx -v 2>&1 | awk -F/ '{print $2}')"
VERSION="${NGINX_VER}-${GITHUB_RUN_NUMBER:-1}~${TARGET}"
ARCH="amd64"
assemble_deb() {
local pkg_name="$1" unit_src="$2" conflicts="$3"
local pkg_dir="/opt/${pkg_name}_${VERSION}_${ARCH}"
local deb_dir="${pkg_dir}/DEBIAN"
mkdir -p "${pkg_dir}/usr/sbin" \
"${pkg_dir}/etc/systemd/system" \
"${pkg_dir}/usr/lib" \
"${pkg_dir}/usr/nginx_lua" \
"${pkg_dir}/usr/share/twiy/defaults/nginx" \
"${pkg_dir}/nginx/live" "${pkg_dir}/nginx/conf.d" \
"${pkg_dir}/nginx/config" "${pkg_dir}/nginx/modsec" \
"${pkg_dir}/nginx/modules"
cp /usr/sbin/nginx "${pkg_dir}/usr/sbin/"
# /nginx ships as an EMPTY, dpkg-owned skeleton (above): the dirs
# are tracked so upgrades from the old layout don't warn about
# "unable to delete old directory /nginx", but NO config file under
# it is tracked. The pristine configs go into a defaults stash;
# postinst places them into /nginx only when missing and never
# overwrites an admin-edited file (drops <file>.new instead).
# /hostdata is intentionally NOT packaged or seeded — postinst only
# ensures the directory exists and never removes it.
cp -R /nginx/. "${pkg_dir}/usr/share/twiy/defaults/nginx/" || true
cp "${unit_src}" "${pkg_dir}/etc/systemd/system/nginx.service"
cp -R /usr/nginx_lua "${pkg_dir}/usr/" || true
for d in /usr/local/aws-lc /usr/local/LuaJIT /usr/local/modsecurity /usr/local/zlib-ng; do
[ -d "$d" ] && cp -R "$d" "${pkg_dir}/usr/local/" || true
done
mkdir -p "${pkg_dir}/usr/local/lib"
cp -R /usr/local/lib/. "${pkg_dir}/usr/local/lib/" 2>/dev/null || true
for lib in $(ldd /usr/sbin/nginx | grep '=> /' | awk '{print $3}'); do
case "$lib" in /usr/local/*) continue ;; esac
cp "$lib" "${pkg_dir}/usr/lib/" || true
done
mkdir -p "${deb_dir}"
printf 'Package: %s\nVersion: %s\nSection: base\nPriority: optional\nArchitecture: %s\nDepends: libjemalloc2, libsystemd0\nConflicts: %s\nReplaces: %s\nMaintainer: Julio <me@julio.al>\nDescription: Nginx L7 DDoS Protection (%s), built by RAWeb CI for %s.\n' \
"${pkg_name}" "${VERSION}" "${ARCH}" "${conflicts}" "${conflicts}" "${pkg_name}" "${TARGET}" \
> "${deb_dir}/control"
# Shared maintainer scripts:
# preinst — backs up /nginx before an upgrade unpacks (so admin
# configs survive the migration off dpkg tracking).
# postinst — restores that backup, then seeds /nginx defaults
# without overwriting any file already there.
cp "${REPO_ROOT}/build/deb/preinst" "${deb_dir}/preinst"
cp "${REPO_ROOT}/build/deb/postinst" "${deb_dir}/postinst"
chmod 755 "${deb_dir}/preinst" "${deb_dir}/postinst"
dpkg-deb --build "${pkg_dir}"
}
assemble_deb "twiy" "${REPO_ROOT}/static/${DISTRO_DIR}/nginx.service" "twiy-raweb"
assemble_deb "twiy-raweb" "${REPO_ROOT}/static/${DISTRO_DIR}/nginx-raweb.service" "twiy"
DEB_TWIY="/opt/twiy_${VERSION}_${ARCH}.deb"
DEB_RAWEB="/opt/twiy-raweb_${VERSION}_${ARCH}.deb"
{
echo "deb_twiy=${DEB_TWIY}"
echo "deb_raweb=${DEB_RAWEB}"
echo "version=${VERSION}"
} >> "$GITHUB_OUTPUT"
ls -la /opt/twiy*.deb
sha256sum /opt/twiy*.deb
- name: Publish
env:
NEXUS_USER: ${{ secrets[matrix.nexus_user_secret] }}
NEXUS_PASS: ${{ secrets[matrix.nexus_pass_secret] }}
NEXUS_URL: ${{ secrets.NEXUS_URL }}
NEXUS_REPO: ${{ secrets[matrix.nexus_repo_secret] }}
DEB_TWIY: ${{ steps.pkg.outputs.deb_twiy }}
DEB_RAWEB: ${{ steps.pkg.outputs.deb_raweb }}
TARGET: ${{ matrix.target }}
run: |
set -euo pipefail
umask 077
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 \
|| mktemp -d -t twiy-XXXXXXXX)"
chmod 700 "$SECDIR"
cleanup() {
find "$SECDIR" -type f -exec shred -uz {} + 2>/dev/null || true
rm -rf "$SECDIR"
}
trap cleanup EXIT INT TERM HUP
NEXUS_HOST="$(printf '%s' "$NEXUS_URL" | awk -F/ '{print $3}')"
printf 'machine %s login %s password %s\n' \
"$NEXUS_HOST" "$NEXUS_USER" "$NEXUS_PASS" > "$SECDIR/netrc"
unset NEXUS_USER NEXUS_PASS
publish_one() {
local deb="$1" pkg_name="$2"
local old_id
old_id="$(curl -fsS --netrc-file "$SECDIR/netrc" \
"$NEXUS_URL/service/rest/v1/components?repository=$NEXUS_REPO" \
| PKG_NAME="$pkg_name" python3 -c '
import sys, json, os
for c in json.load(sys.stdin).get("items", []):
if c.get("name") == os.environ["PKG_NAME"]:
print(c["id"]); break
' || true)"
if [ -n "$old_id" ]; then
curl -fsS -X DELETE --netrc-file "$SECDIR/netrc" \
"$NEXUS_URL/service/rest/v1/components/$old_id" -o /dev/null
fi
local http
http="$(curl -sS --netrc-file "$SECDIR/netrc" \
-o "$SECDIR/upload.body" -w '%{http_code}' \
-X POST -F "apt.asset=@$deb" \
"$NEXUS_URL/service/rest/v1/components?repository=$NEXUS_REPO")"
case "$http" in
201|204) echo "[$TARGET] uploaded $(basename "$deb")" ;;
*) echo "[$TARGET] upload failed for $pkg_name (HTTP $http)"; cat "$SECDIR/upload.body"; exit 1 ;;
esac
}
publish_one "$DEB_TWIY" "twiy"
publish_one "$DEB_RAWEB" "twiy-raweb"