pax_global_header 0000666 0000000 0000000 00000000064 15057316041 0014514 g ustar 00root root 0000000 0000000 52 comment=3139ca940f4035e1a5d0999f43ba9ab25d5ab9ef
wiRedPanda-4.3.0/ 0000775 0000000 0000000 00000000000 15057316041 0013536 5 ustar 00root root 0000000 0000000 wiRedPanda-4.3.0/.devcontainer/ 0000775 0000000 0000000 00000000000 15057316041 0016275 5 ustar 00root root 0000000 0000000 wiRedPanda-4.3.0/.devcontainer/.dockerignore 0000664 0000000 0000000 00000000311 15057316041 0020744 0 ustar 00root root 0000000 0000000 # 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/Dockerfile 0000664 0000000 0000000 00000004616 15057316041 0020276 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000012175 15057316041 0017562 0 ustar 00root root 0000000 0000000 # 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.json 0000664 0000000 0000000 00000005513 15057316041 0021655 0 ustar 00root root 0000000 0000000 {
"$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/.gitattributes 0000664 0000000 0000000 00000000112 15057316041 0016423 0 ustar 00root root 0000000 0000000 # Auto detect text files and perform LF normalization
* text=auto eol=lf
wiRedPanda-4.3.0/.github/ 0000775 0000000 0000000 00000000000 15057316041 0015076 5 ustar 00root root 0000000 0000000 wiRedPanda-4.3.0/.github/workflows/ 0000775 0000000 0000000 00000000000 15057316041 0017133 5 ustar 00root root 0000000 0000000 wiRedPanda-4.3.0/.github/workflows/build.yml 0000664 0000000 0000000 00000004650 15057316041 0020762 0 ustar 00root root 0000000 0000000 # 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.yml 0000664 0000000 0000000 00000002072 15057316041 0021126 0 ustar 00root root 0000000 0000000 # 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.yml 0000664 0000000 0000000 00000002027 15057316041 0021452 0 ustar 00root root 0000000 0000000 # 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.yml 0000664 0000000 0000000 00000066275 15057316041 0021172 0 ustar 00root root 0000000 0000000 # 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.yml 0000664 0000000 0000000 00000030454 15057316041 0021661 0 ustar 00root root 0000000 0000000 name: 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.yml 0000664 0000000 0000000 00000005610 15057316041 0020627 0 ustar 00root root 0000000 0000000 # 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 '/