feat 增加记录用户数的功能 #32
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and Release | |
| on: | |
| push: | |
| branches: [ main, master ] | |
| tags: [ 'v*' ] | |
| pull_request: | |
| branches: [ main, master ] | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| jobs: | |
| # ═══════════════════════════════════════════════════════════════════ | |
| # Linux — Ubuntu, dynamic linking, bundle .so files | |
| # ═══════════════════════════════════════════════════════════════════ | |
| build-linux: | |
| runs-on: ubuntu-24.04 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - arch: amd64 | |
| artifact: phira-mp-server-linux-amd64 | |
| deb_arch: amd64 | |
| triple: x86_64-linux-gnu | |
| cxx: g++ | |
| cc: gcc | |
| cross_pkg: "" | |
| is_cross: false | |
| - arch: arm64 | |
| artifact: phira-mp-server-linux-arm64 | |
| deb_arch: arm64 | |
| triple: aarch64-linux-gnu | |
| cxx: aarch64-linux-gnu-g++ | |
| cc: aarch64-linux-gnu-gcc | |
| cross_pkg: g++-aarch64-linux-gnu | |
| is_cross: true | |
| - arch: armhf | |
| artifact: phira-mp-server-linux-armhf | |
| deb_arch: armhf | |
| triple: arm-linux-gnueabihf | |
| cxx: arm-linux-gnueabihf-g++ | |
| cc: arm-linux-gnueabihf-gcc | |
| cross_pkg: g++-arm-linux-gnueabihf | |
| is_cross: true | |
| env: | |
| SYSROOT: /home/runner/sysroot | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up multiarch apt (cross-compile only) | |
| if: matrix.is_cross | |
| run: | | |
| sudo dpkg --add-architecture ${{ matrix.deb_arch }} | |
| sudo sed -i '/^URIs:/i Architectures: amd64' /etc/apt/sources.list.d/ubuntu.sources | |
| CODENAME=$(lsb_release -cs) | |
| printf 'Types: deb\nURIs: http://ports.ubuntu.com/ubuntu-ports\nSuites: %s %s-updates %s-security\nComponents: main universe\nArchitectures: %s\nSigned-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg\n' \ | |
| "$CODENAME" "$CODENAME" "$CODENAME" "${{ matrix.deb_arch }}" \ | |
| | sudo tee /etc/apt/sources.list.d/${{ matrix.deb_arch }}-cross.sources | |
| sudo apt-get update | |
| - name: Install tools and cross-compiler | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y build-essential make pkg-config cmake ninja-build patchelf | |
| if [ -n "${{ matrix.cross_pkg }}" ]; then | |
| sudo apt-get install -y ${{ matrix.cross_pkg }} | |
| fi | |
| - name: Install library dependencies from apt | |
| run: | | |
| S="" | |
| if [ "${{ matrix.is_cross }}" = "true" ]; then S=":${{ matrix.deb_arch }}"; fi | |
| sudo apt-get install -y libboost-dev nlohmann-json3-dev | |
| sudo apt-get install -y \ | |
| libssl-dev${S} \ | |
| libcurl4-openssl-dev${S} \ | |
| zlib1g-dev${S} \ | |
| uuid-dev${S} \ | |
| libsqlite3-dev${S} | |
| - name: Prepare sysroot | |
| run: mkdir -p $SYSROOT/lib/pkgconfig $SYSROOT/include | |
| - name: Build fmt from source | |
| run: | | |
| cd /tmp && git clone --depth 1 --branch 10.2.1 https://github.com/fmtlib/fmt.git && cd fmt | |
| cmake -B build -G Ninja \ | |
| -DCMAKE_C_COMPILER=${{ matrix.cc }} \ | |
| -DCMAKE_CXX_COMPILER=${{ matrix.cxx }} \ | |
| -DCMAKE_INSTALL_PREFIX=$SYSROOT \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DBUILD_SHARED_LIBS=OFF -DFMT_TEST=OFF -DFMT_DOC=OFF | |
| cmake --build build -j$(nproc) && cmake --install build | |
| - name: Build spdlog from source | |
| run: | | |
| cd /tmp && git clone --depth 1 --branch v1.14.1 https://github.com/gabime/spdlog.git && cd spdlog | |
| cmake -B build -G Ninja \ | |
| -DCMAKE_C_COMPILER=${{ matrix.cc }} \ | |
| -DCMAKE_CXX_COMPILER=${{ matrix.cxx }} \ | |
| -DCMAKE_INSTALL_PREFIX=$SYSROOT \ | |
| -DCMAKE_PREFIX_PATH=$SYSROOT \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DBUILD_SHARED_LIBS=OFF \ | |
| -DSPDLOG_BUILD_EXAMPLE=OFF -DSPDLOG_BUILD_TESTS=OFF \ | |
| -DSPDLOG_FMT_EXTERNAL=ON | |
| cmake --build build -j$(nproc) && cmake --install build | |
| - name: Build argon2 from source | |
| run: | | |
| cd /tmp && git clone --depth 1 https://github.com/P-H-C/phc-winner-argon2.git && cd phc-winner-argon2 | |
| ${{ matrix.cc }} -std=c89 -O2 -fPIC -c src/argon2.c -Iinclude -o argon2.o | |
| ${{ matrix.cc }} -std=c89 -O2 -fPIC -c src/core.c -Iinclude -o core.o | |
| ${{ matrix.cc }} -std=c89 -O2 -fPIC -c src/blake2/blake2b.c -Iinclude -o blake2b.o | |
| ${{ matrix.cc }} -std=c89 -O2 -fPIC -c src/thread.c -Iinclude -o thread.o | |
| ${{ matrix.cc }} -std=c89 -O2 -fPIC -c src/encoding.c -Iinclude -o encoding.o | |
| ${{ matrix.cc }} -std=c89 -O2 -fPIC -c src/ref.c -Iinclude -o ref.o | |
| ar rcs $SYSROOT/lib/libargon2.a argon2.o core.o blake2b.o thread.o encoding.o ref.o | |
| cp include/argon2.h $SYSROOT/include/ | |
| - name: Build phira-mp-server | |
| run: | | |
| LIBDIR="/usr/lib/${{ matrix.triple }}" | |
| export PKG_CONFIG_PATH="${SYSROOT}/lib/pkgconfig:${SYSROOT}/lib64/pkgconfig:${LIBDIR}/pkgconfig:/usr/share/pkgconfig" | |
| export PKG_CONFIG_LIBDIR="${PKG_CONFIG_PATH}" | |
| make -j$(nproc) \ | |
| CXX="${{ matrix.cxx }}" \ | |
| TARGET=phira-mp-server \ | |
| CXXFLAGS="-std=c++20 -Wall -Wextra -O2 -pthread \ | |
| -DLOCALES_DIR=./locales \ | |
| -DSPDLOG_FMT_EXTERNAL -DSPDLOG_COMPILED_LIB \ | |
| -I${SYSROOT}/include \ | |
| $(pkg-config --cflags openssl libcurl nlohmann_json sqlite3 2>/dev/null || true)" \ | |
| LDFLAGS="-L${SYSROOT}/lib -L${LIBDIR} \ | |
| -Wl,-rpath,'\$\$ORIGIN/lib'" \ | |
| LIBS="-lspdlog -lfmt \ | |
| -lcurl -lssl -lcrypto \ | |
| -largon2 -luuid -lz -lsqlite3 \ | |
| -lpthread -ldl" | |
| file phira-mp-server | |
| ls -lh phira-mp-server | |
| - name: Collect .so files and package | |
| run: | | |
| TRIPLE="${{ matrix.triple }}" | |
| LIBDIR="/usr/lib/${TRIPLE}" | |
| DEST="release/${{ matrix.artifact }}" | |
| mkdir -p "$DEST/lib" | |
| cp phira-mp-server "$DEST/" | |
| cp -r locales "$DEST/" | |
| # Download CA certificate bundle | |
| curl -sL -o "$DEST/cacert.pem" https://curl.se/ca/cacert.pem | |
| # ── Collect ALL .so dependencies with correct sonames ── | |
| # The key insight: ldd output shows "soname => /full/path (0x...)" | |
| # We must copy the FILE at /full/path but name it as the SONAME. | |
| # This avoids the bug where libfoo.so.2 is needed but we copy | |
| # libfoo.so.2.0.25 (wrong name). | |
| echo "=== Collecting .so files ===" | |
| collect_libs() { | |
| local binary="$1" | |
| if [ "${{ matrix.is_cross }}" = "true" ]; then | |
| # Cross: use readelf to get NEEDED, then find+copy with soname | |
| ${{ matrix.triple }}-readelf -d "$binary" 2>/dev/null | grep NEEDED | sed 's/.*\[\(.*\)\]/\1/' | while read -r soname; do | |
| case "$soname" in | |
| linux-*|ld-*|libc.so*|libm.so*|libdl.so*|libpthread.so*|librt.so*|libgcc_s*|libstdc++*) continue ;; | |
| esac | |
| [ -f "$DEST/lib/$soname" ] && continue | |
| for dir in "$SYSROOT/lib" "$LIBDIR" "/usr/lib" "/lib/${TRIPLE}"; do | |
| real=$(find "$dir" -name "${soname}*" 2>/dev/null | head -1) | |
| if [ -n "$real" ] && [ -e "$real" ]; then | |
| cp -L "$real" "$DEST/lib/$soname" | |
| echo " COPY: $real -> lib/$soname" | |
| break | |
| fi | |
| done | |
| done | |
| else | |
| # Native: use ldd which recursively resolves ALL deps | |
| ldd "$binary" 2>/dev/null | while read -r line; do | |
| # Parse: "libfoo.so.2 => /usr/lib/x86_64-linux-gnu/libfoo.so.2 (0x...)" | |
| soname=$(echo "$line" | awk '{print $1}') | |
| realpath=$(echo "$line" | awk '{print $3}') | |
| case "$soname" in | |
| linux-*|ld-*|libc.so*|libm.so*|libdl.so*|libpthread.so*|librt.so*|libgcc_s*|libstdc++*) continue ;; | |
| esac | |
| [ -z "$realpath" ] || [ ! -f "$realpath" ] && continue | |
| [ -f "$DEST/lib/$soname" ] && continue | |
| cp -L "$realpath" "$DEST/lib/$soname" | |
| echo " COPY: $realpath -> lib/$soname" | |
| done | |
| fi | |
| } | |
| collect_libs phira-mp-server | |
| # Create start.sh wrapper | |
| printf '#!/bin/sh\nDIR="$(cd "$(dirname "$0")" && pwd)"\nexport LD_LIBRARY_PATH="$DIR/lib:$LD_LIBRARY_PATH"\nexec "$DIR/phira-mp-server" "$@"\n' > "$DEST/start.sh" | |
| chmod +x "$DEST/start.sh" | |
| # Set RPATH on amd64 | |
| if [ "${{ matrix.is_cross }}" = "false" ] && command -v patchelf >/dev/null 2>&1; then | |
| patchelf --set-rpath '$ORIGIN/lib' "$DEST/phira-mp-server" || true | |
| fi | |
| echo "" | |
| echo "=== Package contents ===" | |
| find "$DEST" -type f | sort | |
| - name: Create tarball | |
| run: cd release && tar czf ${{ matrix.artifact }}.tar.gz ${{ matrix.artifact }}/ | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ matrix.artifact }} | |
| path: release/${{ matrix.artifact }}.tar.gz | |
| # ═══════════════════════════════════════════════════════════════════ | |
| # Windows amd64 — MSYS2 UCRT64, dynamic linking, bundle DLLs | |
| # ═══════════════════════════════════════════════════════════════════ | |
| build-windows: | |
| runs-on: windows-latest | |
| defaults: | |
| run: | |
| shell: msys2 {0} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup MSYS2 | |
| uses: msys2/setup-msys2@v2 | |
| with: | |
| msystem: UCRT64 | |
| update: true | |
| install: >- | |
| make pkgconf | |
| mingw-w64-ucrt-x86_64-gcc | |
| mingw-w64-ucrt-x86_64-boost | |
| mingw-w64-ucrt-x86_64-spdlog | |
| mingw-w64-ucrt-x86_64-fmt | |
| mingw-w64-ucrt-x86_64-nlohmann-json | |
| mingw-w64-ucrt-x86_64-curl | |
| mingw-w64-ucrt-x86_64-openssl | |
| mingw-w64-ucrt-x86_64-sqlite3 | |
| mingw-w64-ucrt-x86_64-ntldd | |
| - name: Install or build argon2 | |
| run: | | |
| pacman -S --noconfirm mingw-w64-ucrt-x86_64-argon2 2>/dev/null && exit 0 | |
| echo ">> Building argon2 from source" | |
| cd /tmp && curl -sL https://github.com/P-H-C/phc-winner-argon2/archive/refs/tags/20190702.tar.gz | tar xz | |
| cd phc-winner-argon2-20190702 | |
| gcc -std=c89 -O2 -c src/argon2.c -Iinclude -o a.o | |
| gcc -std=c89 -O2 -c src/core.c -Iinclude -o b.o | |
| gcc -std=c89 -O2 -c src/blake2/blake2b.c -Iinclude -o c.o | |
| gcc -std=c89 -O2 -c src/thread.c -Iinclude -o d.o | |
| gcc -std=c89 -O2 -c src/encoding.c -Iinclude -o e.o | |
| gcc -std=c89 -O2 -c src/ref.c -Iinclude -o f.o | |
| ar rcs libargon2.a a.o b.o c.o d.o e.o f.o | |
| cp libargon2.a /ucrt64/lib/ | |
| cp include/argon2.h /ucrt64/include/ | |
| mkdir -p /ucrt64/lib/pkgconfig | |
| printf 'prefix=/ucrt64\nlibdir=${prefix}/lib\nincludedir=${prefix}/include\n\nName: libargon2\nDescription: Argon2\nVersion: 20190702\nLibs: -L${libdir} -largon2\nCflags: -I${includedir}\n' \ | |
| > /ucrt64/lib/pkgconfig/libargon2.pc | |
| - name: Build | |
| run: | | |
| make -j$(nproc) TARGET=phira-mp-server.exe LOCALES_DIR=./locales | |
| file phira-mp-server.exe | |
| - name: Collect DLLs and package | |
| run: | | |
| DEST=release/phira-mp-server-windows-amd64 | |
| mkdir -p "$DEST" | |
| cp phira-mp-server.exe "$DEST/" | |
| echo "=== Collecting UCRT64 DLLs ===" | |
| ntldd -R phira-mp-server.exe | grep -i 'ucrt64' | awk '{print $1}' | sort -u | while IFS= read -r d | |
| do | |
| d=$(echo "$d" | tr -d '[:space:]') | |
| [ -n "$d" ] && [ -f "/ucrt64/bin/$d" ] && echo " COPY: $d" && cp "/ucrt64/bin/$d" "$DEST/" | |
| done | |
| cp -r locales "$DEST/" | |
| # Download CA certificate bundle | |
| curl -sL -o "$DEST/cacert.pem" https://curl.se/ca/cacert.pem | |
| echo "=== Package contents ===" | |
| ls -la "$DEST/" | |
| - name: Create zip | |
| shell: pwsh | |
| run: Compress-Archive -Path release/phira-mp-server-windows-amd64 -DestinationPath release/phira-mp-server-windows-amd64.zip | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: phira-mp-server-windows-amd64 | |
| path: release/phira-mp-server-windows-amd64.zip | |
| # ═══════════════════════════════════════════════════════════════════ | |
| release: | |
| needs: [build-linux, build-windows] | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| - run: find artifacts -type f | sort | |
| - uses: softprops/action-gh-release@v2 | |
| with: | |
| files: | | |
| artifacts/phira-mp-server-linux-amd64/*.tar.gz | |
| artifacts/phira-mp-server-linux-arm64/*.tar.gz | |
| artifacts/phira-mp-server-linux-armhf/*.tar.gz | |
| artifacts/phira-mp-server-windows-amd64/*.zip | |
| generate_release_notes: true |