Merge branch 'master' into tooomm-qt5

This commit is contained in:
tooomm 2026-08-27 06:33:34 +02:00
commit 3bc08ef94c
357 changed files with 23069 additions and 2916 deletions

95
.github/workflows/codeql.yml vendored Normal file
View file

@ -0,0 +1,95 @@
# GitHub Docs on Code Scanning:
# https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning
# https://docs.github.com/en/code-security/how-tos/find-and-fix-code-vulnerabilities/manage-your-configuration
# https://docs.github.com/en/code-security/reference/code-scanning/workflow-configuration-options
#
# CodeQL Docs:
# https://codeql.github.com/docs/
name: CodeQL
permissions:
contents: read
security-events: write # needed to post results
on:
push:
branches:
- master
pull_request:
# Cancel earlier, unfinished runs of this workflow on the same branch
concurrency:
group: "${{ github.workflow }} @ ${{ github.ref_name }}"
cancel-in-progress: true
jobs:
analyze:
name: Analyze (${{ matrix.language }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
# https://codeql.github.com/docs/codeql-overview/supported-languages-and-frameworks/
- language: cpp
build-mode: manual
- language: actions
build-mode: none
steps:
- name: "Checkout repository"
uses: actions/checkout@v6
- name: "Initialize CodeQL"
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
# https://docs.github.com/en/code-security/reference/code-scanning/codeql/codeql-queries/c-cpp-built-in-queries
# https://docs.github.com/en/code-security/reference/code-scanning/codeql/codeql-queries/actions-built-in-queries
queries: security-extended
dependency-caching: true
- name: "[C++] Install dependencies"
if: matrix.language == 'cpp' && matrix.build-mode == 'manual'
shell: bash
env:
DEBIAN_FRONTEND: noninteractive
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
cmake \
g++ \
libgl-dev \
liblzma-dev \
libmariadb-dev-compat \
libprotobuf-dev \
ninja-build \
protobuf-compiler \
qt6-declarative-dev \
qt6-multimedia-dev \
qt6-shadertools-dev \
qt6-svg-dev \
qt6-tools-dev \
qt6-tools-dev-tools \
qt6-websockets-dev
# Minimize dependency install
# Add ccache usage for faster compilation, (install ccache dep, actions/cache step + append DUSE_CCACHE=1 in cmake config, CCACHE env values)
- name: "[C++] Configure CMake"
if: matrix.language == 'cpp' && matrix.build-mode == 'manual'
shell: bash
run: cmake -S . -B build -G Ninja -DWITH_SERVER=1 -DCMAKE_BUILD_TYPE=Release
- name: "[C++] Build application"
if: matrix.language == 'cpp' && matrix.build-mode == 'manual'
shell: bash
run: cmake --build build
- name: "Perform CodeQL Analysis"
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{ matrix.language }}"

View file

@ -3,7 +3,7 @@ name: Build Desktop
permissions:
actions: write # needed to delete entries in GHA cache (update ccache)
attestations: write # needed to persist the attestation.
contents: write
contents: write # needed for e.g. vcpkg dependency graph updates
id-token: write # needed for signing certificate in attestation
on:
@ -34,7 +34,7 @@ on:
- 'vcpkg.json'
- 'vcpkg' # needed to match submodule bumps (gitlink)
# Cancel earlier, unfinished runs of this workflow on the same branch (unless on release)
# Cancel earlier, unfinished runs of this workflow on the same branch (unless on tag --> release)
concurrency:
group: "${{ github.workflow }} @ ${{ github.ref_name }}"
cancel-in-progress: ${{ github.ref_type != 'tag' }}
@ -42,7 +42,7 @@ concurrency:
jobs:
configure:
name: Configure
runs-on: ubuntu-slim
runs-on: ubuntu-slim # https://github.com/actions/runner-images/blob/main/images/ubuntu-slim/ubuntu-slim-Readme.md
outputs:
tag: ${{ steps.configure.outputs.tag }}
sha: ${{ steps.configure.outputs.sha }}
@ -146,7 +146,7 @@ jobs:
name: ${{ matrix.distro }} ${{ matrix.version }}
needs: configure
runs-on: ubuntu-latest
runs-on: ubuntu-latest # https://github.com/actions/runner-images
continue-on-error: ${{ matrix.allow-failure == 'yes' }}
timeout-minutes: 70
env:
@ -161,14 +161,11 @@ jobs:
uses: actions/checkout@v7
- name: "Restore compiler cache (ccache)"
id: ccache_restore
id: restore_ccache
uses: actions/cache/restore@v6
env:
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
with:
key: ccache-${{ matrix.distro }}${{ matrix.version }}-${{ env.BRANCH_NAME }}
key: ccache-${{ matrix.distro }}${{ matrix.version }}
path: ${{ env.CACHE }}
restore-keys: ccache-${{ matrix.distro }}${{ matrix.version }}-
- name: "Build ${{ matrix.distro }} ${{ matrix.version }} Docker image"
shell: bash
@ -203,10 +200,10 @@ jobs:
# Delete used cache to emulate a ccache update. See https://github.com/actions/cache/issues/342
- name: "Delete remote compiler cache (ccache)"
if: github.ref == 'refs/heads/master' && steps.ccache_restore.outputs.cache-hit
if: github.ref == 'refs/heads/master' && steps.restore_ccache.outputs.cache-hit
continue-on-error: true
env:
CACHE_PRIMARY_KEY: ${{ steps.ccache_restore.outputs.cache-primary-key }}
CACHE_PRIMARY_KEY: ${{ steps.restore_ccache.outputs.cache-primary-key }}
GH_TOKEN: ${{ github.token }}
run: |
if gh cache delete --repo "$GITHUB_REPOSITORY" "$CACHE_PRIMARY_KEY"; then
@ -217,7 +214,7 @@ jobs:
if: github.ref == 'refs/heads/master'
uses: actions/cache/save@v6
with:
key: ${{ steps.ccache_restore.outputs.cache-primary-key }}
key: ${{ steps.restore_ccache.outputs.cache-primary-key }}
path: ${{ env.CACHE }}
- name: "Upload artifact"
@ -262,74 +259,77 @@ jobs:
matrix:
include:
- os: macOS
target: 13
runner: macos-15-intel
target: 13 # EOL 2025-09-15
runner: macos-15-intel # https://github.com/actions/runner-images/blob/main/images/macos/macos-15-Readme.md
# macos-26-intel is very slow and fails in CPack during DMG config if not increasing Finder timeout
ccache_eviction_age: 7d
cmake_generator: Ninja
make_package: 1
override_target: 13
package_suffix: "-macOS13_Intel"
qt_version: 6.11.0
qt_modules: qtimageformats qtmultimedia qtwebsockets
qt_version: 6.11.1
qt_modules: qtimageformats qtmultimedia qtwebsockets qtshadertools
soc: Intel
type: Release
use_ccache: 1
xcode: "16.4"
xcode: "26.3"
- os: macOS
target: 14
runner: macos-14
target: 14 # EOL 2026-??
runner: macos-26 # https://github.com/actions/runner-images/blob/main/images/macos/macos-26-arm64-Readme.md
ccache_eviction_age: 7d
cmake_generator: Ninja
make_package: 1
override_target: 14
package_suffix: "-macOS14"
qt_version: 6.11.0
qt_modules: qtimageformats qtmultimedia qtwebsockets
qt_version: 6.11.1
qt_modules: qtimageformats qtmultimedia qtwebsockets qtshadertools
soc: Apple
type: Release
use_ccache: 1
xcode: "15.4"
xcode: "26.6"
- os: macOS
target: 15
runner: macos-15
runner: macos-26 # https://github.com/actions/runner-images/blob/main/images/macos/macos-26-arm64-Readme.md
ccache_eviction_age: 7d
cmake_generator: Ninja
make_package: 1
override_target: 15
package_suffix: "-macOS15"
qt_version: 6.11.0
qt_modules: qtimageformats qtmultimedia qtwebsockets
qt_version: 6.11.1
qt_modules: qtimageformats qtmultimedia qtwebsockets qtshadertools
soc: Apple
type: Release
use_ccache: 1
xcode: "16.4"
xcode: "26.6"
- os: macOS
target: 15
runner: macos-15
target: 26
runner: macos-26 # https://github.com/actions/runner-images/blob/main/images/macos/macos-26-arm64-Readme.md
ccache_eviction_age: 7d
cmake_generator: Ninja
qt_version: 6.11.0
qt_modules: qtimageformats qtmultimedia qtwebsockets
qt_version: 6.11.1
qt_modules: qtimageformats qtmultimedia qtwebsockets qtshadertools
soc: Apple
type: Debug
use_ccache: 1
xcode: "16.4"
xcode: "26.6"
- os: Windows
target: 10
runner: windows-2025
runner: windows-2025 # https://github.com/actions/runner-images/blob/main/images/windows/Windows2025-VS2026-Readme.md
cmake_generator: "Visual Studio 18 2026"
cmake_generator_platform: x64
make_package: 1
package_suffix: "-Win10"
qt_version: 6.11.0
qt_modules: qtimageformats qtmultimedia qtwebsockets
qt_version: 6.11.1
qt_modules: qtimageformats qtmultimedia qtwebsockets qtshadertools
type: Release
name: ${{ matrix.os }} ${{ matrix.target }}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }}
@ -348,7 +348,6 @@ jobs:
- name: "[Windows] Add msbuild to PATH"
if: matrix.os == 'Windows'
id: add-msbuild
uses: microsoft/setup-msbuild@v3
with:
msbuild-architecture: x64
@ -359,14 +358,11 @@ jobs:
- name: "[macOS] Restore compiler cache (ccache)"
if: matrix.os == 'macOS' && matrix.use_ccache == 1
id: ccache_restore
id: restore_ccache
uses: actions/cache/restore@v6
env:
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
with:
key: ccache-${{ matrix.runner }}-${{ matrix.soc }}-${{ matrix.type }}-${{ env.BRANCH_NAME }}
key: ccache-${{ matrix.runner }}_${{ matrix.override_target }}-Xcode${{ matrix.xcode }}
path: ${{ env.CCACHE_DIR }}
restore-keys: ccache-${{ matrix.runner }}-${{ matrix.soc }}-${{ matrix.type }}-
- name: "Install aqtinstall"
run: pipx install aqtinstall
@ -384,7 +380,7 @@ jobs:
id: restore_qt
uses: actions/cache/restore@v6
with:
key: thin-qt-macos-${{ matrix.soc }}-${{ steps.resolve_qt_version.outputs.version }}
key: Qt-${{ steps.resolve_qt_version.outputs.version }}-macOS-${{ matrix.soc }}-${{ matrix.qt_modules }}-thin
path: ${{ github.workspace }}/Qt
# Using jurplel/install-qt-action to install Qt without using brew
@ -406,7 +402,7 @@ jobs:
if: matrix.os == 'macOS' && steps.restore_qt.outputs.cache-hit != 'true'
uses: actions/cache/save@v6
with:
key: thin-qt-macos-${{ matrix.soc }}-${{ steps.resolve_qt_version.outputs.version }}
key: ${{ steps.restore_qt.outputs.cache-primary-key }}
path: ${{ github.workspace }}/Qt
- name: "[Windows] Install Qt ${{ matrix.qt_version }}"
@ -416,6 +412,7 @@ jobs:
# Qt 6.11.0 only works with aqtinstall directly from git until aqtinstall 3.4 is released
aqtsource: git+https://github.com/miurahr/aqtinstall.git
cache: true
cache-key-prefix: Qt
modules: ${{ matrix.qt_modules }}
version: ${{ steps.resolve_qt_version.outputs.version }}
@ -440,6 +437,7 @@ jobs:
CMAKE_GENERATOR: ${{ matrix.cmake_generator }}
CMAKE_GENERATOR_PLATFORM: ${{ matrix.cmake_generator_platform }}
DEVELOPER_DIR: '/Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer'
GITHUB_TOKEN: ${{ github.token }} # needed for vcpkg dependency graph updates, see VCPKG_FEATURE_FLAGS
MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }}
MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }}
@ -450,25 +448,26 @@ jobs:
USE_CCACHE: ${{ matrix.use_ccache }}
VCPKG_BINARY_SOURCES: 'clear;files,${{ steps.vcpkg-cache.outputs.path }},readwrite'
VCPKG_DISABLE_METRICS: 1
VCPKG_FEATURE_FLAGS: dependencygraph
run: .ci/compile.sh --server --test --vcpkg
# Delete used cache to emulate a ccache update. See https://github.com/actions/cache/issues/342
- name: "[macOS] Delete remote compiler cache (ccache)"
if: matrix.os == 'macOS' && matrix.use_ccache == 1 && github.ref == 'refs/heads/master' && steps.ccache_restore.outputs.cache-hit
if: matrix.os == 'macOS' && matrix.use_ccache == 1 && github.ref == 'refs/heads/master' && steps.restore_ccache.outputs.cache-hit
continue-on-error: true
env:
CACHE_PRIMARY_KEY: ${{ steps.ccache_restore.outputs.cache-primary-key }}
CACHE_PRIMARY_KEY: ${{ steps.restore_ccache.outputs.cache-primary-key }}
GH_TOKEN: ${{ github.token }}
run: |
if gh cache delete --repo "$GITHUB_REPOSITORY" "$CACHE_PRIMARY_KEY"; then
echo "Cache deleted successfully"
fi
- name: "[macOS] Save updated compiler cache (ccache)"
- name: "[macOS] Cache updated compiler cache (ccache)"
if: matrix.os == 'macOS' && matrix.use_ccache == 1 && github.ref == 'refs/heads/master'
uses: actions/cache/save@v6
with:
key: ${{ steps.ccache_restore.outputs.cache-primary-key }}
key: ${{ steps.restore_ccache.outputs.cache-primary-key }}
path: ${{ env.CCACHE_DIR }}
- name: "[macOS] Sign app bundle"

