mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-08 02:53:25 -08:00
Adds --sanitize to .ci/compile.sh, mirroring --test, and turns it on for one entry of the existing Linux Docker matrix: Ubuntu 26.04, which already had a test-enabled leg. That reuses the image, the ccache layer and the existing step shape, so the CI diff is a matrix key plus the argument plumbing. Debian 13 and Fedora 44 keep covering the uninstrumented suite, so nothing is lost by instrumenting one leg. Sanitizers stay off the release and package legs, which build with --release for packaging: instrumenting those would change the shipped binaries' optimization profile and build time for no benefit. macOS and Windows stay uninstrumented too, since ASan is unreliable against the Qt build there and MSVC has no equivalent without /fsanitize=address. --sanitize does not imply --test, so an instrumented build can be produced locally without paying for ctest. When both are given, ctest runs with detect_leaks=0 because Qt and the sanitizer runtimes both leak at exit by design and LeakSanitizer's default buries real findings under hundreds of process-teardown reports, and with UBSan halt_on_error=0 so one run collects many findings instead of stopping at the first. ASan keeps abort_on_error=1, since a bad access leaves the process unusable and continuing only produces a second, more confusing report from the wreckage.
593 lines
22 KiB
YAML
593 lines
22 KiB
YAML
name: Build Desktop
|
|
|
|
permissions:
|
|
actions: write # needed to delete entries in GHA cache (update ccache)
|
|
attestations: write # needed to persist the attestation.
|
|
contents: write # needed for e.g. vcpkg dependency graph updates
|
|
id-token: write # needed for signing certificate in attestation
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- master
|
|
paths:
|
|
- '*/**' # matches all files not in root
|
|
- '!**.md'
|
|
- '!.github/**'
|
|
- '!.tx/**'
|
|
- '!doc/**'
|
|
- '.github/workflows/desktop-build.yml'
|
|
- 'CMakeLists.txt'
|
|
- 'vcpkg.json'
|
|
- 'vcpkg' # needed to match submodule bumps (gitlink)
|
|
tags:
|
|
- '*'
|
|
pull_request:
|
|
paths:
|
|
- '*/**' # matches all files not in root
|
|
- '!**.md'
|
|
- '!.github/**'
|
|
- '!.tx/**'
|
|
- '!doc/**'
|
|
- '.github/workflows/desktop-build.yml'
|
|
- 'CMakeLists.txt'
|
|
- 'vcpkg.json'
|
|
- 'vcpkg' # needed to match submodule bumps (gitlink)
|
|
|
|
# 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' }}
|
|
|
|
jobs:
|
|
configure:
|
|
name: Configure
|
|
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 }}
|
|
|
|
steps:
|
|
- name: "Configure"
|
|
env:
|
|
RESOLVED_SHA: ${{ case(github.event_name == 'pull_request', github.event.pull_request.head.sha, github.sha) }}
|
|
id: configure
|
|
shell: bash
|
|
run: |
|
|
if [[ "$GITHUB_REF_TYPE" == 'tag' ]]; then # release
|
|
echo "tag=$GITHUB_REF_NAME" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
echo "sha=$RESOLVED_SHA" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: "Checkout"
|
|
if: steps.configure.outputs.tag != null
|
|
uses: actions/checkout@v7
|
|
with:
|
|
fetch-depth: 0 # fetch all history for all branches and tags
|
|
|
|
- name: "Prepare release parameters"
|
|
id: prepare
|
|
if: steps.configure.outputs.tag != null
|
|
shell: bash
|
|
env:
|
|
TAG: ${{ steps.configure.outputs.tag }}
|
|
run: .ci/prep_release.sh
|
|
|
|
- name: "Create release"
|
|
if: steps.configure.outputs.tag != null
|
|
id: create_release
|
|
shell: bash
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
tag_name: ${{ steps.configure.outputs.tag }}
|
|
target: ${{ steps.configure.outputs.sha }}
|
|
release_name: ${{ steps.prepare.outputs.title }}
|
|
body_path: ${{ steps.prepare.outputs.body_path }}
|
|
prerelease: ${{ steps.prepare.outputs.is_beta }}
|
|
run: |
|
|
args=()
|
|
[[ $prerelease == yes ]] && args+=(--prerelease)
|
|
|
|
gh release create "$tag_name" --verify-tag --draft "${args[@]}" \
|
|
--target "$target" \
|
|
--title "$release_name" \
|
|
--notes-file "$body_path"
|
|
|
|
build-linux:
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
# The files in ".ci/$distro$version" correspond to the values given here
|
|
include:
|
|
- distro: Arch
|
|
|
|
allow-failure: yes
|
|
package: skip # We are packaged in Arch already
|
|
|
|
- distro: Servatrice_Debian
|
|
version: 12
|
|
|
|
package: DEB
|
|
server_only: yes
|
|
test: skip
|
|
|
|
- distro: Debian
|
|
version: 12
|
|
|
|
package: DEB
|
|
test: skip # Running tests on all distros is superfluous
|
|
|
|
- distro: Debian
|
|
version: 13
|
|
|
|
package: DEB
|
|
|
|
- distro: Fedora
|
|
version: 43
|
|
|
|
package: RPM
|
|
test: skip # Running tests on all distros is superfluous
|
|
|
|
- distro: Fedora
|
|
version: 44
|
|
|
|
package: RPM
|
|
|
|
- distro: Ubuntu
|
|
version: 24.04
|
|
|
|
package: DEB
|
|
test: skip # Running tests on all distros is superfluous
|
|
|
|
- distro: Ubuntu
|
|
version: 26.04
|
|
|
|
package: DEB
|
|
|
|
# The one leg that runs the suite under AddressSanitizer and
|
|
# UndefinedBehaviorSanitizer. Debian 13 and Fedora 44 keep covering the
|
|
# uninstrumented suite, so nothing is lost by instrumenting this one.
|
|
sanitize: yes
|
|
|
|
name: ${{ matrix.distro }} ${{ matrix.version }}
|
|
needs: configure
|
|
runs-on: ubuntu-latest # https://github.com/actions/runner-images
|
|
continue-on-error: ${{ matrix.allow-failure == 'yes' }}
|
|
timeout-minutes: 70
|
|
env:
|
|
CACHE: ${{ github.workspace }}/.cache/${{ matrix.distro }}${{ matrix.version }} # directory for caching docker image and ccache
|
|
CCACHE_EVICTION_AGE: 7d
|
|
CCACHE_SIZE: 600M # space of all repo is 10Gi: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#usage-limits-and-eviction-policy
|
|
CMAKE_GENERATOR: 'Ninja'
|
|
NAME: ${{ matrix.distro }}${{ matrix.version }}
|
|
|
|
steps:
|
|
- name: "Checkout"
|
|
uses: actions/checkout@v7
|
|
|
|
- name: "Restore compiler cache (ccache)"
|
|
id: restore_ccache
|
|
uses: actions/cache/restore@v6
|
|
with:
|
|
key: ccache-${{ matrix.distro }}${{ matrix.version }}
|
|
path: ${{ env.CACHE }}
|
|
|
|
- name: "Build ${{ matrix.distro }} ${{ matrix.version }} Docker image"
|
|
shell: bash
|
|
run: source .ci/docker.sh --build
|
|
|
|
- name: "Build debug and test"
|
|
if: matrix.test != 'skip'
|
|
shell: bash
|
|
env:
|
|
sanitize: '${{ matrix.sanitize }}'
|
|
run: |
|
|
source .ci/docker.sh
|
|
args=()
|
|
[[ $GITHUB_REF == "refs/heads/master" ]] && args+=(--evict-ccache "$CCACHE_EVICTION_AGE")
|
|
args+=(--ccache "$CCACHE_SIZE")
|
|
args+=(--cmake-generator "$CMAKE_GENERATOR")
|
|
|
|
extra=()
|
|
[[ $sanitize == yes ]] && extra+=(--sanitize)
|
|
|
|
RUN --server --debug --test "${extra[@]}" "${args[@]}"
|
|
|
|
- name: "Build release package"
|
|
id: build
|
|
if: matrix.package != 'skip'
|
|
shell: bash
|
|
env:
|
|
SUFFIX: '-${{ matrix.distro }}${{ matrix.version }}'
|
|
package: '${{ matrix.package }}'
|
|
server_only: '${{ matrix.server_only }}'
|
|
run: |
|
|
source .ci/docker.sh
|
|
args=()
|
|
[[ $server_only == yes ]] && args+=(--no-client)
|
|
[[ $GITHUB_REF == "refs/heads/master" ]] && args+=(--evict-ccache "$CCACHE_EVICTION_AGE")
|
|
args+=(--ccache "$CCACHE_SIZE")
|
|
args+=(--cmake-generator "$CMAKE_GENERATOR")
|
|
args+=(--suffix "$SUFFIX")
|
|
|
|
RUN --server --release --package "$package" "${args[@]}"
|
|
|
|
# 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.restore_ccache.outputs.cache-hit
|
|
continue-on-error: true
|
|
env:
|
|
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: "Save updated compiler cache (ccache)"
|
|
if: github.ref == 'refs/heads/master'
|
|
uses: actions/cache/save@v6
|
|
with:
|
|
key: ${{ steps.restore_ccache.outputs.cache-primary-key }}
|
|
path: ${{ env.CACHE }}
|
|
|
|
- name: "Upload artifact"
|
|
id: upload_artifact
|
|
if: matrix.package != 'skip'
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
archive: false
|
|
if-no-files-found: error
|
|
path: ${{ steps.build.outputs.path }}
|
|
|
|
- name: "Upload to release"
|
|
id: upload_release
|
|
if: matrix.package != 'skip' && needs.configure.outputs.tag != null
|
|
shell: bash
|
|
env:
|
|
asset_name: ${{ steps.build.outputs.fullname }}
|
|
asset_path: ${{ steps.build.outputs.path }}
|
|
GH_TOKEN: ${{ github.token }}
|
|
tag_name: ${{ needs.configure.outputs.tag }}
|
|
run: gh release upload "$tag_name" "$asset_path#$asset_name"
|
|
|
|
- name: "Attest binary provenance"
|
|
id: attestation
|
|
if: steps.upload_release.outcome == 'success'
|
|
uses: actions/attest@v4
|
|
with:
|
|
show-summary: false
|
|
subject-path: ${{ steps.build.outputs.path }}
|
|
|
|
- name: "Verify binary attestation"
|
|
if: steps.attestation.outcome == 'success'
|
|
shell: bash
|
|
env:
|
|
BUILD_PATH: ${{ steps.build.outputs.path }}
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: gh attestation verify "$BUILD_PATH" --repo Cockatrice/Cockatrice
|
|
|
|
build-vcpkg:
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- os: macOS
|
|
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.*
|
|
qt_modules: qtimageformats qtmultimedia qtshadertools qtwebsockets
|
|
soc: Intel
|
|
type: Release
|
|
use_ccache: 1
|
|
xcode: "26.3"
|
|
|
|
- os: macOS
|
|
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.*
|
|
qt_modules: qtimageformats qtmultimedia qtshadertools qtwebsockets
|
|
soc: Apple
|
|
type: Release
|
|
use_ccache: 1
|
|
xcode: "26.6"
|
|
|
|
- os: macOS
|
|
target: 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.*
|
|
qt_modules: qtimageformats qtmultimedia qtshadertools qtwebsockets
|
|
soc: Apple
|
|
type: Release
|
|
use_ccache: 1
|
|
xcode: "26.6"
|
|
|
|
- os: macOS
|
|
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.*
|
|
qt_modules: qtimageformats qtmultimedia qtshadertools qtwebsockets
|
|
soc: Apple
|
|
type: Debug
|
|
use_ccache: 1
|
|
xcode: "26.6"
|
|
|
|
- os: Windows
|
|
target: 10
|
|
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.*
|
|
qt_modules: qtimageformats qtmultimedia qtshadertools qtwebsockets
|
|
type: Release
|
|
|
|
name: ${{ matrix.os }} ${{ matrix.target }}${{ matrix.soc == 'Intel' && ' Intel' || '' }}${{ matrix.type == 'Debug' && ' Debug' || '' }}
|
|
needs: configure
|
|
runs-on: ${{ matrix.runner }}
|
|
timeout-minutes: 100
|
|
env:
|
|
CCACHE_DIR: ${{ github.workspace }}/.cache/
|
|
CCACHE_SIZE: 600M # space of all repo is 10Gi: https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#usage-limits-and-eviction-policy
|
|
|
|
steps:
|
|
- name: "Checkout"
|
|
uses: actions/checkout@v7
|
|
with:
|
|
submodules: recursive
|
|
|
|
- name: "[Windows] Add msbuild to PATH"
|
|
if: matrix.os == 'Windows'
|
|
uses: microsoft/setup-msbuild@v3
|
|
with:
|
|
msbuild-architecture: x64
|
|
|
|
- name: "[macOS] Setup ccache"
|
|
if: matrix.os == 'macOS' && matrix.use_ccache == 1
|
|
run: brew install ccache
|
|
|
|
- name: "[macOS] Restore compiler cache (ccache)"
|
|
if: matrix.os == 'macOS' && matrix.use_ccache == 1
|
|
id: restore_ccache
|
|
uses: actions/cache/restore@v6
|
|
with:
|
|
key: ccache-${{ matrix.runner }}_${{ matrix.override_target }}-Xcode${{ matrix.xcode }}
|
|
path: ${{ env.CCACHE_DIR }}
|
|
|
|
- name: "[macOS] Install aqtinstall"
|
|
if: matrix.os == 'macOS'
|
|
run: pipx install aqtinstall
|
|
|
|
# Resolve given wildcard versions (e.g. Qt 6.6.*) to latest version via aqtinstall to avoid stale caches on new releases
|
|
- name: "[macOS] Resolve latest Qt from ${{ matrix.qt_version }} input"
|
|
if: matrix.os == 'macOS'
|
|
env:
|
|
QT_VERSION: ${{ matrix.qt_version }}
|
|
id: resolve_qt_version
|
|
shell: bash
|
|
run: .ci/resolve_latest_aqt_qt_version.sh "$QT_VERSION"
|
|
|
|
- name: "[macOS] Restore thin Qt ${{ steps.resolve_qt_version.outputs.version }}"
|
|
if: matrix.os == 'macOS'
|
|
id: restore_qt
|
|
uses: actions/cache/restore@v6
|
|
with:
|
|
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
|
|
# Qt build using vcpkg either just fails or takes too long to build
|
|
- name: "[macOS] Install fat Qt ${{ matrix.qt_version }}"
|
|
if: matrix.os == 'macOS' && steps.restore_qt.outputs.cache-hit != 'true'
|
|
uses: jurplel/install-qt-action@v4
|
|
with:
|
|
cache: false
|
|
# cache-key-prefix: Qt
|
|
dir: ${{ github.workspace }} # thinning script depends on this location
|
|
modules: ${{ matrix.qt_modules }}
|
|
version: ${{ matrix.qt_version }}
|
|
|
|
- name: "[macOS] Create thin Qt libraries"
|
|
if: matrix.os == 'macOS' && steps.restore_qt.outputs.cache-hit != 'true'
|
|
run: .ci/thin_macos_qtlib.sh
|
|
|
|
- name: "[macOS] Cache thin Qt libraries"
|
|
if: matrix.os == 'macOS' && steps.restore_qt.outputs.cache-hit != 'true' && github.ref == 'refs/heads/master'
|
|
uses: actions/cache/save@v6
|
|
with:
|
|
key: ${{ steps.restore_qt.outputs.cache-primary-key }}
|
|
path: ${{ github.workspace }}/Qt
|
|
|
|
- name: "[Windows] Install Qt ${{ matrix.qt_version }}"
|
|
if: matrix.os == 'Windows'
|
|
uses: jurplel/install-qt-action@v4
|
|
with:
|
|
# 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: ${{ github.ref == 'refs/heads/master' }}
|
|
cache-key-prefix: Qt
|
|
modules: ${{ matrix.qt_modules }}
|
|
version: ${{ matrix.qt_version }}
|
|
|
|
- name: "[Windows] Install NSIS"
|
|
if: matrix.os == 'Windows'
|
|
shell: bash
|
|
run: choco install nsis
|
|
|
|
- name: "Setup vcpkg cache"
|
|
id: vcpkg-cache
|
|
uses: TAServers/vcpkg-cache@v3
|
|
with:
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
# Uses environment variables, see compile.sh for more details
|
|
- name: "Build Cockatrice"
|
|
id: build
|
|
shell: bash
|
|
env:
|
|
BUILDTYPE: '${{ matrix.type }}'
|
|
CCACHE_EVICTION_AGE: ${{ matrix.ccache_eviction_age }}
|
|
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 }}
|
|
MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }}
|
|
MAKE_PACKAGE: '${{ matrix.make_package }}'
|
|
PACKAGE_SUFFIX: '${{ matrix.package_suffix }}'
|
|
TARGET_MACOS_VERSION: ${{ matrix.override_target }}
|
|
USE_CCACHE: ${{ matrix.use_ccache }}
|
|
VCPKG_BINARY_SOURCES: "clear;files,${{ steps.vcpkg-cache.outputs.path }},${{ case(github.ref == 'refs/heads/master', 'readwrite', 'read') }}"
|
|
VCPKG_DISABLE_METRICS: 1
|
|
VCPKG_FEATURE_FLAGS: dependencygraph
|
|
run: .ci/compile.sh --server --test --vcpkg
|
|
|
|
# CPack reports a failed makensis run as "Problem running NSIS command"
|
|
# plus a path to NSISOutput.log, and that log lives only on the runner, so
|
|
# the actual compile error is otherwise nowhere in the workflow output.
|
|
# Dump it, or a broken installer script is undiagnosable from CI alone.
|
|
# shell: bash matters here - the default pwsh resolves `find` to Windows'
|
|
# text-search find.exe, which errors instead of searching.
|
|
- name: "Dump NSIS compile log"
|
|
if: failure() && matrix.os == 'Windows'
|
|
shell: bash
|
|
run: find . -name NSISOutput.log -exec cat {} +
|
|
|
|
# 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.restore_ccache.outputs.cache-hit
|
|
continue-on-error: true
|
|
env:
|
|
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] 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.restore_ccache.outputs.cache-primary-key }}
|
|
path: ${{ env.CCACHE_DIR }}
|
|
|
|
- name: "[macOS] Sign app bundle"
|
|
if: matrix.os == 'macOS' && matrix.make_package && needs.configure.outputs.tag != null
|
|
id: sign_macos
|
|
env:
|
|
BUILD_PATH: ${{ steps.build.outputs.path }}
|
|
MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }}
|
|
MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }}
|
|
run: |
|
|
if [[ -n "$MACOS_CERTIFICATE_NAME" ]]
|
|
then
|
|
security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain
|
|
/usr/bin/codesign --sign="$MACOS_CERTIFICATE_NAME" --entitlements=".ci/macos.entitlements" --options=runtime --force --deep --timestamp --verbose "$BUILD_PATH"
|
|
fi
|
|
|
|
- name: "[macOS] Notarize app bundle"
|
|
if: matrix.os == 'macOS' && steps.sign_macos.outcome == 'success'
|
|
env:
|
|
BUILD_PATH: ${{ steps.build.outputs.path }}
|
|
MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }}
|
|
MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }}
|
|
MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }}
|
|
run: |
|
|
if [[ -n "$MACOS_NOTARIZATION_APPLE_ID" ]]
|
|
then
|
|
# Store the notarization credentials so that we can prevent a UI password dialog from blocking the CI
|
|
echo "Create keychain profile"
|
|
xcrun notarytool store-credentials "notarytool-profile" --apple-id "$MACOS_NOTARIZATION_APPLE_ID" --team-id "$MACOS_NOTARIZATION_TEAM_ID" --password "$MACOS_NOTARIZATION_PWD"
|
|
|
|
# We can't notarize an app bundle directly, but we need to compress it as an archive.
|
|
# Therefore, we create a zip file containing our app bundle, so that we can send it to the
|
|
# notarization service
|
|
echo "Creating temp notarization archive"
|
|
ditto -c -k --keepParent "$BUILD_PATH" "notarization.zip"
|
|
|
|
# Here we send the notarization request to the Apple's Notarization service, waiting for the result.
|
|
# This typically takes a few seconds inside a CI environment, but it might take more depending on the App
|
|
# characteristics. Visit the Notarization docs for more information and strategies on how to optimize it if
|
|
# you're curious
|
|
echo "Notarize app"
|
|
xcrun notarytool submit "notarization.zip" --keychain-profile "notarytool-profile" --wait
|
|
|
|
# Finally, we need to "attach the staple" to our executable, which will allow our app to be
|
|
# validated by macOS even when an internet connection is not available.
|
|
echo "Attach staple"
|
|
xcrun stapler staple "$BUILD_PATH"
|
|
fi
|
|
|
|
- name: "Upload artifact"
|
|
if: matrix.make_package
|
|
id: upload_artifact
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
archive: false
|
|
if-no-files-found: error
|
|
path: ${{ steps.build.outputs.path }}
|
|
|
|
- name: "[Windows] Upload PDBs (Program Databases)"
|
|
if: matrix.os == 'Windows' && github.ref_type != 'tag'
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
if-no-files-found: error
|
|
name: ${{ steps.build.outputs.name }}-PDBs
|
|
path: |
|
|
build/cockatrice/Release/*.pdb
|
|
build/oracle/Release/*.pdb
|
|
build/servatrice/Release/*.pdb
|
|
|
|
- name: "Upload to release"
|
|
if: needs.configure.outputs.tag != null && matrix.make_package == '1'
|
|
id: upload_release
|
|
shell: bash
|
|
env:
|
|
asset_name: ${{ steps.build.outputs.fullname }}
|
|
asset_path: ${{ steps.build.outputs.path }}
|
|
GH_TOKEN: ${{ github.token }}
|
|
tag_name: ${{ needs.configure.outputs.tag }}
|
|
run: gh release upload "$tag_name" "$asset_path#$asset_name"
|
|
|
|
- name: "Attest binary provenance"
|
|
if: steps.upload_release.outcome == 'success'
|
|
id: attestation
|
|
uses: actions/attest@v4
|
|
with:
|
|
show-summary: false
|
|
subject-path: ${{ steps.build.outputs.path }}
|
|
|
|
- name: "Verify binary attestation"
|
|
if: steps.attestation.outcome == 'success'
|
|
shell: bash
|
|
env:
|
|
BUILD_PATH: ${{ steps.build.outputs.path }}
|
|
GH_TOKEN: ${{ github.token }}
|
|
run: gh attestation verify "$BUILD_PATH" --repo Cockatrice/Cockatrice
|