pax_global_header00006660000000000000000000000064150573160410014514gustar00rootroot0000000000000052 comment=3139ca940f4035e1a5d0999f43ba9ab25d5ab9ef wiRedPanda-4.3.0/000077500000000000000000000000001505731604100135365ustar00rootroot00000000000000wiRedPanda-4.3.0/.devcontainer/000077500000000000000000000000001505731604100162755ustar00rootroot00000000000000wiRedPanda-4.3.0/.devcontainer/.dockerignore000066400000000000000000000003111505731604100207440ustar00rootroot00000000000000# Ignore build artifacts build/ CMakeCache.txt cmake_install.cmake CMakeFiles/ compile_commands.json # Ignore git .git/ # Ignore IDE files *.code-workspace # Keep devcontainer files !.devcontainer/ wiRedPanda-4.3.0/.devcontainer/Dockerfile000066400000000000000000000046161505731604100202760ustar00rootroot00000000000000# Use Ubuntu 22.04 LTS as base image FROM ubuntu:22.04 # Avoid warnings by switching to noninteractive ENV DEBIAN_FRONTEND=noninteractive # Install dependencies with proper ordering RUN apt-get update && apt-get install -y --no-install-recommends --no-install-suggests \ curl \ wget \ ca-certificates \ gnupg \ lsb-release \ apt-transport-https \ && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ && curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \ && chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ && apt-get update && apt-get install -y --no-install-recommends --no-install-suggests \ # Essential build tools build-essential \ clang \ clang-tools \ lld \ cmake \ ninja-build \ mold \ ccache \ pkg-config \ # Qt5 development packages qtbase5-dev \ qttools5-dev \ qttools5-dev-tools \ qtmultimedia5-dev \ qt5-qmake \ libqt5svg5-dev \ libqt5printsupport5 \ # Development tools git \ gh \ # Debugging tools gdb \ gdbserver \ lldb \ strace \ ltrace \ # Performance analysis tools valgrind \ perf-tools-unstable \ linux-tools-generic \ # Testing and coverage tools lcov \ # Python for build scripts python3 \ python3-pip \ # Node.js nodejs \ # Additional development utilities htop \ iotop \ sysstat \ lsof \ net-tools \ tcpdump \ vim \ nano \ tmux \ screen # Install Claude Code CLI RUN npm install -g @anthropic-ai/claude-code # Set up ccache for faster compilation RUN /usr/sbin/update-ccache-symlinks 2>/dev/null || true \ && ccache --set-config=max_size=2G \ && mkdir -p /home/vscode/.ccache \ && chown -R 1000:1000 /home/vscode/.ccache # Add ccache to PATH for all users ENV PATH="/usr/lib/ccache:${PATH}" ENV CCACHE_DIR="/home/vscode/.ccache" # Create workspace directory RUN mkdir -p /workspace # Set working directory WORKDIR /workspace # Set the default command CMD ["/bin/bash"] # Reset to default for subsequent operations ENV DEBIAN_FRONTEND=dialog wiRedPanda-4.3.0/.devcontainer/README.md000066400000000000000000000121751505731604100175620ustar00rootroot00000000000000# wiRedPanda Development Container This directory contains the configuration for a streamlined containerized development environment for wiRedPanda using Ubuntu 22.04 LTS. ## 🚀 Quick Start ### Prerequisites - [Docker](https://www.docker.com/get-started) installed and running - [Visual Studio Code](https://code.visualstudio.com/) with the [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) ### Using the Development Container 1. **Open in VS Code**: Open the wiRedPanda project folder in VS Code 2. **Reopen in Container**: When prompted, click "Reopen in Container" or use the command palette (`Ctrl+Shift+P`) and run "Dev Containers: Reopen in Container" 3. **Wait for Setup**: The container will build and set up automatically (this may take several minutes on first run) 4. **Start Developing**: Once complete, you'll have a fully configured development environment ## 🛠️ What's Included ### Development Tools - **Build System**: CMake 3.22+ with Ninja generator - **Compiler**: GCC 11+ with C++20 support - **Qt Framework**: Qt 5.15 with core, widgets, multimedia, SVG modules - **Performance**: Mold linker and ccache for faster builds - **Shell**: Zsh with Oh My Zsh for enhanced terminal experience - **AI Assistant**: Claude Code CLI for AI-powered development assistance ### VS Code Extensions - C/C++ extension pack (IntelliSense, debugging, themes) - CMake Tools for build management and configuration ### Core Utilities - **Version Control**: Git and GitHub CLI - **Languages**: Python 3, Node.js 20.x - **Testing**: lcov for coverage analysis - **Package Management**: pip3 and npm ## 📁 Container Structure ``` /workspace/ # Your project files (mounted from host) ├── app/ # Application source code ├── test/ # Test suite ├── build/ # Build output directory └── .devcontainer/ # Container configuration ``` ## 🔧 Build Commands ### VS Code Tasks (Recommended) Use **Ctrl+Shift+P** → "Tasks: Run Task": - **Build** - Build the project (default: Ctrl+Shift+B) - **Configure Debug** - Configure CMake for debug build - **Configure Release** - Configure CMake for release build - **Clean Build** - Clean and rebuild from scratch - **Run Tests** - Run the test suite ### Manual Build Process ```bash # Configure and build with CMake/Ninja cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug cmake --build build ``` ## 🧪 Testing ```bash # Run all tests (automatic via VS Code task) # Ctrl+Shift+P → "Tasks: Run Task" → "Run Tests" # Manual test execution ./build/test/wiredpanda-test # Run specific test class ./build/test/wiredpanda-test TestBasicGates ``` ## 🖥️ Display Mode The container is configured to run in **offscreen mode** by default (`QT_QPA_PLATFORM=offscreen`), making it compatible with all host operating systems without requiring X11 setup. This is ideal for: - Running automated tests - CI/CD pipelines - Development on Windows/macOS hosts - Headless server environments ## 🐛 Troubleshooting ### Container Won't Start - Ensure Docker is running - Check Docker has enough resources allocated - Try rebuilding: "Dev Containers: Rebuild Container" ### Build Failures - Check Qt installation: `qt5-qmake --version` - Verify CMake configuration: `cd build && cmake ..` - Clean build: `rm -rf build && mkdir build` ### Permission Issues - The container user (developer) should have UID 1000 - If issues persist, rebuild container with correct UID mapping ## 🔄 Updating the Container When the Dockerfile changes: 1. **Rebuild Container**: Use command palette → "Dev Containers: Rebuild Container" 2. **Clean Rebuild**: Use "Dev Containers: Rebuild Container Without Cache" ## 📝 Customization ### Adding Packages Edit `.devcontainer/Dockerfile` and add packages to the `apt-get install` command. ### VS Code Settings Modify `.devcontainer/devcontainer.json` to change VS Code settings and extensions. ### Environment Variables Add environment variables in the `containerEnv` section of `devcontainer.json`. ## 🤝 Development Workflow 1. **Code**: Write code using VS Code with full IntelliSense support 2. **Build**: Use cmake and ninja commands 3. **Test**: Run test binaries to verify functionality 4. **Debug**: Use VS Code's integrated debugger 5. **AI Assist**: Use Claude Code CLI for code assistance 6. **Commit**: Git is pre-configured for version control ## 🔒 Security Notes - Container runs as non-root user `developer` - Minimal package installation for reduced attack surface - No X11 forwarding required (offscreen mode) ## 📚 Additional Resources - [Dev Containers Documentation](https://code.visualstudio.com/docs/devcontainers/containers) - [Qt Documentation](https://doc.qt.io/) - [CMake Documentation](https://cmake.org/documentation/) - [Claude Code Documentation](https://docs.anthropic.com/en/docs/claude-code) - [wiRedPanda Project README](../README.md) ## 🐛 Reporting Issues If you encounter issues with the development container, please: 1. Check this README for troubleshooting steps 2. Verify your host system requirements 3. Report issues with container logs and system information wiRedPanda-4.3.0/.devcontainer/devcontainer.json000066400000000000000000000055131505731604100216550ustar00rootroot00000000000000{ "$schema": "https://raw.githubusercontent.com/devcontainers/spec/main/schemas/devContainer.schema.json", "name": "wiRedPanda Development Environment", // Use this image if it exists, otherwise build it "image": "wiredpanda-dev:latest", "build": { "dockerfile": "Dockerfile", "context": ".." }, // Configure tool-specific properties "customizations": { "vscode": { // Set *default* container specific settings.json values on container create "settings": { "terminal.integrated.defaultProfile.linux": "zsh", "cmake.configureOnOpen": true, "cmake.buildDirectory": "${workspaceFolder}/build", "cmake.generator": "Ninja", "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", "C_Cpp.default.compilerPath": "/usr/bin/g++", "C_Cpp.default.cStandard": "c17", "C_Cpp.default.cppStandard": "c++20" }, // Add the IDs of extensions you want installed when the container is created "extensions": [ "Anthropic.claude-code", "astro-build.astro-vscode", "bierner.markdown-mermaid", "eamodio.gitlens", "github.vscode-github-actions", "ms-python.python-extension-pack", "ms-vscode.cmake-tools", "ms-vscode.cpptools-extension-pack" ] } }, // Configure container user "remoteUser": "developer", // Enable debugging capabilities "runArgs": [ "--volume=/etc/timezone:/etc/timezone:ro", "--volume=/etc/localtime:/etc/localtime:ro", "--cap-add=SYS_PTRACE", "--security-opt=seccomp:unconfined" ], // Container environment variables "containerEnv": { "QT_QPA_PLATFORM": "offscreen", "QTDIR": "/usr/lib/qt5", "QT_PLUGIN_PATH": "/usr/lib/x86_64-linux-gnu/qt5/plugins" }, // Features to add to the dev container "features": { "ghcr.io/devcontainers/features/common-utils:2": { "installZsh": true, "configureZshAsDefaultShell": true, "installOhMyZsh": true, "upgradePackages": true, "username": "developer", "userUid": "1000", "userGid": "1000" } }, // Lifecycle scripts "initializeCommand": "echo 'Initializing wiRedPanda development container...'", "onCreateCommand": "echo 'Container created successfully'", "updateContentCommand": "echo 'Content updated'", // Set the default path that VS Code should open when connecting to the container "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached", "workspaceFolder": "/workspace" } wiRedPanda-4.3.0/.gitattributes000066400000000000000000000001121505731604100164230ustar00rootroot00000000000000# Auto detect text files and perform LF normalization * text=auto eol=lf wiRedPanda-4.3.0/.github/000077500000000000000000000000001505731604100150765ustar00rootroot00000000000000wiRedPanda-4.3.0/.github/workflows/000077500000000000000000000000001505731604100171335ustar00rootroot00000000000000wiRedPanda-4.3.0/.github/workflows/build.yml000066400000000000000000000046501505731604100207620ustar00rootroot00000000000000# Copyright 2015 - 2025, GIBIS-Unifesp and the wiRedPanda contributors # SPDX-License-Identifier: GPL-3.0-or-later name: Build on: push: branches-ignore: - master - wasm pull_request: branches: - master types: [opened, synchronize, reopened] jobs: build: strategy: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] qt: [5.15.2, 6.2.4, 6.5.3, 6.9.0] # ================================= runs-on: ${{ matrix.os }} if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name steps: - uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 - name: Install Ninja on Ubuntu if: runner.os == 'Linux' run: sudo apt-get update && sudo apt-get install -y ninja-build - name: Install Qt uses: jurplel/install-qt-action@v4 with: version: ${{ matrix.qt }} cache: true aqtversion: ==3.2.* modules: ${{ startsWith(matrix.qt, '6') && 'qtmultimedia qtimageformats' || '' }} - name: ccache uses: hendrikmuhs/ccache-action@v1.2 with: key: ${{ matrix.os }}-${{ matrix.qt }} # ================================= - name: Build Ubuntu if: runner.os == 'Linux' run: | cmake -S . -B build -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_PREFIX_PATH=$QT_INSTALL_PATH cmake --build build - name: Test Ubuntu if: runner.os == 'Linux' run: | QT_QPA_PLATFORM=offscreen ./build/wiredpanda-test # ================================= - name: Setup Windows MSVC Toolchain if: runner.os == 'Windows' uses: pbeast/gha-setup-vsdevenv@master - name: Build Windows if: runner.os == 'Windows' run: | cmake -S . -B build -G Ninja ` -DCMAKE_PREFIX_PATH=$QT_INSTALL_PATH cmake --build build - name: Test Windows if: runner.os == 'Windows' run: | ./build/wiredpanda-test.exe # ================================= - name: Build macOS if: runner.os == 'macOS' run: | cmake -S . -B build -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_PREFIX_PATH=$QT_INSTALL_PATH cmake --build build - name: Test macOS if: runner.os == 'macOS' run: | ./build/wiredpanda-test wiRedPanda-4.3.0/.github/workflows/codeql.yml000066400000000000000000000020721505731604100211260ustar00rootroot00000000000000# Copyright 2015 - 2025, GIBIS-Unifesp and the wiRedPanda contributors # SPDX-License-Identifier: GPL-3.0-or-later name: "CodeQL" on: push: branches: - master jobs: analyze: name: Analyze runs-on: ubuntu-latest permissions: actions: read contents: read security-events: write strategy: fail-fast: false steps: - name: Checkout repository uses: actions/checkout@v4 - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: languages: cpp - name: Install Qt5 uses: jurplel/install-qt-action@v4 with: version: 5.15.2 cache: true aqtversion: ==3.2.* - name: ccache uses: hendrikmuhs/ccache-action@v1.2 with: key: ubuntu-latest-5.15.2 - name: Build run: | cmake -B build -G Ninja cmake --build build --config Release - name: Test run: | QT_QPA_PLATFORM=offscreen ./build/wiredpanda-test - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 wiRedPanda-4.3.0/.github/workflows/coverage.yml000066400000000000000000000020271505731604100214520ustar00rootroot00000000000000# Copyright 2015 - 2025, GIBIS-Unifesp and the wiRedPanda contributors # SPDX-License-Identifier: GPL-3.0-or-later name: Coverage on: push: branches: - master jobs: Ubuntu-Qt5_15_2-Code_Coverage: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 - name: Install Qt5 uses: jurplel/install-qt-action@v4 with: version: 5.15.2 cache: true aqtversion: ==3.2.* - name: ccache uses: hendrikmuhs/ccache-action@v1.2 with: key: ubuntu-latest-5.15.2 - name: Build run: | cmake -B build -G Ninja -DENABLE_COVERAGE=ON cmake --build build --config Release - name: Test run: | QT_QPA_PLATFORM=offscreen ./build/wiredpanda-test - name: Upload coverage data run: | cd build gcov -abcfu $(find . -name "*.gcno") curl -Os https://uploader.codecov.io/latest/linux/codecov chmod +x ./codecov ./codecov wiRedPanda-4.3.0/.github/workflows/deploy.yml000066400000000000000000000662751505731604100211720ustar00rootroot00000000000000# Copyright 2015 - 2025, GIBIS-Unifesp and the wiRedPanda contributors # SPDX-License-Identifier: GPL-3.0-or-later name: Deploy on: release: types: [published] jobs: build: strategy: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] qt: [5.15.2, 6.9.0] # ================================= runs-on: ${{ matrix.os }} container: ${{ matrix.os == 'ubuntu-latest' && 'ubuntu:20.04' || '' }} steps: - name: Install Ubuntu dependencies if: runner.os == 'Linux' run: | export DEBIAN_FRONTEND=noninteractive apt-get update apt-get install -y software-properties-common add-apt-repository ppa:ubuntu-toolchain-r/test -y apt-get update apt-get install -y \ build-essential \ gcc-11 \ g++-11 \ git \ jq \ libasound2 \ libcups2 \ libcurl4-openssl-dev \ libfontconfig1-dev \ libfreetype6-dev \ libfuse2 \ libgstreamer-gl1.0-0 \ libx11-dev \ libx11-xcb-dev \ libxcb-cursor0 \ libxcb-glx0-dev \ libxcb-icccm4-dev \ libxcb-image0-dev \ libxcb-keysyms1-dev \ libxcb-randr0-dev \ libxcb-render-util0-dev \ libxcb-shape0-dev \ libxcb-shm0-dev \ libxcb-sync0-dev \ libxcb-xfixes0-dev \ libxcb1-dev \ libxext-dev \ libxfixes-dev \ libxi-dev \ libxkbcommon-dev \ libxkbcommon-x11-dev \ libxrandr2 \ libxrender-dev \ ninja-build \ sudo \ wget update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 110 --slave /usr/bin/g++ g++ /usr/bin/g++-11 - name: Install Modern CMake if: runner.os == 'Linux' run: | # Install CMake 3.25+ from Kitware's APT repository wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null echo 'deb https://apt.kitware.com/ubuntu/ focal main' | tee /etc/apt/sources.list.d/kitware.list >/dev/null apt-get update apt-get install -y cmake - name: Install Ubuntu Python if: runner.os == 'Linux' run: | apt-get install -y software-properties-common add-apt-repository ppa:deadsnakes/ppa apt-get update apt-get install -y curl python3.10 ln -sf /usr/bin/python3.10 /usr/bin/python3 curl -sS https://bootstrap.pypa.io/get-pip.py -o get-pip.py python3 get-pip.py python3 -m pip install --no-cache-dir --upgrade pip setuptools wheel - uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 - name: Extract Version run: echo "VERSION=$(echo $GITHUB_REF | sed 's|refs/tags/||')" >> $GITHUB_ENV shell: bash - name: Install Sentry CLI run: | if [ "$RUNNER_OS" == "Windows" ]; then LATEST_VERSION=$(curl -s https://api.github.com/repos/getsentry/sentry-cli/releases/latest | jq -r .tag_name) curl -LO "https://github.com/getsentry/sentry-cli/releases/download/$LATEST_VERSION/sentry-cli-Windows-x86_64.exe" mv sentry-cli-Windows-x86_64.exe sentry-cli.exe ACTUAL_VERSION=$(./sentry-cli.exe -V 2>&1 | tr -d '\r') if [[ ! "$ACTUAL_VERSION" =~ ^sentry-cli ]]; then echo "Downloaded Sentry CLI binary is invalid!" >&2 exit 1 fi else curl -sL https://sentry.io/get-cli/ | bash fi shell: bash - name: Install Qt uses: jurplel/install-qt-action@v4 with: version: ${{ matrix.qt }} arch: ${{ matrix.os == 'windows-latest' && matrix.qt == '5.15.2' && 'win32_msvc2019' || '' }} cache: true aqtversion: ==3.2.* modules: ${{ startsWith(matrix.qt, '6') && 'qtmultimedia qtimageformats debug_info' || 'debug_info' }} setup-python: ${{ matrix.os == 'ubuntu-latest' && 'false' || 'true' }} - name: ccache uses: hendrikmuhs/ccache-action@v1.2 with: key: ${{ matrix.os }}-${{ matrix.qt }} # ================================= - name: Compile Ubuntu Sentry SDK if: runner.os == 'Linux' run: | git clone --recursive https://github.com/getsentry/sentry-native.git mkdir -p sentry-native/build cd sentry-native/build cmake .. -B build -D SENTRY_BACKEND=crashpad -D CMAKE_BUILD_TYPE=RelWithDebInfo -G Ninja cmake --build build cmake --install build --prefix ../../thirdparty/sentry - name: Build Ubuntu if: runner.os == 'Linux' run: | cmake -B build -G Ninja cmake --build build --config Release mkdir -p build/lib cp thirdparty/sentry/bin/crashpad_handler build/ cp thirdparty/sentry/lib/libsentry.so build/lib/ # Ensure crashpad_handler is executable chmod +x build/crashpad_handler - name: Test Ubuntu if: runner.os == 'Linux' run: | QT_QPA_PLATFORM=offscreen ./build/wiredpanda-test - name: linuxdeployqt if: runner.os == 'Linux' run: | mkdir -p appimage appimage/lib cp app/resources/wpanda.desktop appimage/wpanda.desktop cp app/resources/wpanda.svg appimage/wpanda_icon.svg cp build/wiredpanda appimage cp build/crashpad_handler appimage/ cp thirdparty/sentry/lib/libsentry.so appimage/lib/ wget https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage chmod +x ./linuxdeployqt-continuous-x86_64.AppImage ./linuxdeployqt-continuous-x86_64.AppImage --appimage-extract VERSION=$VERSION ./squashfs-root/usr/bin/linuxdeployqt ./appimage/wiredpanda -appimage rm ./linuxdeployqt-continuous-x86_64.AppImage mv wiRedPanda-$VERSION-x86_64.AppImage wiRedPanda-$VERSION-Ubuntu-Qt${{ matrix.qt }}.AppImage - name: Validate Ubuntu Release Artifacts if: runner.os == 'Linux' run: | # Verify AppImage exists and is executable if [ ! -f "wiRedPanda-$VERSION-Ubuntu-Qt${{ matrix.qt }}.AppImage" ]; then echo "Error: AppImage not found" exit 1 fi # Verify AppImage build quality and structure chmod +x "wiRedPanda-$VERSION-Ubuntu-Qt${{ matrix.qt }}.AppImage" echo "Validating AppImage build quality..." # Check AppImage file properties APPIMAGE_FILE="wiRedPanda-$VERSION-Ubuntu-Qt${{ matrix.qt }}.AppImage" echo "AppImage file info:" ls -lh "$APPIMAGE_FILE" file "$APPIMAGE_FILE" # Extract AppImage to verify internal structure echo "Extracting AppImage to verify contents..." "./$APPIMAGE_FILE" --appimage-extract >/dev/null 2>&1 if [ ! -d "squashfs-root" ]; then echo "Error: AppImage extraction failed - corrupt AppImage" exit 1 fi echo "AppImage structure validation:" # Verify main executable exists and is properly linked if [ ! -f "squashfs-root/wiredpanda" ]; then echo "Error: Main executable missing from AppImage" exit 1 fi echo "✓ Main executable: $(ls -lh squashfs-root/wiredpanda)" echo "✓ Executable type: $(file squashfs-root/wiredpanda)" # Check Qt libraries are bundled QT_LIBS_COUNT=$(find squashfs-root -name "libQt*.so*" | wc -l) echo "✓ Qt libraries found: $QT_LIBS_COUNT" if [ "$QT_LIBS_COUNT" -lt 3 ]; then echo "Warning: Few Qt libraries found, may cause runtime issues" find squashfs-root -name "libQt*.so*" | head -10 fi # Verify desktop integration files if [ -f "squashfs-root/wpanda.desktop" ]; then echo "✓ Desktop integration file present" else echo "Warning: Desktop integration file missing" fi # Check dependencies are reasonable echo "✓ Executable dependencies (sample):" ldd squashfs-root/wiredpanda | head -10 | grep -v "not found" || echo "Some dependencies missing (may be normal)" echo "AppImage build quality validation completed successfully" # Verify required Sentry files are included if [ ! -f "appimage/lib/libsentry.so" ]; then echo "Error: Sentry library missing from AppImage" exit 1 fi if [ ! -f "appimage/crashpad_handler" ]; then echo "Error: Crashpad handler missing from AppImage" exit 1 fi # Log Sentry configuration for debugging echo "Sentry configuration check:" echo " - libsentry.so: $(ls -la appimage/lib/libsentry.so)" echo " - crashpad_handler: $(ls -la appimage/crashpad_handler)" echo " - RPATH settings: $(objdump -p appimage/wiredpanda | grep RPATH || echo 'No RPATH found')" echo "Ubuntu release artifacts validated successfully" - name: Upload Ubuntu Debug Symbols to Sentry if: runner.os == 'Linux' env: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} run: | git config --global --add safe.directory '*' sentry-cli login --auth-token "$SENTRY_AUTH_TOKEN" sentry-cli releases new "wiredpanda@$VERSION" -p wiredpanda sentry-cli debug-files upload --include-sources -p wiredpanda build/ sentry-cli debug-files upload --include-sources -p wiredpanda $QT_ROOT_DIR sentry-cli releases set-commits --auto "wiredpanda@$VERSION" --log-level=debug - name: Publish Ubuntu uses: softprops/action-gh-release@v2 if: runner.os == 'Linux' with: fail_on_unmatched_files: true files: '*.AppImage' # ================================= - name: Setup Windows MSVC Toolchain if: runner.os == 'Windows' uses: pbeast/gha-setup-vsdevenv@master with: arch: ${{ startsWith(matrix.qt, '5') && 'x86' || 'x64' }} - name: Compile Windows Sentry SDK if: runner.os == 'Windows' run: | git clone --recursive https://github.com/getsentry/sentry-native.git mkdir -p sentry-native/build cd sentry-native/build cmake .. -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo -G Ninja cmake --build build cmake --install build --prefix ../../thirdparty/sentry - name: Build Windows if: runner.os == 'Windows' run: | cmake -B build -G "Visual Studio 17 2022" -A ${{ startsWith(matrix.qt, '5') && 'Win32' || 'x64' }} cmake --build build --config Release cp thirdparty/sentry/bin/crashpad_handler.exe build/Release/ cp thirdparty/sentry/bin/sentry.dll build/Release/ cp thirdparty/sentry/bin/crashpad_wer.dll build/Release/ - name: Test Windows if: runner.os == 'Windows' run: | cd build/Release powershell -Command "Start-Process -FilePath 'wiredpanda-test.exe' -Wait -NoNewWindow" - name: windeployqt if: runner.os == 'Windows' run : | # Create clean distribution directory cd build mkdir wiredpanda-$env:VERSION # Copy only essential files to clean directory cp Release/wiredpanda.exe wiredpanda-$env:VERSION/ cp Release/crashpad_handler.exe wiredpanda-$env:VERSION/ cp Release/sentry.dll wiredpanda-$env:VERSION/ cp Release/crashpad_wer.dll wiredpanda-$env:VERSION/ cp -r ../examples wiredpanda-$env:VERSION/ # Run windeployqt in the clean directory cd wiredpanda-$env:VERSION windeployqt --compiler-runtime wiredpanda.exe # Create the ZIP from the clean directory cd .. Compress-Archive -Path wiredpanda-$env:VERSION -DestinationPath wiRedPanda-$env:VERSION-Windows-Qt${{ matrix.qt }}-Portable.zip - name: Validate Windows Release Artifacts if: runner.os == 'Windows' run: | # Verify ZIP file exists if (!(Test-Path "build/wiRedPanda-$env:VERSION-Windows-Qt${{ matrix.qt }}-Portable.zip")) { Write-Error "Error: Windows ZIP file not found" exit 1 } # Verify executable exists in the extracted folder if (!(Test-Path "build/wiredpanda-$env:VERSION/wiredpanda.exe")) { Write-Error "Error: wiredpanda.exe not found in package" exit 1 } # Verify required Sentry files are included if (!(Test-Path "build/wiredpanda-$env:VERSION/sentry.dll")) { Write-Error "Error: Sentry DLL missing from package" exit 1 } if (!(Test-Path "build/wiredpanda-$env:VERSION/crashpad_handler.exe")) { Write-Error "Error: Crashpad handler missing from package" exit 1 } # Validate Windows executable build quality Write-Output "Validating Windows executable build quality..." $executablePath = "build/wiredpanda-$env:VERSION/wiredpanda.exe" # Check executable file properties if (Test-Path $executablePath) { $fileInfo = Get-Item $executablePath Write-Output "✓ Executable file info:" Write-Output " Size: $([math]::Round($fileInfo.Length / 1MB, 2)) MB" Write-Output " Created: $($fileInfo.CreationTime)" Write-Output " Modified: $($fileInfo.LastWriteTime)" } else { Write-Error "Error: Main executable not found" exit 1 } # Check if executable is a valid PE file try { $peHeader = [System.IO.File]::ReadAllBytes($executablePath)[0..1] $peSignature = [System.Text.Encoding]::ASCII.GetString($peHeader) if ($peSignature -eq "MZ") { Write-Output "✓ Valid PE executable format" } else { Write-Output "Warning: Unexpected executable format" } } catch { Write-Output "Warning: Could not verify PE format" } # Check Qt DLLs are present $qtDlls = Get-ChildItem "build/wiredpanda-$env:VERSION" -Filter "Qt*.dll" | Measure-Object Write-Output "✓ Qt DLLs found: $($qtDlls.Count)" if ($qtDlls.Count -lt 3) { Write-Output "Warning: Few Qt DLLs found, may cause runtime issues" Get-ChildItem "build/wiredpanda-$env:VERSION" -Filter "Qt*.dll" | Select-Object Name, Length } # Check for required runtime libraries $requiredDlls = @("vcruntime*.dll", "msvcp*.dll") foreach ($pattern in $requiredDlls) { $found = Get-ChildItem "build/wiredpanda-$env:VERSION" -Filter $pattern | Measure-Object if ($found.Count -gt 0) { Write-Output "✓ Runtime libraries found: $pattern" } else { Write-Output "Warning: Runtime libraries not found: $pattern (may be system-provided)" } } # Verify examples directory if (Test-Path "build/wiredpanda-$env:VERSION/examples") { $exampleCount = (Get-ChildItem "build/wiredpanda-$env:VERSION/examples" -Recurse -File | Measure-Object).Count Write-Output "✓ Examples directory present with $exampleCount files" } else { Write-Output "Warning: Examples directory missing" } Write-Output "Windows build quality validation completed successfully" Write-Output "Windows release artifacts validated successfully" - name: Upload Windows Debug Symbols to Sentry if: runner.os == 'Windows' env: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} run: | ./sentry-cli.exe login --auth-token $env:SENTRY_AUTH_TOKEN ./sentry-cli.exe releases new wiredpanda@$env:VERSION -p wiredpanda ./sentry-cli.exe debug-files upload --include-sources -p wiredpanda build/ ./sentry-cli.exe debug-files upload --include-sources -p wiredpanda D:/a/wiRedPanda/Qt/ ./sentry-cli.exe releases set-commits --auto wiredpanda@$env:VERSION --log-level=debug - name: Publish Windows if: runner.os == 'Windows' uses: softprops/action-gh-release@v2 with: fail_on_unmatched_files: true files: 'build/*.zip' # ================================= - name: Compile macOS Sentry SDK if: runner.os == 'macOS' run: | git clone --recursive https://github.com/getsentry/sentry-native.git mkdir -p sentry-native/build cd sentry-native/build cmake .. -B build -D SENTRY_BACKEND=breakpad -D CMAKE_BUILD_TYPE=RelWithDebInfo -D CMAKE_OSX_ARCHITECTURES="x86_64;arm64" -G Ninja cmake --build build cmake --install build --prefix ../../thirdparty/sentry - name: Build macOS if: runner.os == 'macOS' run: | cmake -B build cmake --build build --config Release mkdir -p build/wiredpanda.app/Contents/MacOS mkdir -p build/wiredpanda.app/Contents/Frameworks # Copy the main executable to the app bundle cp build/wiredpanda build/wiredpanda.app/Contents/MacOS/ # Note: breakpad backend doesn't generate crashpad_handler (in-process crash handling) cp thirdparty/sentry/lib/libsentry.dylib build/wiredpanda.app/Contents/Frameworks/ - name: Generate macOS dSYM Symbols if: runner.os == 'macOS' run: | cd build dsymutil wiredpanda.app/Contents/MacOS/wiredpanda -o wiredpanda.app.dSYM - name: Test macOS if: runner.os == 'macOS' run: | ./build/wiredpanda-test - name: macdeployqt if: runner.os == 'macOS' run: | cd build # Verify app bundle structure before deployment echo "Verifying app bundle structure..." if [ ! -d "wiredpanda.app/Contents/MacOS" ]; then echo "Error: App bundle MacOS directory missing" exit 1 fi # Ensure executable has proper permissions and is linked correctly chmod +x wiredpanda.app/Contents/MacOS/wiredpanda # Create Info.plist if missing (helps macdeployqt identify the bundle) if [ ! -f "wiredpanda.app/Contents/Info.plist" ]; then echo "Creating missing Info.plist..." cat > wiredpanda.app/Contents/Info.plist << 'INFOPLIST' CFBundleExecutable wiredpanda CFBundleIdentifier com.wiredpanda.wiRedPanda CFBundleName wiRedPanda CFBundleVersion 1.0 CFBundlePackageType APPL INFOPLIST fi # Show Qt installation path and verify it's accessible echo "Qt installation path: $QT_ROOT_DIR" echo "Qt binary path: $(which macdeployqt)" # Check what frameworks the executable currently links to echo "Current framework dependencies:" otool -L wiredpanda.app/Contents/MacOS/wiredpanda | head -20 # Run macdeployqt with verbose output and additional options echo "Running macdeployqt with verbose output..." macdeployqt wiredpanda.app -verbose=2 -always-overwrite -dmg || { echo "macdeployqt failed, attempting with force option..." # If macdeployqt fails, try to manually copy Qt frameworks and try again mkdir -p wiredpanda.app/Contents/Frameworks # Find and copy critical Qt libraries that might be missing for qtlib in QtCore QtGui QtWidgets; do if [ -f "$QT_ROOT_DIR/lib/lib${qtlib}.dylib" ]; then echo "Manually copying $qtlib..." cp "$QT_ROOT_DIR/lib/lib${qtlib}.dylib" wiredpanda.app/Contents/Frameworks/ || true elif [ -f "$QT_ROOT_DIR/lib/${qtlib}.framework/${qtlib}" ]; then echo "Manually copying $qtlib framework..." cp -R "$QT_ROOT_DIR/lib/${qtlib}.framework" wiredpanda.app/Contents/Frameworks/ || true fi done # Try macdeployqt again after manual framework copying macdeployqt wiredpanda.app -verbose=2 -dmg } # Verify the DMG was created if [ ! -f "wiredpanda.dmg" ]; then echo "Error: DMG creation failed" ls -la exit 1 fi mv wiredpanda.dmg wiRedPanda-$VERSION-macOS-Qt${{ matrix.qt }}.dmg - name: Validate macOS Release Artifacts if: runner.os == 'macOS' run: | # Verify DMG file exists if [ ! -f "build/wiRedPanda-$VERSION-macOS-Qt${{ matrix.qt }}.dmg" ]; then echo "Error: macOS DMG file not found" exit 1 fi # Verify app bundle exists if [ ! -d "build/wiredpanda.app" ]; then echo "Error: wiredpanda.app bundle not found" exit 1 fi # Verify executable exists in app bundle if [ ! -f "build/wiredpanda.app/Contents/MacOS/wiredpanda" ]; then echo "Error: wiredpanda executable not found in app bundle" exit 1 fi # Verify required Sentry files are included (breakpad backend) if [ ! -f "build/wiredpanda.app/Contents/Frameworks/libsentry.dylib" ]; then echo "Error: Sentry library missing from app bundle" exit 1 fi # CRITICAL: Verify Qt frameworks are properly deployed echo "Checking Qt framework deployment..." FRAMEWORKS_DIR="build/wiredpanda.app/Contents/Frameworks" MISSING_FRAMEWORKS=() # Check for essential Qt frameworks for framework in QtCore QtGui QtWidgets; do if [ ! -d "$FRAMEWORKS_DIR/${framework}.framework" ] && [ ! -f "$FRAMEWORKS_DIR/lib${framework}.dylib" ]; then MISSING_FRAMEWORKS+=("$framework") fi done if [ ${#MISSING_FRAMEWORKS[@]} -gt 0 ]; then echo "Error: Missing Qt frameworks: ${MISSING_FRAMEWORKS[*]}" echo "Contents of Frameworks directory:" ls -la "$FRAMEWORKS_DIR/" || echo "Frameworks directory not found" echo "Executable dependencies:" otool -L "build/wiredpanda.app/Contents/MacOS/wiredpanda" | grep -E "(Qt|@rpath)" || echo "No Qt dependencies found" exit 1 fi # Verify frameworks are properly linked (no external Qt paths) echo "Verifying Qt framework linking..." EXTERNAL_QT_DEPS=$(otool -L "build/wiredpanda.app/Contents/MacOS/wiredpanda" | grep -E "/Users/.*/Qt|/usr/local.*/Qt" | wc -l) if [ "$EXTERNAL_QT_DEPS" -gt 0 ]; then echo "Warning: Found external Qt dependencies (may cause runtime issues):" otool -L "build/wiredpanda.app/Contents/MacOS/wiredpanda" | grep -E "/Users/.*/Qt|/usr/local.*/Qt" fi # Verify DMG contents by mounting it temporarily echo "Verifying DMG contents..." hdiutil attach "build/wiRedPanda-$VERSION-macOS-Qt${{ matrix.qt }}.dmg" -mountpoint /tmp/wiredpanda_dmg -readonly || { echo "Error: Failed to mount DMG for verification" exit 1 } # Check if the app in DMG has Qt frameworks if [ ! -d "/tmp/wiredpanda_dmg/wiredpanda.app/Contents/Frameworks" ]; then echo "Error: DMG app bundle missing Frameworks directory" hdiutil detach /tmp/wiredpanda_dmg exit 1 fi DMG_FRAMEWORKS_COUNT=$(find "/tmp/wiredpanda_dmg/wiredpanda.app/Contents/Frameworks" -name "*.framework" -o -name "*.dylib" | wc -l) echo "Found $DMG_FRAMEWORKS_COUNT frameworks/libraries in DMG" if [ "$DMG_FRAMEWORKS_COUNT" -lt 3 ]; then echo "Error: Insufficient frameworks in DMG (expected at least 3 Qt frameworks + Sentry)" echo "DMG Frameworks contents:" ls -la "/tmp/wiredpanda_dmg/wiredpanda.app/Contents/Frameworks/" hdiutil detach /tmp/wiredpanda_dmg exit 1 fi hdiutil detach /tmp/wiredpanda_dmg # Verify dSYM symbols were generated if [ ! -d "build/wiredpanda.app.dSYM" ]; then echo "Error: dSYM symbols not found" exit 1 fi # Validate macOS app bundle build quality echo "Validating macOS app bundle build quality..." # Check executable file properties EXECUTABLE_PATH="build/wiredpanda.app/Contents/MacOS/wiredpanda" if [ ! -f "$EXECUTABLE_PATH" ]; then echo "Error: Main executable missing from app bundle" exit 1 fi echo "✓ Executable file info:" ls -lh "$EXECUTABLE_PATH" echo "✓ Executable type: $(file "$EXECUTABLE_PATH")" # Verify app bundle structure echo "✓ App bundle structure validation:" if [ -f "build/wiredpanda.app/Contents/Info.plist" ]; then echo " ✓ Info.plist present" else echo " Warning: Info.plist missing" fi if [ -d "build/wiredpanda.app/Contents/Resources" ]; then echo " ✓ Resources directory present" else echo " Warning: Resources directory missing" fi # Check framework dependencies and linking echo "✓ Framework dependencies (first 10):" otool -L "$EXECUTABLE_PATH" | head -10 # Verify Qt frameworks are bundled (not external) EXTERNAL_QT=$(otool -L "$EXECUTABLE_PATH" | grep -E "/Users/.*/Qt|/usr/local.*/Qt" | wc -l) if [ "$EXTERNAL_QT" -eq 0 ]; then echo "✓ No external Qt dependencies found (properly bundled)" else echo "Warning: Found $EXTERNAL_QT external Qt dependencies:" otool -L "$EXECUTABLE_PATH" | grep -E "/Users/.*/Qt|/usr/local.*/Qt" fi # Check architecture ARCH_INFO=$(file "$EXECUTABLE_PATH" | grep -o "x86_64\|arm64\|universal") echo "✓ Architecture: $ARCH_INFO" # Verify code signing (basic check) CODESIGN_STATUS=$(codesign -dv "$EXECUTABLE_PATH" 2>&1 | grep -o "adhoc\|signed" || echo "unsigned") echo "✓ Code signing status: $CODESIGN_STATUS" echo "macOS build quality validation completed successfully" # Log Sentry configuration for debugging (breakpad backend) echo "Sentry configuration check:" echo " - libsentry.dylib: $(ls -la build/wiredpanda.app/Contents/Frameworks/libsentry.dylib)" echo " - Backend: breakpad (in-process, no separate handler required)" echo " - dylib dependencies: $(otool -L build/wiredpanda.app/Contents/MacOS/wiredpanda | grep sentry || echo 'No sentry dylib dependency found')" echo "macOS release artifacts validated successfully" - name: Upload macOS Debug Symbols to Sentry if: runner.os == 'macOS' env: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} run: | sentry-cli login --auth-token "$SENTRY_AUTH_TOKEN" sentry-cli releases new "wiredpanda@$VERSION" -p wiredpanda sentry-cli debug-files upload --include-sources -p wiredpanda build/ sentry-cli debug-files upload --include-sources -p wiredpanda $QT_ROOT_DIR sentry-cli releases set-commits --auto "wiredpanda@$VERSION" --log-level=debug - name: Publish macOS if: runner.os == 'macOS' uses: softprops/action-gh-release@v2 with: fail_on_unmatched_files: true files: 'build/*.dmg' wiRedPanda-4.3.0/.github/workflows/translate.yml000066400000000000000000000304541505731604100216610ustar00rootroot00000000000000name: Translation Management on: # Trigger on source code changes to update .ts files push: branches: [master, translations] paths: - 'app/**/*.cpp' - 'app/**/*.h' - 'app/**/*.ui' - 'CMakeLists.txt' # Trigger on translation file changes (typically from Weblate) pull_request: branches: [master] paths: - 'app/resources/translations/*.ts' types: [opened, synchronize, reopened] # Manual trigger workflow_dispatch: inputs: update_sources: description: 'Update source strings (lupdate)' type: boolean default: false compile_only: description: 'Only compile translations (lrelease)' type: boolean default: true jobs: update-sources: name: Update Translation Sources runs-on: ubuntu-latest if: (github.event_name == 'push' && github.ref == 'refs/heads/master') || (github.event_name == 'workflow_dispatch' && github.event.inputs.update_sources == 'true') steps: - name: Checkout code uses: actions/checkout@v4 with: token: ${{ secrets.GITHUB_TOKEN }} fetch-depth: 0 - name: Install Qt uses: jurplel/install-qt-action@v4 with: version: 6.9.0 cache: true aqtversion: ==3.2.* modules: qtmultimedia - name: Install GitHub CLI run: | sudo apt-get update sudo apt-get install -y gh - name: Run lupdate to extract strings run: | cmake -S . -B build_translations -DCMAKE_PREFIX_PATH=$QT_INSTALL_PATH cmake --build build_translations --target lupdate - name: Compile translations run: | cmake --build build_translations --target lrelease cmake --build build_translations --target generate_translations_qrc - name: Create PR for translation updates run: | git config user.name "Translation Bot" git config user.email "translation-bot@users.noreply.github.com" # Check if there are any changes if ! git diff --quiet; then # Create a new branch for the PR branch_name="translation-update-$(date +%Y%m%d-%H%M%S)" git checkout -b "$branch_name" git add app/resources/translations/ # Create commit message changed_files=$(git diff --cached --name-only | wc -l) echo "Translation update: Updated $changed_files files" git commit -m "Update translation sources and compiled files - Updated source strings with lupdate - Compiled .ts files to .qm files with lrelease - Regenerated translations.qrc 🤖 Automated translation update" git push origin "$branch_name" # Create PR using GitHub CLI gh pr create \ --title "🤖 Automated translation update" \ --body "## Summary Automated update of translation files triggered by source code changes. ## Changes - Updated source strings with \`lupdate\` - Compiled .ts files to .qm files with \`lrelease\` - Regenerated \`translations.qrc\` ## Files Changed $(git diff --name-only HEAD~1) 🤖 This PR was automatically created by the translation workflow." else echo "No translation updates needed" fi env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} compile-translations: name: Compile Translations runs-on: ubuntu-latest if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && github.event.inputs.compile_only == 'true') steps: - name: Checkout code uses: actions/checkout@v4 with: token: ${{ secrets.GITHUB_TOKEN }} fetch-depth: 0 # For PRs, checkout the PR branch from the correct repository repository: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name || github.repository }} ref: ${{ github.event_name == 'pull_request' && github.head_ref || github.ref }} - name: Install Qt uses: jurplel/install-qt-action@v4 with: version: 6.9.0 cache: true aqtversion: ==3.2.* modules: qtmultimedia - name: Install XML tools run: | sudo apt-get update sudo apt-get install -y libxml2-utils - name: Validate translation files run: | cd app/resources/translations echo "Validating .ts files..." for ts_file in wpanda_*.ts; do if [[ -f "$ts_file" ]]; then # Check if file is valid XML error_output=$(xmllint --noout "$ts_file" 2>&1) if [ $? -ne 0 ]; then echo "❌ Invalid XML in $ts_file" echo "Error details: $error_output" exit 1 fi echo "✅ $ts_file is valid" fi done - name: Compile translations run: | cmake -S . -B build_translations -DCMAKE_PREFIX_PATH=$QT_INSTALL_PATH cmake --build build_translations --target lrelease cmake --build build_translations --target generate_translations_qrc - name: Check translation completeness run: | cd app/resources/translations echo "Translation completeness report:" echo "==================================" for ts_file in wpanda_*.ts; do if [[ -f "$ts_file" ]]; then lang=$(basename "$ts_file" .ts | sed 's/wpanda_//') total=$(grep -c '' "$ts_file" 2>/dev/null | head -1) unfinished=$(grep -c 'type="unfinished"' "$ts_file" 2>/dev/null | head -1) # Ensure numeric values total=${total:-0} unfinished=${unfinished:-0} if [[ $total -gt 0 ]]; then finished=$((total - unfinished)) percentage=$((finished * 100 / total)) echo "$lang: $finished/$total ($percentage%)" else echo "$lang: No messages found" fi fi done - name: Commit compiled translations (for PRs) if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository run: | git config user.name "Translation Bot" git config user.email "translation-bot@users.noreply.github.com" # Check if there are any changes to compiled files if ! git diff --quiet app/resources/translations/; then git add app/resources/translations/*.qm git add app/resources/translations/translations.qrc git commit -m "Compile translation files - Compiled .ts files to .qm files with lrelease - Regenerated translations.qrc 🤖 Automated by translation workflow" git push origin HEAD:${{ github.head_ref }} echo "✅ Compiled translations committed to PR" else echo "ℹ️ No compiled translation updates needed" fi weblate-pr-handler: name: Handle Weblate PR runs-on: ubuntu-latest if: github.event_name == 'pull_request' && contains(github.event.pull_request.title, 'Weblate') || contains(github.event.pull_request.user.login, 'weblate') steps: - name: Checkout code uses: actions/checkout@v4 with: token: ${{ secrets.GITHUB_TOKEN }} fetch-depth: 0 # For cross-repository PRs (like from Weblate fork), use the PR head repository repository: ${{ github.event.pull_request.head.repo.full_name }} ref: ${{ github.head_ref }} - name: Install Qt uses: jurplel/install-qt-action@v4 with: version: 6.9.0 cache: true aqtversion: ==3.2.* modules: qtmultimedia - name: Install XML tools run: | sudo apt-get update sudo apt-get install -y libxml2-utils - name: Process Weblate changes run: | cd app/resources/translations # Remove backup files that Weblate might have created find . -name "*.ts.backup" -delete # Check for any issues with .ts files echo "Checking Weblate translation files..." for ts_file in wpanda_*.ts; do if [[ -f "$ts_file" ]]; then # Validate XML error_output=$(xmllint --noout "$ts_file" 2>&1) if [ $? -ne 0 ]; then echo "❌ XML validation failed for $ts_file" echo "Error details: $error_output" exit 1 fi # Check for incomplete translations that might need attention unfinished=$(grep -c 'type="unfinished"' "$ts_file" 2>/dev/null || echo "0") if [[ $unfinished -gt 0 ]]; then echo "ℹ️ $ts_file has $unfinished unfinished translations" fi fi done - name: Compile translations run: | cmake -S . -B build_translations -DCMAKE_PREFIX_PATH=$QT_INSTALL_PATH cmake --build build_translations --target lrelease cmake --build build_translations --target generate_translations_qrc - name: Commit compiled files run: | git config user.name "Weblate Integration" git config user.email "weblate-integration@users.noreply.github.com" # Remove any backup files find app/resources/translations -name "*.backup" -delete # Add all translation-related changes git add app/resources/translations/ # Check if there are changes to commit if ! git diff --cached --quiet; then # Get list of modified languages modified_langs=$(git diff --cached --name-only | grep '\.ts$' | sed 's/.*wpanda_//' | sed 's/\.ts$//' | sort | tr '\n' ' ') git commit -m "Process Weblate translation updates Languages updated: $modified_langs - Processed translation updates from Weblate - Compiled .ts files to .qm files - Regenerated translations.qrc - Cleaned up backup files 🌐 Weblate integration update" git push origin HEAD:${{ github.head_ref }} echo "✅ Weblate changes processed and compiled" else echo "ℹ️ No changes to commit from Weblate PR" fi - name: Add PR comment with translation status uses: actions/github-script@v7 with: script: | const fs = require('fs'); const path = require('path'); // Get translation completeness const translationsDir = 'app/resources/translations'; const tsFiles = fs.readdirSync(translationsDir).filter(f => f.startsWith('wpanda_') && f.endsWith('.ts')); let report = '## 🌐 Translation Status\n\n'; report += '| Language | Completion | Status |\n'; report += '|----------|------------|--------|\n'; for (const tsFile of tsFiles) { const lang = tsFile.replace('wpanda_', '').replace('.ts', ''); const content = fs.readFileSync(path.join(translationsDir, tsFile), 'utf8'); const totalMatches = content.match(//g); const finishedMatches = content.match(/type="finished"/g); const total = totalMatches ? totalMatches.length : 0; const finished = finishedMatches ? finishedMatches.length : 0; const percentage = total > 0 ? Math.round((finished / total) * 100) : 0; let status = '🔴 Low'; if (percentage >= 90) status = '🟢 Excellent'; else if (percentage >= 70) status = '🟡 Good'; else if (percentage >= 50) status = '🟠 Fair'; report += `| ${lang} | ${percentage}% (${finished}/${total}) | ${status} |\n`; } report += '\n✅ Translation files have been compiled and are ready for merge.'; github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: report }); wiRedPanda-4.3.0/.github/workflows/wasm.yml000066400000000000000000000056101505731604100206270ustar00rootroot00000000000000# Copyright 2015 - 2025, GIBIS-Unifesp and the wiRedPanda contributors # SPDX-License-Identifier: GPL-3.0-or-later name: Build WebAssembly on: push: branches: - wasm jobs: build-wasm: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 - name: Setup Qt for WASM uses: jurplel/install-qt-action@v4 with: version: 6.9.0 host: all_os target: wasm arch: wasm_multithread modules: qtmultimedia qtimageformats extra: --autodesktop cache: true - name: Setup emscripten run: | git clone https://github.com/emscripten-core/emsdk cd emsdk ./emsdk install 3.1.70 ./emsdk activate 3.1.70 - name: Install Ninja run: sudo apt-get update && sudo apt-get install -y ninja-build - name: Setup ccache uses: hendrikmuhs/ccache-action@v1.2 with: key: wasm-ubuntu-6.9.0 - name: Build WASM run: | source ./emsdk/emsdk_env.sh mkdir build cd build qt-cmake .. -DCMAKE_BUILD_TYPE=Release -G Ninja ninja wiredpanda cp wiredpanda.html index.html cp ../app/resources/wasm/coi-serviceworker.min.js . cp ../app/resources/wasm/favicon.ico . sed -i '/