View file

@ -1,5 +1,8 @@
name: Code Style (C++)
permissions:
contents: read
on:
# Push trigger not needed for linting, we do not allow direct pushes to master
pull_request:

View file

@ -1,8 +1,8 @@
name: Build Docker Image
name: Build Docker
permissions:
contents: read
packages: write
contents: read # needed to checkout repo
packages: write # needed for interacting with GHCR
on:
push:
@ -13,7 +13,10 @@ on:
- master
paths:
- '.github/workflows/docker-release.yml'
- '.dockerignore'
- 'Dockerfile'
- 'docker-compose.yml'
- 'docker-compose.yml.windows'
release:
types:
- released # publishing of stable releases
@ -23,36 +26,38 @@ concurrency:
group: "${{ github.workflow }} @ ${{ github.ref_name }}"
cancel-in-progress: ${{ github.event_name != 'release' }}
env:
GHCR_IMAGE: ghcr.io/cockatrice/servatrice
OCI_DESCRIPTION: Server for Cockatrice, a cross-platform virtual tabletop for multiplayer card games
OCI_TITLE: Servatrice
OCI_URL: https://cockatrice.github.io/
jobs:
docker:
name: amd64 & arm64
if: ${{ github.repository_owner == 'Cockatrice' }}
runs-on: ubuntu-latest
# Create one platform-specific image and publish its OCI image manifest per matrix job
build:
name: "Servatrice (${{ matrix.label }})"
if: github.repository_owner == 'Cockatrice'
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- label: x86
platform: linux/amd64
runner: ubuntu-latest # https://github.com/actions/runner-images
- label: arm
platform: linux/arm64
runner: ubuntu-24.04-arm # https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Arm64-Readme.md, replace with "ubuntu-latest-arm" once available
env:
CACHE_SCOPE: servatrice-${{ matrix.label }}
steps:
- name: "Checkout"
uses: actions/checkout@v7
- name: "Docker metadata"
id: metadata
uses: docker/metadata-action@v6
env:
DOCKER_METADATA_ANNOTATIONS_LEVELS: index # needed for GHCR
with:
annotations: |
org.opencontainers.image.title=Servatrice
org.opencontainers.image.url=https://cockatrice.github.io/
org.opencontainers.image.description=Server for Cockatrice, a cross-platform virtual tabletop for multiplayer card games
images: |
ghcr.io/cockatrice/servatrice
labels: |
org.opencontainers.image.title=Servatrice
org.opencontainers.image.url=https://cockatrice.github.io/
org.opencontainers.image.description=Server for Cockatrice, a cross-platform virtual tabletop for multiplayer card games
- name: "Set up QEMU"
uses: docker/setup-qemu-action@v4
- name: "Set up Docker buildx"
uses: docker/setup-buildx-action@v4
@ -61,18 +66,117 @@ jobs:
id: login
uses: docker/login-action@v4
with:
password: ${{ github.token }}
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}
- name: "Build and push Docker image"
# Don't push for non-release triggers
- name: "Build image"
if: steps.login.outcome != 'success'
uses: docker/build-push-action@v7
with:
annotations: ${{ steps.metadata.outputs.annotations }}
cache-from: type=gha,scope=servatrice
cache-to: type=gha,mode=max,scope=servatrice
cache-from: type=gha,scope=${{ env.CACHE_SCOPE }}
cache-to: type=gha,mode=max,scope=${{ env.CACHE_SCOPE }}
context: .
labels: ${{ steps.metadata.outputs.labels }}
platforms: linux/amd64,linux/arm64
push: ${{ steps.login.outcome == 'success' }}
tags: ${{ steps.metadata.outputs.tags }}
platforms: ${{ matrix.platform }}
push: false
# Add OCI labels and push single-platform image by digest (without tags)
- name: "Build image and push by digest"
if: steps.login.outcome == 'success'
id: build
uses: docker/build-push-action@v7
with:
cache-from: type=gha,scope=${{ env.CACHE_SCOPE }}
cache-to: type=gha,mode=max,scope=${{ env.CACHE_SCOPE }}
context: .
labels: |
org.opencontainers.image.description=${{ env.OCI_DESCRIPTION }}
org.opencontainers.image.title=${{ env.OCI_TITLE }}
org.opencontainers.image.url=${{ env.OCI_URL }}
outputs: type=image,name=${{ env.GHCR_IMAGE }},name-canonical=true,push=true,push-by-digest=true
platforms: ${{ matrix.platform }}
provenance: mode=max # Do not pass secrets as build arguments with this option
sbom: true
- name: "Export digest"
if: steps.login.outcome == 'success'
env:
DIGEST: ${{ steps.build.outputs.digest }}
run: |
mkdir -p "$RUNNER_TEMP/digests"
touch "$RUNNER_TEMP/digests/${DIGEST#sha256:}"
- name: "Upload digest"
if: steps.login.outcome == 'success'
uses: actions/upload-artifact@v7
with:
archive: false
if-no-files-found: error
name: digest-${{ matrix.label }}
path: ${{ runner.temp }}/digests/*
retention-days: 1
# Create an OCI image index from the platform-specific image manifests
index:
name: "Publish multi-platform Servatrice image"
if: github.repository_owner == 'Cockatrice' && github.event_name == 'release' && github.event.release.prerelease == false
needs: build
runs-on: ubuntu-slim # https://github.com/actions/runner-images/blob/main/images/ubuntu-slim/ubuntu-slim-Readme.md
steps:
- name: "Download digests"
uses: actions/download-artifact@v7
with:
path: ${{ runner.temp }}/digests
pattern: digest-*
merge-multiple: true
- name: "Login to GitHub Container Registry (GHCR)"
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}
- name: "Docker metadata"
id: metadata
uses: docker/metadata-action@v6
with:
images: ${{ env.GHCR_IMAGE }}
flavor: |
latest=auto
tags: |
type=ref,event=tag # if semver, also: type=semver,pattern={{version}} / {{major}}.{{minor}}
# Add OCI annotations to image index and publish tags
- name: "Create image index"
env:
DOCKER_TAGS: ${{ steps.metadata.outputs.tags }}
working-directory: ${{ runner.temp }}/digests
run: |
TAG_ARGS=()
while IFS= read -r tag; do
TAG_ARGS+=(--tag "$tag")
done <<< "$DOCKER_TAGS"
DIGEST_ARGS=()
for digest in *; do
DIGEST_ARGS+=("$GHCR_IMAGE@sha256:$digest")
done
docker buildx imagetools create \
--prefer-index=true \
--annotation "index:org.opencontainers.image.description=$OCI_DESCRIPTION" \
--annotation "index:org.opencontainers.image.title=$OCI_TITLE" \
--annotation "index:org.opencontainers.image.url=$OCI_URL" \
"${TAG_ARGS[@]}" \
"${DIGEST_ARGS[@]}"
- name: "Inspect images"
env:
GITHUB_TAG: ${{ github.ref_name }}
run: |
docker buildx imagetools inspect "$GHCR_IMAGE:latest"
docker buildx imagetools inspect "$GHCR_IMAGE:$GITHUB_TAG"

View file

@ -1,5 +1,8 @@
name: Generate Docs
permissions:
contents: read # write permission to the destination repo come from 'deploy_key'
on:
pull_request:
paths:
@ -11,6 +14,11 @@ on:
- published # publishing of stable releases and pre-releases
workflow_dispatch:
# Cancel earlier, unfinished runs of this workflow on the same branch (unless on release)
concurrency:
group: "${{ github.workflow }} @ ${{ github.ref_name }}"
cancel-in-progress: ${{ github.event_name != 'release' }}
env:
COCKATRICE_REF: ${{ github.ref_name }} # tag name if the commit is tagged, otherwise branch name

View file

@ -1,5 +1,9 @@
name: Update Translations
permissions:
contents: read
pull-requests: write
on:
pull_request:
paths:

View file

@ -1,5 +1,9 @@
name: Update Translation Source
permissions:
contents: read
pull-requests: write
on:
pull_request:
paths: