Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
7e3c718
Make macOS system OpenAL lookup strict (#94)
themuffinator Aug 13, 2026
f3bde18
Probe loose Frameworks for MoltenVK (#95)
themuffinator Aug 13, 2026
a8fc1b1
Publish generated loadscreens atomically (#102)
themuffinator Aug 13, 2026
b93c41f
Document resolved issue paths (#73 #94 #95 #102)
themuffinator Aug 13, 2026
1e3dfed
Isolate concurrent loadscreen staging (#102)
themuffinator Aug 13, 2026
698b1ff
Complete retail levelshot coverage (#11)
themuffinator Aug 13, 2026
95f1bd7
Warn when Quake 4 dialogue media is absent
themuffinator Aug 13, 2026
a6a6ddc
Correct high-refresh scope documentation (themuffinator/openQ4#99)
themuffinator Aug 13, 2026
7fa3f47
Track current macOS signoff issue in policy guard
themuffinator Aug 13, 2026
9b6b22e
Allow live macOS issue in release policy
themuffinator Aug 13, 2026
3107f8f
Harden issue-resolution diagnostics and staging
themuffinator Aug 13, 2026
03c2034
Use secure loadscreen staging nonces (#102)
themuffinator Aug 13, 2026
8cfa4cc
Align issue-resolution smoke contracts (#94 #102)
themuffinator Aug 13, 2026
19dd219
Stage MoltenVK before macOS provenance (#95)
themuffinator Aug 13, 2026
b7d421c
Stage MoltenVK in universal2 candidates (#95)
themuffinator Aug 13, 2026
eeba86b
Harden release payload validation (#95)
themuffinator Aug 13, 2026
0ab0e97
Normalize host-signed MoltenVK inputs (#95)
themuffinator Aug 13, 2026
ef2196d
Sign fused universal2 binaries (#95)
themuffinator Aug 13, 2026
6db32cc
Pass universal package suffix safely (#95)
themuffinator Aug 13, 2026
be2e95d
Install universal package docs dependency (#95)
themuffinator Aug 13, 2026
6f743c7
Launch universal candidate from absolute path (#95)
themuffinator Aug 13, 2026
5153ba4
Validate universal candidate launch evidence (#95)
themuffinator Aug 13, 2026
e84b89a
Capture universal candidate launch output (#95)
themuffinator Aug 13, 2026
7efd92b
Exclude generated bytecode from GameLib staging (#95)
themuffinator Aug 13, 2026
02cbe9b
Keep BSE sanitizer builds linkable
themuffinator Aug 13, 2026
be7ce02
Close MD5R export files through the engine
themuffinator Aug 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
46 changes: 45 additions & 1 deletion .github/workflows/commit-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ jobs:
tools/tests/idstr_input_safety.py \
tools/tests/lexer_peek_contract.py \
tools/tests/key_bind_presentation.py \
tools/tests/levelshot_inventory.py \
tools/tests/linux_arm64_cross_compile.py \
tools/tests/linux_arm64_ci_coverage.py \
tools/tests/linux_arm64_release_evidence.py \
Expand Down Expand Up @@ -215,6 +216,7 @@ jobs:
python tools/tests/idstr_input_safety.py
python tools/tests/lexer_peek_contract.py
python tools/tests/key_bind_presentation.py
python tools/tests/levelshot_inventory.py
python tools/tests/linux_arm64_cross_compile.py
python tools/tests/linux_arm64_ci_coverage.py
python tools/tests/linux_arm64_release_evidence.py
Expand Down Expand Up @@ -349,6 +351,15 @@ jobs:
python -m pip install --upgrade pip
python -m pip install meson ninja

- name: Prepare OpenAL Soft (Windows)
shell: pwsh
run: |
$ErrorActionPreference = "Stop"
$outputRoot = Join-Path $env:GITHUB_WORKSPACE ".tmp/openal-soft-x64"
$env:OPENQ4_VS_TARGET_ARCH = "x64"
powershell -ExecutionPolicy Bypass -File tools/build/prepare_windows_openal.ps1 -Architecture "x64" -OutputRoot $outputRoot
"OPENQ4_OPENAL_ROOT=$outputRoot" >> $env:GITHUB_ENV

- name: Run selected validation profile
shell: pwsh
run: |
Expand Down Expand Up @@ -1021,13 +1032,28 @@ jobs:
--extra-setup-arg=-Dmacos_graphics_bridge=${{ matrix.macos_graphics_bridge }} \
--extra-setup-arg=-Dmacos_openal_provider=${{ matrix.macos_openal_provider }}

- name: Normalize ARM64 thin payload
shell: bash
run: |
set -euo pipefail
python tools/build/assemble_macos_universal2.py prepare \
--install-root .install \
--arch arm64

- name: Run macOS dedicated server smoke
shell: bash
run: |
set -euo pipefail
python tools/tests/macos_dedicated_server_smoke.py \
--output-root .tmp/macos-dedicated-smoke/${{ matrix.artifact_suffix }}

- name: Stage pinned MoltenVK for ARM64 thin payload
shell: bash
run: |
set -euo pipefail
bash tools/build/prepare_macos_moltenvk.sh --output-dir .install
bash tools/build/prepare_macos_moltenvk.sh --verify-only --output-dir .install

- name: Record macOS ARM64 thin-build provenance
shell: bash
run: |
Expand Down Expand Up @@ -1135,6 +1161,14 @@ jobs:
--extra-setup-arg=-Dmacos_graphics_bridge=${{ matrix.macos_graphics_bridge }} \
--extra-setup-arg=-Dmacos_openal_provider=${{ matrix.macos_openal_provider }}

- name: Normalize Intel thin payload
shell: bash
run: |
set -euo pipefail
python tools/build/assemble_macos_universal2.py prepare \
--install-root .install \
--arch x64

- name: Run macOS dedicated server smoke
shell: bash
run: |
Expand All @@ -1143,6 +1177,13 @@ jobs:
--arch x64 \
--output-root .tmp/macos-dedicated-smoke/x64-${{ matrix.artifact_suffix }}

- name: Stage pinned MoltenVK for Intel thin payload
shell: bash
run: |
set -euo pipefail
bash tools/build/prepare_macos_moltenvk.sh --output-dir .install
bash tools/build/prepare_macos_moltenvk.sh --verify-only --output-dir .install

- name: Record macOS Intel thin-build provenance
shell: bash
run: |
Expand Down Expand Up @@ -1214,6 +1255,9 @@ jobs:
with:
python-version: "3.x"

- name: Install release documentation dependency
run: python -m pip install markdown

- name: Download macOS ARM64 thin payload
uses: actions/download-artifact@v5
with:
Expand Down Expand Up @@ -1280,7 +1324,7 @@ jobs:
--install-dir "${corridor_root}/universal2" \
--output-dir "${corridor_root}/package-output" \
--archive-format tar.xz \
--package-suffix "-${{ matrix.artifact_suffix }}" \
--package-suffix=-${{ matrix.artifact_suffix }} \
--macos-signing-mode ad-hoc

- name: Publish universal2 assembly evidence
Expand Down
70 changes: 61 additions & 9 deletions .github/workflows/macos-universal2-candidate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,14 @@ jobs:
--expected-project-commit "${{ needs.metadata.outputs.source_sha }}" \
--expected-gamelibs-commit "${{ needs.metadata.outputs.game_sha }}"

- name: Normalize thin universal2 payload
shell: bash
run: |
set -euo pipefail
python tools/build/assemble_macos_universal2.py prepare \
--install-root .install \
--arch "${{ matrix.binary_arch }}"

- name: Run thin dedicated-server smoke
shell: bash
run: |
Expand All @@ -261,6 +269,13 @@ jobs:
--arch "${{ matrix.binary_arch }}" \
--output-root ".tmp/macos-universal2-candidate/${{ matrix.bridge }}/${{ matrix.binary_arch }}/dedicated-smoke"

- name: Stage pinned MoltenVK for thin payload
shell: bash
run: |
set -euo pipefail
bash tools/build/prepare_macos_moltenvk.sh --output-dir .install
bash tools/build/prepare_macos_moltenvk.sh --verify-only --output-dir .install

- name: Record thin universal2 provenance
shell: bash
run: |
Expand Down Expand Up @@ -316,6 +331,9 @@ jobs:
with:
python-version: "3.x"

- name: Install release documentation dependency
run: python -m pip install markdown

- name: Download ARM64 thin payload
uses: actions/download-artifact@v5
with:
Expand Down Expand Up @@ -434,7 +452,7 @@ jobs:
--arch universal2
--version "${{ needs.metadata.outputs.version }}"
--version-tag "${{ needs.metadata.outputs.version_tag }}"
--package-suffix "${package_suffix}"
"--package-suffix=${package_suffix}"
--archive-format "${archive_format}"
--source-root "${GITHUB_WORKSPACE}"
--install-dir "${corridor_root}/universal2"
Expand All @@ -448,7 +466,7 @@ jobs:
--arch universal2
--version "${{ needs.metadata.outputs.version }}"
--version-tag "${{ needs.metadata.outputs.version_tag }}"
--package-suffix "${package_suffix}"
"--package-suffix=${package_suffix}"
--archive-format "${archive_format}"
--source-root "${GITHUB_WORKSPACE}"
--install-dir "${corridor_root}/universal2"
Expand Down Expand Up @@ -543,13 +561,15 @@ jobs:
shell: bash
run: |
set -euo pipefail
package_dir="${{ steps.package.outputs.package_dir }}"
package_dir="${GITHUB_WORKSPACE}/${{ steps.package.outputs.package_dir }}"
app_exec="${package_dir}/openQ4.app/Contents/MacOS/openQ4"
smoke_root="${RUNNER_TEMP}/openq4-universal2-candidate-${{ matrix.bridge }}"
smoke_cwd="${smoke_root}/finder-style-cwd"
smoke_save="${smoke_root}/save"
smoke_log="${smoke_save}/baseoq4/logs/macos_universal2_candidate_app_smoke.log"
smoke_console="${smoke_root}/console.log"
smoke_timeout_marker="${smoke_root}/timed-out"
smoke_exit_status="${smoke_root}/app-exit-status"
rm -rf "${smoke_root}"
mkdir -p "${smoke_cwd}" "${smoke_save}"
(
Expand All @@ -564,7 +584,7 @@ jobs:
+set r_fullscreen 0 \
+set r_ignoreGLErrors 0 \
+rendererDefaultSafetySelfTest \
+quit &
+quit > "${smoke_console}" 2>&1 &
app_pid=$!
(
sleep 90
Expand All @@ -586,12 +606,44 @@ jobs:
if [ -f "${smoke_timeout_marker}" ]; then
exit 124
fi
exit "${app_status}"
printf '%s\n' "${app_status}" > "${smoke_exit_status}"
)
grep -F "RendererDefaultSafety self-test passed" "${smoke_log}" >/dev/null
grep -F "Filesystem paths:" "${smoke_log}" >/dev/null
grep -F "fs_cdpath='${package_dir}/openQ4.app/Contents/Resources'" "${smoke_log}" >/dev/null
grep -F "game-sp_universal2.dylib" "${smoke_log}" >/dev/null
if [ ! -f "${smoke_log}" ]; then
echo "Universal2 app smoke log was not created: ${smoke_log}"
exit 1
fi
if [ ! -f "${smoke_exit_status}" ]; then
echo "Universal2 app smoke did not record the application exit status."
exit 1
fi
if [ ! -f "${smoke_console}" ]; then
echo "Universal2 app smoke console output was not created: ${smoke_console}"
exit 1
fi
app_status="$(tr -d '[:space:]' < "${smoke_exit_status}")"
if ! [[ "${app_status}" =~ ^[0-9]+$ ]] || [ "${app_status}" -gt 127 ]; then
echo "Universal2 app smoke ended abnormally with status '${app_status}'."
exit 1
fi
require_smoke_output() {
local expected="$1"
if ! grep -Fq "${expected}" "${smoke_console}"; then
echo "Universal2 app smoke console output is missing: ${expected}"
tail -n 160 "${smoke_console}" || true
exit 1
fi
}
require_smoke_output "RendererDefaultSafety self-test passed"
require_smoke_output "Filesystem paths:"
require_smoke_output "fs_cdpath='${package_dir}/openQ4.app/Contents/Resources'"
require_smoke_output "Selected game module: logical='game_sp' binary='game-sp_universal2'"
if grep -Eiq '(^|[[:space:]])(FATAL|Sys_Error):' "${smoke_console}" "${smoke_log}"; then
echo "Universal2 app smoke output contains a fatal startup diagnostic."
exit 1
fi
if [ "${app_status}" -ne 0 ]; then
echo "Universal2 app smoke completed its startup and shutdown checks with SDL launcher status ${app_status}."
fi

- name: Upload universal2 candidate evidence
if: always()
Expand Down
8 changes: 5 additions & 3 deletions .github/workflows/manual-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1615,6 +1615,7 @@ jobs:
module_dir="${app_root}/Contents/Frameworks"
sp_module="${module_dir}/game-sp_${{ matrix.binary_arch }}.dylib"
mp_module="${module_dir}/game-mp_${{ matrix.binary_arch }}.dylib"
renderer_module="${module_dir}/renderer-vk_${{ matrix.binary_arch }}.dylib"

if [ ! -f "${app_plist}" ]; then
echo "Missing macOS app Info.plist: ${app_plist}"
Expand Down Expand Up @@ -1729,7 +1730,7 @@ jobs:
echo "macOS package must not duplicate baseoq4 beside the self-contained app bundle."
exit 1
fi
for module in "${sp_module}" "${mp_module}"; do
for module in "${sp_module}" "${mp_module}" "${renderer_module}"; do
if [ ! -x "${module}" ]; then
echo "Missing or non-executable macOS package game module: ${module}"
exit 1
Expand Down Expand Up @@ -1810,7 +1811,7 @@ jobs:
for macho_arch in ${expected_lipo_arches}; do
actual="$(otool -arch "${macho_arch}" -D "${binary}" | sed -n '2p' | tr -d '[:space:]')"
if [ "${actual}" != "${expected}" ]; then
echo "macOS game module install name mismatch: ${binary} (${macho_arch}); expected ${expected}, found ${actual:-<empty>}."
echo "macOS loadable module install name mismatch: ${binary} (${macho_arch}); expected ${expected}, found ${actual:-<empty>}."
exit 1
fi
done
Expand Down Expand Up @@ -1841,7 +1842,7 @@ jobs:
done
done
}
for binary in "${app_exec}" "${client_binary}" "${dedicated_binary}" "${sp_module}" "${mp_module}"; do
for binary in "${app_exec}" "${client_binary}" "${dedicated_binary}" "${sp_module}" "${mp_module}" "${renderer_module}"; do
check_macos_binary_architecture "${binary}"
check_macos_binary_dependencies "${binary}"
check_macos_codesignature "${binary}"
Expand All @@ -1862,6 +1863,7 @@ jobs:
fi
check_macos_install_name "${sp_module}" "@loader_path/game-sp_${{ matrix.binary_arch }}.dylib"
check_macos_install_name "${mp_module}" "@loader_path/game-mp_${{ matrix.binary_arch }}.dylib"
check_macos_install_name "${renderer_module}" "@loader_path/renderer-vk_${{ matrix.binary_arch }}.dylib"
check_plist_value() {
key="$1"
expected="$2"
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/push-verification.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ jobs:
tools/tests/idstr_input_safety.py \
tools/tests/lexer_peek_contract.py \
tools/tests/key_bind_presentation.py \
tools/tests/levelshot_inventory.py \
tools/tests/linux_arm64_cross_compile.py \
tools/tests/linux_arm64_ci_coverage.py \
tools/tests/linux_arm64_release_evidence.py \
Expand Down Expand Up @@ -215,6 +216,7 @@ jobs:
python tools/tests/idstr_input_safety.py
python tools/tests/lexer_peek_contract.py
python tools/tests/key_bind_presentation.py
python tools/tests/levelshot_inventory.py
python tools/tests/linux_arm64_cross_compile.py
python tools/tests/linux_arm64_ci_coverage.py
python tools/tests/linux_arm64_release_evidence.py
Expand Down
Loading
Loading