mirror of
https://git.citron-emu.org/citron/emu
synced 2025-05-13 03:10:36 +01:00
CI: Update CI workflows to use Citron-specific naming and paths
This commit is contained in:
parent
257aad2431
commit
eec0f34204
65 changed files with 2596 additions and 10 deletions
14
.ci/citron-canary-step1.yml
Executable file
14
.ci/citron-canary-step1.yml
Executable file
|
@ -0,0 +1,14 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
trigger:
|
||||
- master
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
stages:
|
||||
- stage: merge
|
||||
displayName: 'merge'
|
||||
jobs:
|
||||
- template: ./templates/merge-private.yml
|
59
.ci/citron-canary-step2.yml
Executable file
59
.ci/citron-canary-step2.yml
Executable file
|
@ -0,0 +1,59 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
trigger:
|
||||
- master
|
||||
|
||||
variables:
|
||||
DisplayVersion: $[counter(variables['DisplayPrefix'], 1)]
|
||||
|
||||
stages:
|
||||
- stage: build
|
||||
displayName: 'build'
|
||||
jobs:
|
||||
- job: linux
|
||||
timeoutInMinutes: 120
|
||||
displayName: 'linux'
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
strategy:
|
||||
maxParallel: 10
|
||||
matrix:
|
||||
linux:
|
||||
BuildSuffix: 'linux'
|
||||
ScriptFolder: 'linux'
|
||||
steps:
|
||||
- template: ./templates/sync-source.yml
|
||||
parameters:
|
||||
artifactSource: $(parameters.artifactSource)
|
||||
needSubmodules: 'true'
|
||||
- template: ./templates/build-single.yml
|
||||
parameters:
|
||||
artifactSource: 'false'
|
||||
cache: $(parameters.cache)
|
||||
version: $(DisplayVersion)
|
||||
- job: msvc
|
||||
timeoutInMinutes: 120
|
||||
displayName: 'windows'
|
||||
pool:
|
||||
vmImage: windows-2022
|
||||
steps:
|
||||
- template: ./templates/sync-source.yml
|
||||
parameters:
|
||||
artifactSource: $(parameters.artifactSource)
|
||||
needSubmodules: 'true'
|
||||
- template: ./templates/build-msvc.yml
|
||||
parameters:
|
||||
artifactSource: 'false'
|
||||
cache: $(parameters.cache)
|
||||
version: $(DisplayVersion)
|
||||
- stage: release
|
||||
displayName: 'release'
|
||||
dependsOn: build
|
||||
jobs:
|
||||
- job: release
|
||||
displayName: 'source'
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- template: ./templates/release-private-tag.yml
|
106
.ci/citron-pipeline.yml
Normal file
106
.ci/citron-pipeline.yml
Normal file
|
@ -0,0 +1,106 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
trigger:
|
||||
- master
|
||||
|
||||
variables:
|
||||
DisplayVersion: $[counter(variables['DisplayPrefix'], 1)]
|
||||
BuildName: 'stable'
|
||||
|
||||
stages:
|
||||
- stage: build
|
||||
displayName: 'build'
|
||||
jobs:
|
||||
- job: build
|
||||
timeoutInMinutes: 120
|
||||
displayName: 'standard'
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
strategy:
|
||||
maxParallel: 10
|
||||
matrix:
|
||||
linux:
|
||||
BuildSuffix: 'linux'
|
||||
ScriptFolder: 'linux'
|
||||
steps:
|
||||
- template: ./templates/sync-source.yml
|
||||
parameters:
|
||||
artifactSource: $(parameters.artifactSource)
|
||||
needSubmodules: 'true'
|
||||
- template: ./templates/build-single.yml
|
||||
parameters:
|
||||
artifactSource: 'false'
|
||||
cache: 'true'
|
||||
version: $(DisplayVersion)
|
||||
# Make tokens available to scripts
|
||||
- task: Bash@3
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: |
|
||||
echo "##vso[task.setvariable variable=EARLY_ACCESS_TOKEN]$(EARLY_ACCESS_TOKEN)"
|
||||
echo "##vso[task.setvariable variable=CI_RELEASE_TOKEN]$(CI_RELEASE_TOKEN)"
|
||||
|
||||
- stage: build_win
|
||||
displayName: 'build-windows'
|
||||
jobs:
|
||||
- job: build
|
||||
timeoutInMinutes: 120
|
||||
displayName: 'msvc'
|
||||
pool:
|
||||
vmImage: windows-2022
|
||||
steps:
|
||||
- template: ./templates/sync-source.yml
|
||||
parameters:
|
||||
artifactSource: $(parameters.artifactSource)
|
||||
needSubmodules: 'true'
|
||||
- template: ./templates/build-msvc.yml
|
||||
parameters:
|
||||
artifactSource: 'false'
|
||||
cache: 'true'
|
||||
version: $(DisplayVersion)
|
||||
# Make tokens available to scripts
|
||||
- task: PowerShell@2
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: |
|
||||
Write-Host "##vso[task.setvariable variable=EARLY_ACCESS_TOKEN]$(EARLY_ACCESS_TOKEN)"
|
||||
Write-Host "##vso[task.setvariable variable=CI_RELEASE_TOKEN]$(CI_RELEASE_TOKEN)"
|
||||
|
||||
- stage: build_android
|
||||
displayName: 'build-android'
|
||||
jobs:
|
||||
- job: build
|
||||
timeoutInMinutes: 120
|
||||
displayName: 'android'
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- template: ./templates/sync-source.yml
|
||||
parameters:
|
||||
artifactSource: $(parameters.artifactSource)
|
||||
needSubmodules: 'true'
|
||||
- task: Bash@3
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: |
|
||||
export USE_DEBUG_KEYSTORE=true
|
||||
chmod +x ./.ci/scripts/android/build.sh
|
||||
./.ci/scripts/android/build.sh
|
||||
- publish: artifacts
|
||||
artifact: 'citron-$(BuildName)-android'
|
||||
displayName: 'Upload Android Artifacts'
|
||||
|
||||
- stage: release
|
||||
displayName: 'release'
|
||||
dependsOn:
|
||||
- build
|
||||
- build_win
|
||||
- build_android
|
||||
jobs:
|
||||
- job: github
|
||||
displayName: 'github'
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- template: ./templates/release-github.yml
|
22
.ci/citron-repo-sync.yml
Executable file
22
.ci/citron-repo-sync.yml
Executable file
|
@ -0,0 +1,22 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
trigger:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
- job: copy
|
||||
displayName: 'Sync Repository'
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- script: echo 'https://$(GitUsername):$(GitAccessToken)@dev.azure.com' > $HOME/.git-credentials
|
||||
displayName: 'Load Credentials'
|
||||
- script: git config --global credential.helper store
|
||||
displayName: 'Register Credential Helper'
|
||||
- script: git remote add other $(GitRepoPushChangesURL)
|
||||
displayName: 'Register Repository'
|
||||
- script: git push --force other HEAD:$(GitPushBranch)
|
||||
displayName: 'Update Code'
|
||||
- script: rm -rf $HOME/.git-credentials
|
||||
displayName: 'Clear Cached Credentials'
|
14
.ci/citron-stable-step1.yml
Executable file
14
.ci/citron-stable-step1.yml
Executable file
|
@ -0,0 +1,14 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
trigger:
|
||||
- master
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
stages:
|
||||
- stage: merge
|
||||
displayName: 'merge'
|
||||
jobs:
|
||||
- template: ./templates/merge.yml
|
64
.ci/citron-stable-step2.yml
Executable file
64
.ci/citron-stable-step2.yml
Executable file
|
@ -0,0 +1,64 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
trigger:
|
||||
- master
|
||||
|
||||
variables:
|
||||
DisplayVersion: $[counter(variables['DisplayPrefix'], 1)]
|
||||
|
||||
stages:
|
||||
- stage: build
|
||||
displayName: 'build'
|
||||
jobs:
|
||||
- job: build
|
||||
timeoutInMinutes: 120
|
||||
displayName: 'standard'
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
strategy:
|
||||
maxParallel: 10
|
||||
matrix:
|
||||
linux:
|
||||
BuildSuffix: 'linux'
|
||||
ScriptFolder: 'linux'
|
||||
steps:
|
||||
- template: ./templates/sync-source.yml
|
||||
parameters:
|
||||
artifactSource: $(parameters.artifactSource)
|
||||
needSubmodules: 'true'
|
||||
- template: ./templates/build-single.yml
|
||||
parameters:
|
||||
artifactSource: 'false'
|
||||
cache: 'true'
|
||||
version: $(DisplayVersion)
|
||||
- stage: build_win
|
||||
displayName: 'build-windows'
|
||||
jobs:
|
||||
- job: build
|
||||
timeoutInMinutes: 120
|
||||
displayName: 'msvc'
|
||||
pool:
|
||||
vmImage: windows-2022
|
||||
steps:
|
||||
- template: ./templates/sync-source.yml
|
||||
parameters:
|
||||
artifactSource: $(parameters.artifactSource)
|
||||
needSubmodules: 'true'
|
||||
- template: ./templates/build-msvc.yml
|
||||
parameters:
|
||||
artifactSource: 'false'
|
||||
cache: 'true'
|
||||
version: $(DisplayVersion)
|
||||
- stage: release
|
||||
displayName: 'release'
|
||||
dependsOn:
|
||||
- build
|
||||
- build_win
|
||||
jobs:
|
||||
- job: github
|
||||
displayName: 'github'
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- template: ./templates/release-github.yml
|
23
.ci/citron-verify.yml
Executable file
23
.ci/citron-verify.yml
Executable file
|
@ -0,0 +1,23 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
stages:
|
||||
- stage: format
|
||||
displayName: 'format'
|
||||
jobs:
|
||||
- job: format
|
||||
displayName: 'clang'
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- template: ./templates/format-check.yml
|
||||
parameters:
|
||||
artifactSource: 'false'
|
||||
- stage: build
|
||||
displayName: 'build'
|
||||
dependsOn: format
|
||||
jobs:
|
||||
- template: ./templates/build-standard.yml
|
||||
parameters:
|
||||
cache: 'false'
|
||||
- template: ./templates/build-testing.yml
|
28
.ci/scripts/android/build.sh
Executable file
28
.ci/scripts/android/build.sh
Executable file
|
@ -0,0 +1,28 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
export NDK_CCACHE="$(which ccache)"
|
||||
ccache -s
|
||||
|
||||
BUILD_FLAVOR="stable"
|
||||
|
||||
mkdir -p "artifacts"
|
||||
|
||||
BUILD_TYPE="release"
|
||||
if [ "${GITHUB_REPOSITORY}" == "Citron-Project/Cit" ]; then
|
||||
BUILD_TYPE="relWithDebInfo"
|
||||
fi
|
||||
|
||||
# We'll use the Android debug keystore for builds
|
||||
# This removes the requirement for storing a keystore in secrets
|
||||
# For production builds, this should be replaced with a proper signing configuration
|
||||
export USE_DEBUG_KEYSTORE=true
|
||||
|
||||
cd src/android
|
||||
chmod +x ./gradlew
|
||||
./gradlew clean
|
||||
./gradlew app:assemble${BUILD_FLAVOR}${BUILD_TYPE}
|
||||
|
||||
ccache -s
|
21
.ci/scripts/android/canarybuild.sh
Executable file
21
.ci/scripts/android/canarybuild.sh
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2024 Citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
export NDK_CCACHE="$(which ccache)"
|
||||
ccache -s
|
||||
|
||||
export ANDROID_KEYSTORE_FILE="${GITHUB_WORKSPACE}/ks.jks"
|
||||
export SERVICE_ACCOUNT_KEY_PATH="${GITHUB_WORKSPACE}/service-account-key.json"
|
||||
|
||||
base64 --decode <<< "${CANARY_PLAY_ANDROID_KEYSTORE_B64}" > "${ANDROID_KEYSTORE_FILE}"
|
||||
chmod 600 "${ANDROID_KEYSTORE_FILE}"
|
||||
|
||||
mkdir -p "$(dirname "${SERVICE_ACCOUNT_KEY_PATH}")"
|
||||
base64 --decode <<< "${CANARY_SERVICE_ACCOUNT_KEY_B64}" > "${SERVICE_ACCOUNT_KEY_PATH}"
|
||||
./gradlew "publishCanaryReleaseBundle"
|
||||
|
||||
ccache -s
|
||||
|
||||
rm "${ANDROID_KEYSTORE_FILE}" "${SERVICE_ACCOUNT_KEY_PATH}"
|
21
.ci/scripts/android/eabuild.sh
Executable file
21
.ci/scripts/android/eabuild.sh
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2024 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
export NDK_CCACHE="$(which ccache)"
|
||||
ccache -s
|
||||
|
||||
export ANDROID_KEYSTORE_FILE="${GITHUB_WORKSPACE}/ks.jks"
|
||||
base64 --decode <<< "${EA_PLAY_ANDROID_KEYSTORE_B64}" > "${ANDROID_KEYSTORE_FILE}"
|
||||
export ANDROID_KEY_ALIAS="${PLAY_ANDROID_KEY_ALIAS}"
|
||||
export ANDROID_KEYSTORE_PASS="${PLAY_ANDROID_KEYSTORE_PASS}"
|
||||
export SERVICE_ACCOUNT_KEY_PATH="${GITHUB_WORKSPACE}/sa.json"
|
||||
base64 --decode <<< "${EA_SERVICE_ACCOUNT_KEY_B64}" > "${SERVICE_ACCOUNT_KEY_PATH}"
|
||||
./gradlew "publishEaReleaseBundle"
|
||||
|
||||
ccache -s
|
||||
|
||||
if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
|
||||
rm "${ANDROID_KEYSTORE_FILE}"
|
||||
fi
|
21
.ci/scripts/android/stablebuild.sh
Executable file
21
.ci/scripts/android/stablebuild.sh
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
export NDK_CCACHE="$(which ccache)"
|
||||
ccache -s
|
||||
|
||||
export ANDROID_KEYSTORE_FILE="${GITHUB_WORKSPACE}/ks.jks"
|
||||
export SERVICE_ACCOUNT_KEY_PATH="${GITHUB_WORKSPACE}/service-account-key.json"
|
||||
|
||||
base64 --decode <<< "${STABLE_PLAY_ANDROID_KEYSTORE_B64}" > "${ANDROID_KEYSTORE_FILE}"
|
||||
chmod 600 "${ANDROID_KEYSTORE_FILE}"
|
||||
|
||||
mkdir -p "$(dirname "${SERVICE_ACCOUNT_KEY_PATH}")"
|
||||
base64 --decode <<< "${STABLE_SERVICE_ACCOUNT_KEY_B64}" > "${SERVICE_ACCOUNT_KEY_PATH}"
|
||||
./gradlew "publishStableReleaseBundle"
|
||||
|
||||
ccache -s
|
||||
|
||||
rm "${ANDROID_KEYSTORE_FILE}" "${SERVICE_ACCOUNT_KEY_PATH}"
|
41
.ci/scripts/android/upload.sh
Executable file
41
.ci/scripts/android/upload.sh
Executable file
|
@ -0,0 +1,41 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
. .ci/scripts/common/pre-upload.sh
|
||||
|
||||
APPNAME="org.citron.citron"
|
||||
|
||||
REV_NAME="${APPNAME}-${GITDATE}-${GITREV}"
|
||||
|
||||
APK="${REV_NAME}.apk"
|
||||
|
||||
if [ "${GITHUB_REPOSITORY}" == "Citron-Project/Cit" ]; then
|
||||
cd src/android
|
||||
./gradlew app:bundleRelease
|
||||
# RELEASE_BODY gets reset here, but its fine since we're uploading after the GitHub Release
|
||||
. .ci/scripts/common/post-upload.sh
|
||||
|
||||
sudo apt-get install -y jq
|
||||
|
||||
ls app/build/outputs/bundle/release/
|
||||
|
||||
echo "Downloading CI scripts bundle"
|
||||
ARTIFACTS_DIR="/tmp/artifact-pool"
|
||||
mkdir -p "$ARTIFACTS_DIR"
|
||||
fi
|
||||
|
||||
BUILD_FLAVOR="stable"
|
||||
|
||||
BUILD_TYPE_LOWER="release"
|
||||
BUILD_TYPE_UPPER="Release"
|
||||
if [ "${GITHUB_REPOSITORY}" == "Citron-Project/Cit" ]; then
|
||||
BUILD_TYPE_LOWER="relWithDebInfo"
|
||||
BUILD_TYPE_UPPER="RelWithDebInfo"
|
||||
fi
|
||||
|
||||
cp src/android/app/build/outputs/apk/"${BUILD_FLAVOR}/${BUILD_TYPE_LOWER}/app-${BUILD_FLAVOR}-${BUILD_TYPE_LOWER}.apk" \
|
||||
"artifacts/${REV_NAME}.apk"
|
||||
cp src/android/app/build/outputs/bundle/"${BUILD_FLAVOR}${BUILD_TYPE_UPPER}"/"app-${BUILD_FLAVOR}-${BUILD_TYPE_LOWER}.aab" \
|
||||
"artifacts/${REV_NAME}.aab"
|
32
.ci/scripts/clang/docker.sh
Executable file
32
.ci/scripts/clang/docker.sh
Executable file
|
@ -0,0 +1,32 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2021 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# Exit on error, rather than continuing with the rest of the script.
|
||||
set -e
|
||||
|
||||
ccache -s
|
||||
|
||||
mkdir build || true && cd build
|
||||
cmake .. \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_CXX_FLAGS="-march=x86-64-v2" \
|
||||
-DCMAKE_CXX_COMPILER=/usr/lib/ccache/clang++ \
|
||||
-DCMAKE_C_COMPILER=/usr/lib/ccache/clang \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DDISPLAY_VERSION=$1 \
|
||||
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
|
||||
-DENABLE_QT_TRANSLATION=ON \
|
||||
-DUSE_DISCORD_PRESENCE=ON \
|
||||
-DYUZU_CRASH_DUMPS=ON \
|
||||
-DYUZU_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} \
|
||||
-DYUZU_USE_BUNDLED_FFMPEG=ON \
|
||||
-GNinja
|
||||
|
||||
ninja
|
||||
|
||||
ccache -s
|
||||
|
||||
ctest -VV -C Release
|
||||
|
11
.ci/scripts/clang/exec.sh
Executable file
11
.ci/scripts/clang/exec.sh
Executable file
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2021 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
mkdir -p "ccache" || true
|
||||
chmod a+x ./.ci/scripts/clang/docker.sh
|
||||
# the UID for the container citron user is 1027
|
||||
sudo chown -R 1027 ./
|
||||
docker run -e ENABLE_COMPATIBILITY_REPORTING -e CCACHE_DIR=/citron/ccache -v "$(pwd):/citron" -w /citron yuzu-emu-mirror/build-environments:linux-fresh /bin/bash /citron/.ci/scripts/clang/docker.sh "$1"
|
||||
sudo chown -R $UID ./
|
23
.ci/scripts/clang/upload.sh
Executable file
23
.ci/scripts/clang/upload.sh
Executable file
|
@ -0,0 +1,23 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
. .ci/scripts/common/pre-upload.sh
|
||||
|
||||
REV_NAME="citron-linux-clang-${GITDATE}-${GITREV}"
|
||||
ARCHIVE_NAME="${REV_NAME}.tar.xz"
|
||||
COMPRESSION_FLAGS="-cJvf"
|
||||
|
||||
if [ "${RELEASE_NAME}" = "stable" ]; then
|
||||
DIR_NAME="${REV_NAME}"
|
||||
else
|
||||
DIR_NAME="${REV_NAME}_${RELEASE_NAME}"
|
||||
fi
|
||||
|
||||
mkdir -p $DIR_NAME
|
||||
|
||||
cp build/bin/citron "$DIR_NAME"
|
||||
cp build/bin/citron-cmd "$DIR_NAME"
|
||||
|
||||
. .ci/scripts/common/post-upload.sh
|
20
.ci/scripts/common/post-upload.sh
Executable file
20
.ci/scripts/common/post-upload.sh
Executable file
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# Copy documentation
|
||||
cp LICENSE.txt "$DIR_NAME"
|
||||
cp README.md "$DIR_NAME"
|
||||
|
||||
if [[ -z "${NO_SOURCE_PACK}" ]]; then
|
||||
git clone --depth 1 file://$(readlink -e .) ${REV_NAME}-source
|
||||
tar -cJvf "${REV_NAME}-source.tar.xz" ${REV_NAME}-source
|
||||
cp -v "${REV_NAME}-source.tar.xz" "$DIR_NAME"
|
||||
cp -v "${REV_NAME}-source.tar.xz" "${ARTIFACTS_DIR}/"
|
||||
fi
|
||||
|
||||
tar $COMPRESSION_FLAGS "$ARCHIVE_NAME" "$DIR_NAME"
|
||||
|
||||
# move the compiled archive into the artifacts directory to be uploaded by travis releases
|
||||
mv "$ARCHIVE_NAME" "${ARTIFACTS_DIR}/"
|
10
.ci/scripts/common/pre-upload.sh
Executable file
10
.ci/scripts/common/pre-upload.sh
Executable file
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
GITDATE="`git show -s --date=short --format='%ad' | sed 's/-//g'`"
|
||||
GITREV="`git show -s --format='%h'`"
|
||||
ARTIFACTS_DIR="$PWD/artifacts"
|
||||
|
||||
mkdir -p "${ARTIFACTS_DIR}/"
|
9
.ci/scripts/format/docker.sh
Executable file
9
.ci/scripts/format/docker.sh
Executable file
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# Run clang-format
|
||||
cd /citron
|
||||
chmod a+x ./.ci/scripts/format/script.sh
|
||||
./.ci/scripts/format/script.sh
|
10
.ci/scripts/format/exec.sh
Executable file
10
.ci/scripts/format/exec.sh
Executable file
|
@ -0,0 +1,10 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
chmod a+x ./.ci/scripts/format/docker.sh
|
||||
# the UID for the container citron user is 1027
|
||||
sudo chown -R 1027 ./
|
||||
docker run -v "$(pwd):/citron" -w /citron yuzu-emu-mirror/build-environments:linux-clang-format /bin/bash -ex /citron/.ci/scripts/format/docker.sh
|
||||
sudo chown -R $UID ./
|
37
.ci/scripts/format/script.sh
Executable file
37
.ci/scripts/format/script.sh
Executable file
|
@ -0,0 +1,37 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
shopt -s nullglob globstar
|
||||
|
||||
if git grep -nrI '\s$' src **/*.yml **/*.txt **/*.md Doxyfile .gitignore .gitmodules .ci* dist/*.desktop dist/*.svg dist/*.xml; then
|
||||
echo Trailing whitespace found, aborting
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Default clang-format points to default 3.5 version one
|
||||
CLANG_FORMAT="${CLANG_FORMAT:-clang-format-15}"
|
||||
"$CLANG_FORMAT" --version
|
||||
|
||||
# Turn off tracing for this because it's too verbose
|
||||
set +x
|
||||
|
||||
# Check everything for branch pushes
|
||||
FILES_TO_LINT="$(find src/ -name '*.cpp' -or -name '*.h')"
|
||||
|
||||
for f in $FILES_TO_LINT; do
|
||||
echo "$f"
|
||||
"$CLANG_FORMAT" -i "$f"
|
||||
done
|
||||
|
||||
DIFF=$(git -c core.fileMode=false diff)
|
||||
|
||||
if [ ! -z "$DIFF" ]; then
|
||||
echo "!!! Not compliant to coding style, here is the fix:"
|
||||
echo "$DIFF"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd src/android
|
||||
./gradlew ktlintCheck
|
79
.ci/scripts/linux/docker.sh
Executable file
79
.ci/scripts/linux/docker.sh
Executable file
|
@ -0,0 +1,79 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# Exit on error, rather than continuing with the rest of the script.
|
||||
set -e
|
||||
|
||||
ccache -s
|
||||
|
||||
mkdir build || true && cd build
|
||||
cmake .. \
|
||||
-DBoost_USE_STATIC_LIBS=ON \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DCMAKE_CXX_FLAGS="-march=x86-64-v2" \
|
||||
-DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ \
|
||||
-DCMAKE_C_COMPILER=/usr/lib/ccache/gcc \
|
||||
-DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DDISPLAY_VERSION=$1 \
|
||||
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
|
||||
-DENABLE_QT_TRANSLATION=ON \
|
||||
-DUSE_DISCORD_PRESENCE=ON \
|
||||
-DCITRON_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} \
|
||||
-DCITRON_USE_BUNDLED_FFMPEG=ON \
|
||||
-DCITRON_ENABLE_LTO=ON \
|
||||
-DCITRON_CRASH_DUMPS=ON \
|
||||
-GNinja
|
||||
|
||||
ninja
|
||||
|
||||
ccache -s
|
||||
|
||||
ctest -VV -C Release
|
||||
|
||||
# Separate debug symbols from specified executables
|
||||
for EXE in citron; do
|
||||
EXE_PATH="bin/$EXE"
|
||||
# Copy debug symbols out
|
||||
objcopy --only-keep-debug $EXE_PATH $EXE_PATH.debug
|
||||
# Add debug link and strip debug symbols
|
||||
objcopy -g --add-gnu-debuglink=$EXE_PATH.debug $EXE_PATH $EXE_PATH.out
|
||||
# Overwrite original with stripped copy
|
||||
mv $EXE_PATH.out $EXE_PATH
|
||||
done
|
||||
# Strip debug symbols from all executables
|
||||
find bin/ -type f -not -regex '.*.debug' -exec strip -g {} ';'
|
||||
|
||||
DESTDIR="$PWD/AppDir" ninja install
|
||||
rm -vf AppDir/usr/bin/citron-cmd AppDir/usr/bin/citron-tester
|
||||
|
||||
# Download tools needed to build an AppImage
|
||||
wget -nc https://raw.githubusercontent.com/yuzu-emu-mirror/ext-linux-bin/main/appimage/deploy-linux.sh || wget -nc https://raw.githubusercontent.com/AppImage/AppImageKit/master/appimagetool/deploy-linux.sh
|
||||
wget -nc https://raw.githubusercontent.com/yuzu-emu-mirror/AppImageKit-checkrt/old/AppRun.sh || wget -nc https://raw.githubusercontent.com/darealshinji/AppImageKit-checkrt/master/AppRun.sh
|
||||
wget -nc https://github.com/yuzu-emu-mirror/ext-linux-bin/raw/main/appimage/exec-x86_64.so || wget -nc https://github.com/darealshinji/AppImageKit-checkrt/releases/download/continuous/exec-x86_64.so
|
||||
# Set executable bit
|
||||
chmod 755 \
|
||||
deploy-linux.sh \
|
||||
AppRun.sh \
|
||||
exec-x86_64.so
|
||||
|
||||
# Workaround for https://github.com/AppImage/AppImageKit/issues/828
|
||||
export APPIMAGE_EXTRACT_AND_RUN=1
|
||||
|
||||
mkdir -p AppDir/usr/optional
|
||||
mkdir -p AppDir/usr/optional/libstdc++
|
||||
mkdir -p AppDir/usr/optional/libgcc_s
|
||||
|
||||
# Deploy citron's needed dependencies
|
||||
DEPLOY_QT=1 ./deploy-linux.sh AppDir/usr/bin/citron AppDir
|
||||
|
||||
# Workaround for libQt5MultimediaGstTools indirectly requiring libwayland-client and breaking Vulkan usage on end-user systems
|
||||
find AppDir -type f -regex '.*libwayland-client\.so.*' -delete -print
|
||||
|
||||
# Workaround for building citron with GCC 10 but also trying to distribute it to Ubuntu 18.04 et al.
|
||||
# See https://github.com/darealshinji/AppImageKit-checkrt
|
||||
cp exec-x86_64.so AppDir/usr/optional/exec.so
|
||||
cp AppRun.sh AppDir/AppRun
|
||||
cp --dereference /usr/lib/x86_64-linux-gnu/libstdc++.so.6 AppDir/usr/optional/libstdc++/libstdc++.so.6
|
||||
cp --dereference /lib/x86_64-linux-gnu/libgcc_s.so.1 AppDir/usr/optional/libgcc_s/libgcc_s.so.1
|
16
.ci/scripts/linux/exec.sh
Executable file
16
.ci/scripts/linux/exec.sh
Executable file
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
mkdir -p "ccache" || true
|
||||
chmod a+x ./.ci/scripts/linux/docker.sh
|
||||
# the UID for the container citron user is 1027
|
||||
sudo chown -R 1027 ./
|
||||
|
||||
# The environment variables listed below:
|
||||
# AZURECIREPO TITLEBARFORMATIDLE TITLEBARFORMATRUNNING DISPLAYVERSION
|
||||
# are requested in src/common/CMakeLists.txt and appear to be provided somewhere in Azure DevOps
|
||||
|
||||
docker run -e AZURECIREPO -e TITLEBARFORMATIDLE -e TITLEBARFORMATRUNNING -e DISPLAYVERSION -e ENABLE_COMPATIBILITY_REPORTING -e CCACHE_DIR=/citron/ccache -v "$(pwd):/citron" -w /citron yuzu-emu-mirror/build-environments:linux-fresh /bin/bash /citron/.ci/scripts/linux/docker.sh "$1"
|
||||
sudo chown -R $UID ./
|
67
.ci/scripts/linux/upload.sh
Executable file
67
.ci/scripts/linux/upload.sh
Executable file
|
@ -0,0 +1,67 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
. .ci/scripts/common/pre-upload.sh
|
||||
|
||||
APPIMAGE_NAME="citron-${RELEASE_NAME}-${GITDATE}-${GITREV}.AppImage"
|
||||
BASE_NAME="citron-linux"
|
||||
REV_NAME="${BASE_NAME}-${GITDATE}-${GITREV}"
|
||||
ARCHIVE_NAME="${REV_NAME}.tar.xz"
|
||||
COMPRESSION_FLAGS="-cJvf"
|
||||
|
||||
if [ "${RELEASE_NAME}" = "stable" ] || [ "${RELEASE_NAME}" = "canary" ]; then
|
||||
DIR_NAME="${BASE_NAME}-${RELEASE_NAME}"
|
||||
else
|
||||
DIR_NAME="${REV_NAME}-${RELEASE_NAME}"
|
||||
fi
|
||||
|
||||
mkdir "$DIR_NAME"
|
||||
|
||||
cp build/bin/citron-cmd "$DIR_NAME"
|
||||
if [ "${RELEASE_NAME}" != "canary" ] && [ "${RELEASE_NAME}" != "stable" ]; then
|
||||
cp build/bin/citron "$DIR_NAME"
|
||||
fi
|
||||
|
||||
# Build an AppImage
|
||||
cd build
|
||||
|
||||
wget -nc https://github.com/yuzu-emu-mirror/ext-linux-bin/raw/main/appimage/appimagetool-x86_64.AppImage || wget -nc https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
chmod 755 appimagetool-x86_64.AppImage
|
||||
|
||||
# if FUSE is not available, then fallback to extract and run
|
||||
if ! ./appimagetool-x86_64.AppImage --version; then
|
||||
export APPIMAGE_EXTRACT_AND_RUN=1
|
||||
fi
|
||||
|
||||
# Don't let AppImageLauncher ask to integrate EA
|
||||
if [ "${RELEASE_NAME}" = "stable" ] || [ "${RELEASE_NAME}" = "canary" ]; then
|
||||
echo "X-AppImage-Integrate=false" >> AppDir/org.citron_emu.citron.desktop
|
||||
fi
|
||||
|
||||
if [ "${RELEASE_NAME}" = "stable" ]; then
|
||||
# Generate update information if releasing to stable
|
||||
./appimagetool-x86_64.AppImage -u "gh-releases-zsync|Citron-Project|Cit|latest|citron-*.AppImage.zsync" AppDir "${APPIMAGE_NAME}"
|
||||
else
|
||||
./appimagetool-x86_64.AppImage AppDir "${APPIMAGE_NAME}"
|
||||
fi
|
||||
cd ..
|
||||
|
||||
# Copy the AppImage and update info to the artifacts directory and avoid compressing it
|
||||
cp "build/${APPIMAGE_NAME}" "${ARTIFACTS_DIR}/"
|
||||
if [ -f "build/${APPIMAGE_NAME}.zsync" ]; then
|
||||
cp "build/${APPIMAGE_NAME}.zsync" "${ARTIFACTS_DIR}/"
|
||||
fi
|
||||
|
||||
# Copy the AppImage to the general release directory and remove git revision info
|
||||
if [ "${RELEASE_NAME}" = "stable" ] || [ "${RELEASE_NAME}" = "canary" ]; then
|
||||
cp "build/${APPIMAGE_NAME}" "${DIR_NAME}/citron-${RELEASE_NAME}.AppImage"
|
||||
fi
|
||||
|
||||
# Copy debug symbols to artifacts
|
||||
cd build/bin
|
||||
tar $COMPRESSION_FLAGS "${ARTIFACTS_DIR}/${REV_NAME}-debug.tar.xz" *.debug
|
||||
cd -
|
||||
|
||||
. .ci/scripts/common/post-upload.sh
|
19
.ci/scripts/merge/apply-patches-by-label-private.py
Executable file
19
.ci/scripts/merge/apply-patches-by-label-private.py
Executable file
|
@ -0,0 +1,19 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# Apply patches that are tagged with a specific label
|
||||
# Current labels include:
|
||||
# "canary merge benefit"
|
||||
|
||||
import os
|
||||
import sys
|
||||
org = os.getenv("PRIVATEMERGEORG", "Citron-Project")
|
||||
base = os.getenv("PRIVATEMERGEBASE", "Cit")
|
||||
head = os.getenv("PRIVATEMERGEBASE", "Cit-canary")
|
||||
|
||||
# We use different files for the 3 PR checkers.
|
||||
check_label_presence_file = ".ci/scripts/merge/check-label-presence.py"
|
||||
check_reviews_file = ".ci/scripts/merge/check-reviews-private.py"
|
||||
|
||||
# python3 python_file org repo pr# label
|
||||
os.system(f"python3 .ci/scripts/merge/apply-patches-by-label.py {sys.argv[1]} {org} {base} {head} {check_label_presence_file} {check_reviews_file}")
|
60
.ci/scripts/merge/apply-patches-by-label.py
Executable file
60
.ci/scripts/merge/apply-patches-by-label.py
Executable file
|
@ -0,0 +1,60 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# Apply patches that are tagged with a specific label
|
||||
# Current labels include:
|
||||
# "canary merge benefit"
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import re
|
||||
from urllib import request
|
||||
|
||||
|
||||
def get_pull_request_list(page=1):
|
||||
url = f"https://api.github.com/repos/Citron-Project/Cit/pulls?page={page}"
|
||||
headers = {'Accept': 'application/vnd.github.v3+json'}
|
||||
token = os.environ.get('EARLY_ACCESS_TOKEN')
|
||||
if token:
|
||||
headers['Authorization'] = f'token {token}'
|
||||
req = request.Request(url, headers=headers)
|
||||
response = request.urlopen(req)
|
||||
result = json.loads(response.read().decode('utf-8'))
|
||||
if len(result) > 0:
|
||||
return result + get_pull_request_list(page + 1)
|
||||
return []
|
||||
|
||||
|
||||
seen = {}
|
||||
|
||||
for pr in get_pull_request_list():
|
||||
pn = pr['number']
|
||||
if pn in seen:
|
||||
continue
|
||||
seen[pn] = True
|
||||
print(subprocess.check_output(["git", "fetch", "https://github.com/Citron-Project/Cit.git", f"pull/{pn}/head:pr-{pn}", "-f", "--no-recurse-submodules"]))
|
||||
out = subprocess.check_output(["python3", ".ci/scripts/merge/check-label-presence.py", str(pn), sys.argv[1]])
|
||||
if b'true' in out:
|
||||
print(f'Applying PR #{pn} matching label {sys.argv[1]}...')
|
||||
try:
|
||||
if b'changes requested' in subprocess.check_output(["python3", ".ci/scripts/merge/check-reviews.py", str(pn)]):
|
||||
print(f'PR #{pn} has requested changes, skipping')
|
||||
continue
|
||||
else:
|
||||
print(f'PR #{pn} has approving reviews, applying')
|
||||
except:
|
||||
print('Could not find any valid reviews, applying anyway')
|
||||
try:
|
||||
print(subprocess.check_output(["git", "merge", "--squash", f"pr-{pn}", "-m", f"Merge PR #{pn} tagged with: {sys.argv[1]}"]))
|
||||
except:
|
||||
print("Failed to merge cleanly, are there conflicts?")
|
||||
exit(0)
|
||||
|
||||
# Apply a tag to the EA release
|
||||
try:
|
||||
print(subprocess.check_output(["git", "tag", "-f", f"canary/{sys.argv[1]}"]))
|
||||
except:
|
||||
print("Failed to apply canary tag")
|
||||
exit(0)
|
27
.ci/scripts/merge/check-label-presence.py
Executable file
27
.ci/scripts/merge/check-label-presence.py
Executable file
|
@ -0,0 +1,27 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# Check if a pull request has a specific label
|
||||
# Usage: python3 check-label-presence.py <PR Number> <Label Text>
|
||||
|
||||
import json, sys
|
||||
from urllib import request
|
||||
import os
|
||||
|
||||
url = 'https://api.github.com/repos/Citron-Project/Cit/issues/%s' % sys.argv[1]
|
||||
headers = {'Accept': 'application/vnd.github.v3+json'}
|
||||
token = os.environ.get('EARLY_ACCESS_TOKEN')
|
||||
if token:
|
||||
headers['Authorization'] = f'token {token}'
|
||||
req = request.Request(url, headers=headers)
|
||||
try:
|
||||
response = request.urlopen(req)
|
||||
j = json.loads(response.read().decode('utf-8'))
|
||||
for label in j['labels']:
|
||||
if label['name'] == sys.argv[2]:
|
||||
print('true')
|
||||
sys.exit(0)
|
||||
except Exception as e:
|
||||
print(f'Error: {e}')
|
||||
print('false')
|
||||
sys.exit(1)
|
5
.ci/scripts/merge/citronbot-git-config.sh
Executable file
5
.ci/scripts/merge/citronbot-git-config.sh
Executable file
|
@ -0,0 +1,5 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
git config --global user.email "zephyron@citron-emu.org"
|
||||
git config --global user.name "Zephyron"
|
19
.ci/scripts/transifex/docker.sh
Executable file
19
.ci/scripts/transifex/docker.sh
Executable file
|
@ -0,0 +1,19 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
# SPDX-FileCopyrightText: 2021 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
set -x
|
||||
|
||||
echo -e "\e[1m\e[33mBuild tools information:\e[0m"
|
||||
cmake --version
|
||||
gcc -v
|
||||
tx --version
|
||||
|
||||
mkdir build && cd build
|
||||
cmake .. -DENABLE_QT_TRANSLATION=ON -DGENERATE_QT_TRANSLATION=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_SDL2=OFF -DYUZU_TESTS=OFF -DYUZU_USE_BUNDLED_VCPKG=ON
|
||||
make translation
|
||||
cd ..
|
||||
|
||||
cd dist/languages
|
||||
tx push -s
|
66
.ci/scripts/windows/docker.sh
Executable file
66
.ci/scripts/windows/docker.sh
Executable file
|
@ -0,0 +1,66 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
set -e
|
||||
|
||||
#cd /citron
|
||||
|
||||
ccache -sv
|
||||
|
||||
mkdir -p build && cd build
|
||||
cmake .. \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_TOOLCHAIN_FILE="${PWD}/../CMakeModules/MinGWCross.cmake" \
|
||||
-DDISPLAY_VERSION="$1" \
|
||||
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
|
||||
-DENABLE_QT_TRANSLATION=ON \
|
||||
-DUSE_CCACHE=ON \
|
||||
-DYUZU_USE_BUNDLED_SDL2=OFF \
|
||||
-DYUZU_USE_EXTERNAL_SDL2=OFF \
|
||||
-DYUZU_TESTS=OFF \
|
||||
-GNinja
|
||||
ninja citron citron-cmd
|
||||
|
||||
ccache -sv
|
||||
|
||||
echo "Tests skipped"
|
||||
#ctest -VV -C Release
|
||||
|
||||
echo 'Prepare binaries...'
|
||||
cd ..
|
||||
mkdir package
|
||||
|
||||
if [ -d "/usr/x86_64-w64-mingw32/lib/qt5/plugins/platforms/" ]; then
|
||||
QT_PLUGINS_PATH='/usr/x86_64-w64-mingw32/lib/qt5/plugins'
|
||||
else
|
||||
#fallback to qt
|
||||
QT_PLUGINS_PATH='/usr/x86_64-w64-mingw32/lib/qt/plugins'
|
||||
fi
|
||||
|
||||
find build/ -name "citron*.exe" -exec cp {} 'package' \;
|
||||
|
||||
# copy Qt plugins
|
||||
mkdir package/platforms
|
||||
cp -v "${QT_PLUGINS_PATH}/platforms/qwindows.dll" package/platforms/
|
||||
cp -rv "${QT_PLUGINS_PATH}/mediaservice/" package/
|
||||
cp -rv "${QT_PLUGINS_PATH}/imageformats/" package/
|
||||
cp -rv "${QT_PLUGINS_PATH}/styles/" package/
|
||||
rm -f package/mediaservice/*d.dll
|
||||
|
||||
for i in package/*.exe; do
|
||||
# we need to process pdb here, however, cv2pdb
|
||||
# does not work here, so we just simply strip all the debug symbols
|
||||
x86_64-w64-mingw32-strip "${i}"
|
||||
done
|
||||
|
||||
python3 .ci/scripts/windows/scan_dll.py package/*.exe package/imageformats/*.dll "package/"
|
||||
|
||||
# copy FFmpeg libraries
|
||||
EXTERNALS_PATH="$(pwd)/build/externals"
|
||||
FFMPEG_DLL_PATH="$(find "${EXTERNALS_PATH}" -maxdepth 1 -type d | grep 'ffmpeg-')/bin"
|
||||
find ${FFMPEG_DLL_PATH} -type f -regex ".*\.dll" -exec cp -nv {} package/ ';'
|
||||
|
||||
# copy libraries from citron.exe path
|
||||
find "$(pwd)/build/bin/" -type f -regex ".*\.dll" -exec cp -v {} package/ ';'
|
11
.ci/scripts/windows/exec.sh
Executable file
11
.ci/scripts/windows/exec.sh
Executable file
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
mkdir -p "ccache" || true
|
||||
chmod a+x ./.ci/scripts/windows/docker.sh
|
||||
# the UID for the container citron user is 1027
|
||||
sudo chown -R 1027 ./
|
||||
docker run -e CCACHE_DIR=/citron/ccache -v "$(pwd):/citron" -w /citron yuzu-emu-mirror/build-environments:linux-mingw /bin/bash -ex /citron/.ci/scripts/windows/docker.sh "$1"
|
||||
sudo chown -R $UID ./
|
33
.ci/scripts/windows/install-vulkan-sdk.ps1
Executable file
33
.ci/scripts/windows/install-vulkan-sdk.ps1
Executable file
|
@ -0,0 +1,33 @@
|
|||
# SPDX-FileCopyrightText: 2023 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$VulkanSDKVer = "1.3.250.1"
|
||||
$ExeFile = "VulkanSDK-$VulkanSDKVer-Installer.exe"
|
||||
$Uri = "https://sdk.lunarg.com/sdk/download/$VulkanSDKVer/windows/$ExeFile"
|
||||
$Destination = "./$ExeFile"
|
||||
|
||||
echo "Downloading Vulkan SDK $VulkanSDKVer from $Uri"
|
||||
$WebClient = New-Object System.Net.WebClient
|
||||
$WebClient.DownloadFile($Uri, $Destination)
|
||||
echo "Finished downloading $ExeFile"
|
||||
|
||||
$VULKAN_SDK = "C:/VulkanSDK/$VulkanSDKVer"
|
||||
$Arguments = "--root `"$VULKAN_SDK`" --accept-licenses --default-answer --confirm-command install"
|
||||
|
||||
echo "Installing Vulkan SDK $VulkanSDKVer"
|
||||
$InstallProcess = Start-Process -FilePath $Destination -NoNewWindow -PassThru -Wait -ArgumentList $Arguments
|
||||
$ExitCode = $InstallProcess.ExitCode
|
||||
|
||||
if ($ExitCode -ne 0) {
|
||||
echo "Error installing Vulkan SDK $VulkanSDKVer (Error: $ExitCode)"
|
||||
Exit $ExitCode
|
||||
}
|
||||
|
||||
echo "Finished installing Vulkan SDK $VulkanSDKVer"
|
||||
|
||||
if ("$env:GITHUB_ACTIONS" -eq "true") {
|
||||
echo "VULKAN_SDK=$VULKAN_SDK" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
echo "$VULKAN_SDK/Bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
}
|
109
.ci/scripts/windows/scan_dll.py
Executable file
109
.ci/scripts/windows/scan_dll.py
Executable file
|
@ -0,0 +1,109 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import pefile
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
import queue
|
||||
import shutil
|
||||
|
||||
# constant definitions
|
||||
KNOWN_SYS_DLLS = ['WINMM.DLL', 'MSVCRT.DLL', 'VERSION.DLL', 'MPR.DLL',
|
||||
'DWMAPI.DLL', 'UXTHEME.DLL', 'DNSAPI.DLL', 'IPHLPAPI.DLL']
|
||||
# below is for Ubuntu 18.04 with specified PPA enabled, if you are using
|
||||
# other distro or different repositories, change the following accordingly
|
||||
DLL_PATH = [
|
||||
'/usr/x86_64-w64-mingw32/bin/',
|
||||
'/usr/x86_64-w64-mingw32/lib/',
|
||||
'/usr/lib/gcc/x86_64-w64-mingw32/7.3-posix/'
|
||||
]
|
||||
|
||||
missing = []
|
||||
|
||||
|
||||
def parse_imports(file_name):
|
||||
results = []
|
||||
pe = pefile.PE(file_name, fast_load=True)
|
||||
pe.parse_data_directories()
|
||||
|
||||
for entry in pe.DIRECTORY_ENTRY_IMPORT:
|
||||
current = entry.dll.decode()
|
||||
current_u = current.upper() # b/c Windows is often case insensitive
|
||||
# here we filter out system dlls
|
||||
# dll w/ names like *32.dll are likely to be system dlls
|
||||
if current_u.upper() not in KNOWN_SYS_DLLS and not re.match(string=current_u, pattern=r'.*32\.DLL'):
|
||||
results.append(current)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def parse_imports_recursive(file_name, path_list=[]):
|
||||
q = queue.Queue() # create a FIFO queue
|
||||
# file_name can be a string or a list for the convenience
|
||||
if isinstance(file_name, str):
|
||||
q.put(file_name)
|
||||
elif isinstance(file_name, list):
|
||||
for i in file_name:
|
||||
q.put(i)
|
||||
full_list = []
|
||||
while q.qsize():
|
||||
current = q.get_nowait()
|
||||
print('> %s' % current)
|
||||
deps = parse_imports(current)
|
||||
# if this dll does not have any import, ignore it
|
||||
if not deps:
|
||||
continue
|
||||
for dep in deps:
|
||||
# the dependency already included in the list, skip
|
||||
if dep in full_list:
|
||||
continue
|
||||
# find the requested dll in the provided paths
|
||||
full_path = find_dll(dep)
|
||||
if not full_path:
|
||||
missing.append(dep)
|
||||
continue
|
||||
full_list.append(dep)
|
||||
q.put(full_path)
|
||||
path_list.append(full_path)
|
||||
return full_list
|
||||
|
||||
|
||||
def find_dll(name):
|
||||
for path in DLL_PATH:
|
||||
for root, _, files in os.walk(path):
|
||||
for f in files:
|
||||
if name.lower() == f.lower():
|
||||
return os.path.join(root, f)
|
||||
|
||||
|
||||
def deploy(name, dst, dry_run=False):
|
||||
dlls_path = []
|
||||
parse_imports_recursive(name, dlls_path)
|
||||
for dll_entry in dlls_path:
|
||||
if not dry_run:
|
||||
shutil.copy(dll_entry, dst)
|
||||
else:
|
||||
print('[Dry-Run] Copy %s to %s' % (dll_entry, dst))
|
||||
print('Deploy completed.')
|
||||
return dlls_path
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 3:
|
||||
print('Usage: %s [files to examine ...] [target deploy directory]')
|
||||
return 1
|
||||
to_deploy = sys.argv[1:-1]
|
||||
tgt_dir = sys.argv[-1]
|
||||
if not os.path.isdir(tgt_dir):
|
||||
print('%s is not a directory.' % tgt_dir)
|
||||
return 1
|
||||
print('Scanning dependencies...')
|
||||
deploy(to_deploy, tgt_dir)
|
||||
if missing:
|
||||
print('Following DLLs are not found: %s' % ('\n'.join(missing)))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
118
.ci/scripts/windows/upload.ps1
Executable file
118
.ci/scripts/windows/upload.ps1
Executable file
|
@ -0,0 +1,118 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
param($BUILD_NAME)
|
||||
|
||||
$GITDATE = $(git show -s --date=short --format='%ad') -replace "-", ""
|
||||
$GITREV = $(git show -s --format='%h')
|
||||
|
||||
if ("$BUILD_NAME" -eq "stable") {
|
||||
$RELEASE_DIST = "citron-stable-msvc"
|
||||
}
|
||||
else {
|
||||
$RELEASE_DIST = "citron-windows-msvc-$BUILD_NAME"
|
||||
}
|
||||
|
||||
$MSVC_BUILD_ZIP = "citron-windows-msvc-$GITDATE-$GITREV.zip" -replace " ", ""
|
||||
$MSVC_BUILD_PDB = "citron-windows-msvc-$GITDATE-$GITREV-debugsymbols.zip" -replace " ", ""
|
||||
$MSVC_SEVENZIP = "citron-windows-msvc-$GITDATE-$GITREV.7z" -replace " ", ""
|
||||
$MSVC_TAR = "citron-windows-msvc-$GITDATE-$GITREV.tar" -replace " ", ""
|
||||
$MSVC_TARXZ = "citron-windows-msvc-$GITDATE-$GITREV.tar.xz" -replace " ", ""
|
||||
$MSVC_SOURCE = "citron-windows-msvc-source-$GITDATE-$GITREV" -replace " ", ""
|
||||
$MSVC_SOURCE_TAR = "$MSVC_SOURCE.tar"
|
||||
$MSVC_SOURCE_TARXZ = "$MSVC_SOURCE_TAR.xz"
|
||||
|
||||
$env:BUILD_ZIP = $MSVC_BUILD_ZIP
|
||||
$env:BUILD_SYMBOLS = $MSVC_BUILD_PDB
|
||||
$env:BUILD_UPDATE = $MSVC_SEVENZIP
|
||||
|
||||
if (Test-Path -Path ".\build\bin\Release") {
|
||||
$BUILD_DIR = ".\build\bin\Release"
|
||||
} else {
|
||||
$BUILD_DIR = ".\build\bin\"
|
||||
}
|
||||
|
||||
# Cleanup unneeded data in submodules
|
||||
git submodule foreach git clean -fxd
|
||||
|
||||
# Upload debugging symbols
|
||||
mkdir pdb
|
||||
Get-ChildItem "$BUILD_DIR\" -Recurse -Filter "*.pdb" | Copy-Item -destination .\pdb
|
||||
7z a -tzip $MSVC_BUILD_PDB .\pdb\*.pdb
|
||||
rm "$BUILD_DIR\*.pdb"
|
||||
|
||||
# Create artifact directories
|
||||
mkdir $RELEASE_DIST
|
||||
mkdir $MSVC_SOURCE
|
||||
mkdir "artifacts"
|
||||
|
||||
$CURRENT_DIR = Convert-Path .
|
||||
|
||||
# Build a tar.xz for the source of the release
|
||||
git clone --depth 1 file://$CURRENT_DIR $MSVC_SOURCE
|
||||
7z a -r -ttar $MSVC_SOURCE_TAR $MSVC_SOURCE
|
||||
7z a -r -txz $MSVC_SOURCE_TARXZ $MSVC_SOURCE_TAR
|
||||
|
||||
# Following section is quick hack to package artifacts differently for GitHub Actions
|
||||
if ("$env:GITHUB_ACTIONS" -eq "true") {
|
||||
echo "Hello GitHub Actions"
|
||||
|
||||
# With vcpkg we now have a few more dll files
|
||||
ls .\build\bin\*.dll
|
||||
cp .\build\bin\*.dll .\artifacts\
|
||||
|
||||
# Hopefully there is an exe in either .\build\bin or .\build\bin\Release
|
||||
cp .\build\bin\citron*.exe .\artifacts\
|
||||
Copy-Item "$BUILD_DIR\*" -Destination "artifacts" -Recurse
|
||||
Remove-Item .\artifacts\tests.exe -ErrorAction ignore
|
||||
|
||||
# None of the other GHA builds are including source, so commenting out today
|
||||
#Copy-Item $MSVC_SOURCE_TARXZ -Destination "artifacts"
|
||||
|
||||
# Debugging symbols
|
||||
cp .\build\bin\citron*.pdb .\artifacts\
|
||||
|
||||
# Write out a tag BUILD_TAG to environment for the Upload step
|
||||
# We're getting ${{ github.event.number }} as $env:PR_NUMBER"
|
||||
echo "env:PR_NUMBER: $env:PR_NUMBER"
|
||||
if (Test-Path env:PR_NUMBER) {
|
||||
$PR_NUMBER = $env:PR_NUMBER.Substring(2) -as [int]
|
||||
$PR_NUMBER_TAG = "pr"+([string]$PR_NUMBER).PadLeft(5,'0')
|
||||
if ($PR_NUMBER -gt 1){
|
||||
$BUILD_TAG="verify-$PR_NUMBER_TAG-$GITDATE-$GITREV"
|
||||
} else {
|
||||
$BUILD_TAG = "verify-$GITDATE-$GITREV"
|
||||
}
|
||||
} else {
|
||||
# If env:PR_NUMBER isn't set, we should still write out a variable
|
||||
$BUILD_TAG = "verify-$GITDATE-$GITREV"
|
||||
}
|
||||
echo "BUILD_TAG=$BUILD_TAG"
|
||||
echo "BUILD_TAG=$BUILD_TAG" >> $env:GITHUB_ENV
|
||||
|
||||
# For extra job, just the exe
|
||||
$INDIVIDUAL_EXE = "citron-msvc-$BUILD_TAG.exe"
|
||||
echo "INDIVIDUAL_EXE=$INDIVIDUAL_EXE"
|
||||
echo "INDIVIDUAL_EXE=$INDIVIDUAL_EXE" >> $env:GITHUB_ENV
|
||||
echo "Just the exe: $INDIVIDUAL_EXE"
|
||||
cp .\artifacts\citron.exe .\$INDIVIDUAL_EXE
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
# Build the final release artifacts
|
||||
Copy-Item $MSVC_SOURCE_TARXZ -Destination $RELEASE_DIST
|
||||
Copy-Item "$BUILD_DIR\*" -Destination $RELEASE_DIST -Recurse
|
||||
rm "$RELEASE_DIST\*.exe"
|
||||
Get-ChildItem "$BUILD_DIR" -Recurse -Filter "citron*.exe" | Copy-Item -destination $RELEASE_DIST
|
||||
Get-ChildItem "$BUILD_DIR" -Recurse -Filter "QtWebEngineProcess*.exe" | Copy-Item -destination $RELEASE_DIST
|
||||
7z a -tzip $MSVC_BUILD_ZIP $RELEASE_DIST\*
|
||||
7z a $MSVC_SEVENZIP $RELEASE_DIST
|
||||
|
||||
7z a -r -ttar $MSVC_TAR $RELEASE_DIST
|
||||
7z a -r -txz $MSVC_TARXZ $MSVC_TAR
|
||||
|
||||
Get-ChildItem . -Filter "*.zip" | Copy-Item -destination "artifacts"
|
||||
Get-ChildItem . -Filter "*.7z" | Copy-Item -destination "artifacts"
|
||||
Get-ChildItem . -Filter "*.tar.xz" | Copy-Item -destination "artifacts"
|
||||
}
|
28
.ci/scripts/windows/upload.sh
Executable file
28
.ci/scripts/windows/upload.sh
Executable file
|
@ -0,0 +1,28 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
. .ci/scripts/common/pre-upload.sh
|
||||
|
||||
REV_NAME="citron-windows-${GITDATE}-${GITREV}"
|
||||
ARCHIVE_NAME="${REV_NAME}.tar.xz"
|
||||
COMPRESSION_FLAGS="-cJvf"
|
||||
|
||||
if [ "${RELEASE_NAME}" = "stable" ]; then
|
||||
DIR_NAME="${REV_NAME}"
|
||||
else
|
||||
DIR_NAME="${REV_NAME}_${RELEASE_NAME}"
|
||||
fi
|
||||
|
||||
mkdir "$DIR_NAME"
|
||||
# get around the permission issues
|
||||
cp -r package/* "$DIR_NAME"
|
||||
|
||||
if [ "${RELEASE_NAME}" = "stable" ]; then
|
||||
MSVC_BUILD_ZIP="citron-stable-msvc.zip"
|
||||
else
|
||||
MSVC_BUILD_ZIP="${REV_NAME}-msvc.zip"
|
||||
fi
|
||||
|
||||
. .ci/scripts/common/post-upload.sh
|
8
.ci/templates/build-mock.yml
Executable file
8
.ci/templates/build-mock.yml
Executable file
|
@ -0,0 +1,8 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
steps:
|
||||
- script: mkdir artifacts || echo 'X' > artifacts/T1.txt
|
||||
- publish: artifacts
|
||||
artifact: 'citron-$(BuildName)-mock'
|
||||
displayName: 'Upload Artifacts'
|
31
.ci/templates/build-msvc.yml
Executable file
31
.ci/templates/build-msvc.yml
Executable file
|
@ -0,0 +1,31 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
parameters:
|
||||
artifactSource: 'true'
|
||||
cache: 'false'
|
||||
version: ''
|
||||
|
||||
steps:
|
||||
- task: Powershell@2
|
||||
displayName: 'Install Vulkan SDK'
|
||||
inputs:
|
||||
targetType: 'filePath'
|
||||
filePath: './.ci/scripts/windows/install-vulkan-sdk.ps1'
|
||||
- script: refreshenv && glslangValidator --version && mkdir build && cd build && cmake -E env CXXFLAGS="/Gw" cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_POLICY_DEFAULT_CMP0069=NEW -DCITRON_ENABLE_LTO=ON -DCITRON_USE_BUNDLED_QT=1 -DCITRON_USE_BUNDLED_SDL2=1 -DCITRON_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DCITRON_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DCITRON_TESTS=OFF -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DDISPLAY_VERSION=${{ parameters['version'] }} -DCMAKE_BUILD_TYPE=Release -DCITRON_CRASH_DUMPS=ON .. && cd ..
|
||||
displayName: 'Configure CMake'
|
||||
- task: MSBuild@1
|
||||
displayName: 'Build'
|
||||
inputs:
|
||||
solution: 'build/citron.sln'
|
||||
maximumCpuCount: true
|
||||
configuration: release
|
||||
- task: PowerShell@2
|
||||
displayName: 'Package Artifacts'
|
||||
inputs:
|
||||
targetType: 'filePath'
|
||||
filePath: './.ci/scripts/windows/upload.ps1'
|
||||
arguments: '$(BuildName)'
|
||||
- publish: artifacts
|
||||
artifact: 'citron-$(BuildName)-windows-msvc'
|
||||
displayName: 'Upload Artifacts'
|
26
.ci/templates/build-single.yml
Executable file
26
.ci/templates/build-single.yml
Executable file
|
@ -0,0 +1,26 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
parameters:
|
||||
artifactSource: 'true'
|
||||
cache: 'false'
|
||||
version: ''
|
||||
|
||||
steps:
|
||||
- task: DockerInstaller@0
|
||||
displayName: 'Prepare Environment'
|
||||
inputs:
|
||||
dockerVersion: '17.09.0-ce'
|
||||
- task: CacheBeta@0
|
||||
displayName: 'Cache Build System'
|
||||
inputs:
|
||||
key: citron-v1-$(BuildName)-$(BuildSuffix)-$(CacheSuffix)
|
||||
path: $(System.DefaultWorkingDirectory)/ccache
|
||||
cacheHitVar: CACHE_RESTORED
|
||||
- script: chmod a+x ./.ci/scripts/$(ScriptFolder)/exec.sh && ./.ci/scripts/$(ScriptFolder)/exec.sh ${{ parameters['version'] }}
|
||||
displayName: 'Build'
|
||||
- script: chmod a+x ./.ci/scripts/$(ScriptFolder)/upload.sh && RELEASE_NAME=$(BuildName) ./.ci/scripts/$(ScriptFolder)/upload.sh
|
||||
displayName: 'Package Artifacts'
|
||||
- publish: artifacts
|
||||
artifact: 'citron-$(BuildName)-$(BuildSuffix)'
|
||||
displayName: 'Upload Artifacts'
|
33
.ci/templates/build-standard.yml
Executable file
33
.ci/templates/build-standard.yml
Executable file
|
@ -0,0 +1,33 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
parameters:
|
||||
version: ''
|
||||
|
||||
jobs:
|
||||
- job: build
|
||||
displayName: 'standard'
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
strategy:
|
||||
maxParallel: 10
|
||||
matrix:
|
||||
windows:
|
||||
BuildSuffix: 'windows-mingw'
|
||||
ScriptFolder: 'windows'
|
||||
clang:
|
||||
BuildSuffix: 'clang'
|
||||
ScriptFolder: 'clang'
|
||||
linux:
|
||||
BuildSuffix: 'linux'
|
||||
ScriptFolder: 'linux'
|
||||
steps:
|
||||
- template: ./sync-source.yml
|
||||
parameters:
|
||||
artifactSource: $(parameters.artifactSource)
|
||||
needSubmodules: 'true'
|
||||
- template: ./build-single.yml
|
||||
parameters:
|
||||
artifactSource: 'false'
|
||||
cache: $(parameters.cache)
|
||||
version: $(parameters.version)
|
40
.ci/templates/build-testing.yml
Executable file
40
.ci/templates/build-testing.yml
Executable file
|
@ -0,0 +1,40 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
parameters:
|
||||
version: ''
|
||||
|
||||
jobs:
|
||||
- job: build_test
|
||||
displayName: 'testing'
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
strategy:
|
||||
maxParallel: 5
|
||||
matrix:
|
||||
windows:
|
||||
BuildSuffix: 'windows-testing'
|
||||
ScriptFolder: 'windows'
|
||||
steps:
|
||||
- script: sudo apt-get update && sudo apt-get --only-upgrade -y install python3-pip && pip install requests urllib3
|
||||
displayName: 'Prepare Environment'
|
||||
- task: PythonScript@0
|
||||
condition: eq(variables['Build.Reason'], 'PullRequest')
|
||||
displayName: 'Determine Testing Status'
|
||||
inputs:
|
||||
scriptSource: 'filePath'
|
||||
scriptPath: '.ci/scripts/merge/check-label-presence.py'
|
||||
arguments: '$(System.PullRequest.PullRequestNumber) create-testing-build'
|
||||
- ${{ if eq(variables.enabletesting, 'true') }}:
|
||||
- template: ./sync-source.yml
|
||||
parameters:
|
||||
artifactSource: $(parameters.artifactSource)
|
||||
needSubmodules: 'true'
|
||||
- template: ./mergebot.yml
|
||||
parameters:
|
||||
matchLabel: 'testing-merge'
|
||||
- template: ./build-single.yml
|
||||
parameters:
|
||||
artifactSource: 'false'
|
||||
cache: 'false'
|
||||
version: $(parameters.version)
|
17
.ci/templates/format-check.yml
Executable file
17
.ci/templates/format-check.yml
Executable file
|
@ -0,0 +1,17 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
parameters:
|
||||
artifactSource: 'true'
|
||||
|
||||
steps:
|
||||
- template: ./sync-source.yml
|
||||
parameters:
|
||||
artifactSource: $(parameters.artifactSource)
|
||||
needSubmodules: 'false'
|
||||
- task: DockerInstaller@0
|
||||
displayName: 'Prepare Environment'
|
||||
inputs:
|
||||
dockerVersion: '17.09.0-ce'
|
||||
- script: chmod a+x ./.ci/scripts/format/exec.sh && ./.ci/scripts/format/exec.sh
|
||||
displayName: 'Verify Formatting'
|
44
.ci/templates/merge-private.yml
Executable file
44
.ci/templates/merge-private.yml
Executable file
|
@ -0,0 +1,44 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
jobs:
|
||||
- job: merge
|
||||
displayName: 'pull requests'
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- checkout: self
|
||||
submodules: recursive
|
||||
- template: ./mergebot-private.yml
|
||||
parameters:
|
||||
matchLabel: '$(BuildName)-merge'
|
||||
matchLabelPublic: '$(PublicBuildName)-merge'
|
||||
- task: ArchiveFiles@2
|
||||
displayName: 'Package Source'
|
||||
inputs:
|
||||
rootFolderOrFile: '$(System.DefaultWorkingDirectory)'
|
||||
includeRootFolder: false
|
||||
archiveType: '7z'
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/citron-$(BuildName)-source.7z'
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: 'Upload Artifacts'
|
||||
inputs:
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)/citron-$(BuildName)-source.7z'
|
||||
artifact: 'citron-$(BuildName)-source'
|
||||
replaceExistingArchive: true
|
||||
- job: upload_source
|
||||
displayName: 'upload'
|
||||
dependsOn: merge
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- template: ./sync-source.yml
|
||||
parameters:
|
||||
artifactSource: 'true'
|
||||
needSubmodules: 'true'
|
||||
- script: chmod a+x $(System.DefaultWorkingDirectory)/.ci/scripts/merge/citronbot-git-config.sh && $(System.DefaultWorkingDirectory)/.ci/scripts/merge/citronbot-git-config.sh
|
||||
displayName: 'Apply Git Configuration'
|
||||
- script: git remote add other $(GitRepoPushChangesURL)
|
||||
displayName: 'Register Repository'
|
||||
- script: git push --force other HEAD:$(GitPushBranch)
|
||||
displayName: 'Update Code'
|
43
.ci/templates/merge.yml
Executable file
43
.ci/templates/merge.yml
Executable file
|
@ -0,0 +1,43 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
jobs:
|
||||
- job: merge
|
||||
displayName: 'pull requests'
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- checkout: self
|
||||
submodules: recursive
|
||||
- template: ./mergebot.yml
|
||||
parameters:
|
||||
matchLabel: '$(BuildName)-merge'
|
||||
- task: ArchiveFiles@2
|
||||
displayName: 'Package Source'
|
||||
inputs:
|
||||
rootFolderOrFile: '$(System.DefaultWorkingDirectory)'
|
||||
includeRootFolder: false
|
||||
archiveType: '7z'
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/citron-$(BuildName)-source.7z'
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: 'Upload Artifacts'
|
||||
inputs:
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)/citron-$(BuildName)-source.7z'
|
||||
artifact: 'citron-$(BuildName)-source'
|
||||
replaceExistingArchive: true
|
||||
- job: upload_source
|
||||
displayName: 'upload'
|
||||
dependsOn: merge
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- template: ./sync-source.yml
|
||||
parameters:
|
||||
artifactSource: 'true'
|
||||
needSubmodules: 'true'
|
||||
- script: chmod a+x $(System.DefaultWorkingDirectory)/.ci/scripts/merge/citronbot-git-config.sh && $(System.DefaultWorkingDirectory)/.ci/scripts/merge/citronbot-git-config.sh
|
||||
displayName: 'Apply Git Configuration'
|
||||
- script: git remote add other $(GitRepoPushChangesURL)
|
||||
displayName: 'Register Repository'
|
||||
- script: git push --force other HEAD:$(GitPushBranch)
|
||||
displayName: 'Update Code'
|
41
.ci/templates/mergebot-private.yml
Executable file
41
.ci/templates/mergebot-private.yml
Executable file
|
@ -0,0 +1,41 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
parameters:
|
||||
matchLabel: 'dummy-merge'
|
||||
matchLabelPublic: 'dummy-merge'
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
fetchDepth: 1
|
||||
submodules: false
|
||||
- task: PythonScript@0
|
||||
displayName: 'Generate Merge Config'
|
||||
inputs:
|
||||
scriptSource: 'inline'
|
||||
script: '${{ parameters.createMergeConfigScript }}'
|
||||
- task: PythonScript@0
|
||||
displayName: 'Discover, Download, and Apply Patches (Stable)'
|
||||
inputs:
|
||||
scriptSource: 'filePath'
|
||||
scriptPath: '.ci/scripts/merge/apply-patches-by-label-private.py'
|
||||
arguments: $(publicLabel)
|
||||
workingDirectory: '$(Build.SourcesDirectory)'
|
||||
- task: PythonScript@0
|
||||
displayName: 'Discover, Download, and Apply Patches (Canary Public)'
|
||||
inputs:
|
||||
scriptSource: 'filePath'
|
||||
scriptPath: '.ci/scripts/merge/apply-patches-by-label-private.py'
|
||||
arguments: $(supporterPublicLabel)
|
||||
workingDirectory: '$(Build.SourcesDirectory)'
|
||||
- task: PythonScript@0
|
||||
displayName: 'Discover, Download, and Apply Patches (Canary Private)'
|
||||
inputs:
|
||||
scriptSource: 'filePath'
|
||||
scriptPath: '.ci/scripts/merge/apply-patches-by-label-private.py'
|
||||
arguments: $(supporterPrivateLabel)
|
||||
workingDirectory: '$(Build.SourcesDirectory)'
|
||||
- script: |
|
||||
echo '##vso[task.setvariable variable=DisplayPrefix]$(tagPrefix)'
|
||||
git rev-parse HEAD
|
||||
displayName: 'Set Version Number'
|
18
.ci/templates/mergebot.yml
Executable file
18
.ci/templates/mergebot.yml
Executable file
|
@ -0,0 +1,18 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
parameters:
|
||||
matchLabel: 'dummy-merge'
|
||||
|
||||
steps:
|
||||
- script: mkdir $(System.DefaultWorkingDirectory)/patches && pip install requests urllib3
|
||||
displayName: 'Prepare Environment'
|
||||
- script: chmod a+x $(System.DefaultWorkingDirectory)/.ci/scripts/merge/citronbot-git-config.sh && $(System.DefaultWorkingDirectory)/.ci/scripts/merge/citronbot-git-config.sh
|
||||
displayName: 'Apply Git Configuration'
|
||||
- task: PythonScript@0
|
||||
displayName: 'Discover, Download, and Apply Patches'
|
||||
inputs:
|
||||
scriptSource: 'filePath'
|
||||
scriptPath: '.ci/scripts/merge/apply-patches-by-label.py'
|
||||
arguments: '${{ parameters.matchLabel }} Tagged patches'
|
||||
workingDirectory: '$(System.DefaultWorkingDirectory)'
|
22
.ci/templates/release-download.yml
Executable file
22
.ci/templates/release-download.yml
Executable file
|
@ -0,0 +1,22 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
steps:
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: 'Download Windows Release'
|
||||
inputs:
|
||||
artifactName: 'citron-$(BuildName)-windows-msvc'
|
||||
buildType: 'current'
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)'
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: 'Download Linux Release'
|
||||
inputs:
|
||||
artifactName: 'citron-$(BuildName)-linux'
|
||||
buildType: 'current'
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)'
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: 'Download Android Release'
|
||||
inputs:
|
||||
artifactName: 'citron-$(BuildName)-android'
|
||||
buildType: 'current'
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)'
|
18
.ci/templates/release-github.yml
Executable file
18
.ci/templates/release-github.yml
Executable file
|
@ -0,0 +1,18 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
steps:
|
||||
- template: ./release-download.yml
|
||||
- task: GitHubRelease@0
|
||||
displayName: 'GitHub Release'
|
||||
inputs:
|
||||
action: 'create'
|
||||
title: '$(ReleasePrefix) $(DisplayVersion)'
|
||||
assets: '$(Build.ArtifactStagingDirectory)/*'
|
||||
gitHubConnection: CI_RELEASE_TOKEN
|
||||
repositoryName: 'Citron-Project/Cit'
|
||||
target: '$(Build.SourceVersion)'
|
||||
tagSource: manual
|
||||
tag: $(BuildName)-$(DisplayPrefix)-$(DisplayVersion)
|
||||
addChangeLog: true
|
||||
isDraft: false
|
12
.ci/templates/release-private-tag.yml
Executable file
12
.ci/templates/release-private-tag.yml
Executable file
|
@ -0,0 +1,12 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
steps:
|
||||
- script: chmod a+x $(System.DefaultWorkingDirectory)/.ci/scripts/merge/citronbot-git-config.sh && $(System.DefaultWorkingDirectory)/.ci/scripts/merge/citronbot-git-config.sh
|
||||
displayName: 'Apply Git Configuration'
|
||||
- script: git tag -a $(BuildName)-$(DisplayPrefix)-$(DisplayVersion) -m "citron $(BuildName) $(Build.BuildNumber) $(Build.DefinitionName) $(DisplayPrefix)-$(DisplayVersion)"
|
||||
displayName: 'Tag Source'
|
||||
- script: git remote add other $(GitRepoPushChangesURL)
|
||||
displayName: 'Register Repository'
|
||||
- script: git push other $(BuildName)-$(DisplayPrefix)-$(DisplayVersion)
|
||||
displayName: 'Update Code'
|
13
.ci/templates/release-universal.yml
Executable file
13
.ci/templates/release-universal.yml
Executable file
|
@ -0,0 +1,13 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
steps:
|
||||
- template: ./release-download.yml
|
||||
- task: UniversalPackages@0
|
||||
displayName: Publish Artifacts
|
||||
inputs:
|
||||
command: publish
|
||||
publishDirectory: '$(Build.ArtifactStagingDirectory)'
|
||||
vstsFeedPublish: 'citron-$(BuildName)'
|
||||
vstsFeedPackagePublish: 'main'
|
||||
packagePublishDescription: 'Citron Windows and Linux Executable Packages'
|
19
.ci/templates/retrieve-artifact-source.yml
Executable file
19
.ci/templates/retrieve-artifact-source.yml
Executable file
|
@ -0,0 +1,19 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
steps:
|
||||
- checkout: none
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: 'Download Source'
|
||||
inputs:
|
||||
artifactName: 'citron-$(BuildName)-source'
|
||||
buildType: 'current'
|
||||
targetPath: '$(Build.ArtifactStagingDirectory)'
|
||||
- script: rm -rf $(System.DefaultWorkingDirectory) && mkdir $(System.DefaultWorkingDirectory)
|
||||
displayName: 'Clean Working Directory'
|
||||
- task: ExtractFiles@1
|
||||
displayName: 'Prepare Source'
|
||||
inputs:
|
||||
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/*.7z'
|
||||
destinationFolder: '$(System.DefaultWorkingDirectory)'
|
||||
cleanDestinationFolder: false
|
14
.ci/templates/retrieve-master-source.yml
Executable file
14
.ci/templates/retrieve-master-source.yml
Executable file
|
@ -0,0 +1,14 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
parameters:
|
||||
needSubmodules: 'true'
|
||||
|
||||
steps:
|
||||
- checkout: self
|
||||
displayName: 'Checkout Recursive'
|
||||
submodules: recursive
|
||||
# condition: eq(parameters.needSubmodules, 'true')
|
||||
#- checkout: self
|
||||
# displayName: 'Checkout Fast'
|
||||
# condition: ne(parameters.needSubmodules, 'true')
|
10
.ci/templates/sync-source.yml
Executable file
10
.ci/templates/sync-source.yml
Executable file
|
@ -0,0 +1,10 @@
|
|||
# SPDX-FileCopyrightText: 2019 citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
steps:
|
||||
- ${{ if eq(parameters.artifactSource, 'true') }}:
|
||||
- template: ./retrieve-artifact-source.yml
|
||||
- ${{ if ne(parameters.artifactSource, 'true') }}:
|
||||
- template: ./retrieve-master-source.yml
|
||||
parameters:
|
||||
needSubmodules: $(parameters.needSubmodules)
|
10
.github/ISSUE_TEMPLATE/blank_issue_template.yml
vendored
Executable file
10
.github/ISSUE_TEMPLATE/blank_issue_template.yml
vendored
Executable file
|
@ -0,0 +1,10 @@
|
|||
name: New Issue (Developers Only)
|
||||
description: A blank issue template for developers only. If you are not a developer, do not use this issue template. Your issue WILL BE CLOSED if you do not use the appropriate issue template.
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**If you are not a developer, do not use this issue template. Your issue WILL BE CLOSED if you do not use the appropriate issue template.**
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "Issue"
|
64
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Executable file
64
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Executable file
|
@ -0,0 +1,64 @@
|
|||
name: Bug Report
|
||||
description: File a bug report
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: Tech support does not belong here. You should only file an issue here if you think you have experienced an actual bug with yuzu.
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing issue for this?
|
||||
description: Please search to see if an issue already exists for the bug you encountered.
|
||||
options:
|
||||
- label: I have searched the existing issues
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Affected Build(s)
|
||||
description: List the affected build(s) that this issue applies to.
|
||||
placeholder: Mainline 1234 / Early Access 1234
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: issue-desc
|
||||
attributes:
|
||||
label: Description of Issue
|
||||
description: A brief description of the issue encountered along with any images and/or videos.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected-behavior
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: A brief description of how it is expected to work along with any images and/or videos.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction-steps
|
||||
attributes:
|
||||
label: Reproduction Steps
|
||||
description: A brief explanation of how to reproduce this issue. If possible, provide a save file to aid in reproducing the issue.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: log
|
||||
attributes:
|
||||
label: Log File
|
||||
description: A log file will help our developers to better diagnose and fix the issue. Instructions can be found [here](https://yuzu-emu.org/help/reference/log-files).
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: system-config
|
||||
attributes:
|
||||
label: System Configuration
|
||||
placeholder: |
|
||||
CPU: Intel i5-10400 / AMD Ryzen 5 3600
|
||||
GPU/Driver: NVIDIA GeForce GTX 1060 (Driver 512.95)
|
||||
RAM: 16GB DDR4-3200
|
||||
OS: Windows 11 22H2 (Build 22621.819)
|
||||
value: |
|
||||
CPU:
|
||||
GPU/Driver:
|
||||
RAM:
|
||||
OS:
|
||||
validations:
|
||||
required: true
|
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Executable file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Executable file
|
@ -0,0 +1,8 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: yuzu Discord
|
||||
url: https://discord.com/invite/u77vRWY
|
||||
about: If you are experiencing an issue with yuzu, and you need tech support, or if you have a general question, try asking in the official yuzu Discord linked here. Piracy is not allowed.
|
||||
- name: Community forums
|
||||
url: https://community.citra-emu.org
|
||||
about: This is an alternative place for tech support, however helpers there are not as active.
|
28
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Executable file
28
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Executable file
|
@ -0,0 +1,28 @@
|
|||
name: Feature Request
|
||||
description: File a feature request
|
||||
labels: "request"
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: Tech support does not belong here. You should only file an issue here if you are requesting a feature you believe would make yuzu better.
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing issue for this?
|
||||
description: Please search to see if an issue already exists for the feature you are requesting.
|
||||
options:
|
||||
- label: I have searched the existing issues
|
||||
required: true
|
||||
- type: textarea
|
||||
id: what-feature
|
||||
attributes:
|
||||
label: What feature are you suggesting?
|
||||
description: A brief description of the requested feature.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: why-feature
|
||||
attributes:
|
||||
label: Why would this feature be useful?
|
||||
description: A brief description of why this feature would make yuzu better.
|
||||
validations:
|
||||
required: true
|
80
.github/workflows/android-build.yml
vendored
Executable file
80
.github/workflows/android-build.yml
vendored
Executable file
|
@ -0,0 +1,80 @@
|
|||
# SPDX-FileCopyrightText: 2022 yuzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
name: 'yuzu-android-build'
|
||||
|
||||
on:
|
||||
push:
|
||||
tags: [ "*" ]
|
||||
|
||||
jobs:
|
||||
android:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'yuzu-emu/yuzu-android' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
- name: Set up cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
~/.ccache
|
||||
key: ${{ runner.os }}-android-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-android-
|
||||
- name: Query tag name
|
||||
uses: olegtarasov/get-tag@v2.1.2
|
||||
id: tagName
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ccache apksigner glslang-dev glslang-tools
|
||||
- name: Build
|
||||
run: ./.ci/scripts/android/build.sh
|
||||
env:
|
||||
ANDROID_KEYSTORE_B64: ${{ secrets.ANDROID_KEYSTORE_B64 }}
|
||||
ANDROID_KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
|
||||
ANDROID_KEYSTORE_PASS: ${{ secrets.ANDROID_KEYSTORE_PASS }}
|
||||
- name: Copy artifacts
|
||||
run: ./.ci/scripts/android/upload.sh
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: android
|
||||
path: artifacts/
|
||||
# release steps
|
||||
release-android:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [android]
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/download-artifact@v3
|
||||
- name: Query tag name
|
||||
uses: olegtarasov/get-tag@v2.1.2
|
||||
id: tagName
|
||||
- name: Create release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ steps.tagName.outputs.tag }}
|
||||
release_name: ${{ steps.tagName.outputs.tag }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
- name: Upload artifacts
|
||||
uses: alexellis/upload-assets@0.2.3
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
asset_paths: '["./**/*.apk","./**/*.aab"]'
|
66
.github/workflows/android-canary-play-release.yml
vendored
Executable file
66
.github/workflows/android-canary-play-release.yml
vendored
Executable file
|
@ -0,0 +1,66 @@
|
|||
# SPDX-FileCopyrightText: 2024 Citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
name: citron-android-canary-play-release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
release-track:
|
||||
description: 'Play store release track (internal/alpha/beta/production)'
|
||||
required: true
|
||||
default: 'alpha'
|
||||
|
||||
jobs:
|
||||
android:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'Citron-Project/Cit' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
name: Checkout
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
token: ${{ secrets.CI_RELEASE_TOKEN }}
|
||||
- run: npm install execa@5
|
||||
- uses: actions/github-script@v5
|
||||
name: 'Merge and publish Android Canary changes'
|
||||
env:
|
||||
CI_RELEASE_TOKEN: ${{ secrets.CI_RELEASE_TOKEN }}
|
||||
BUILD_CANARY: true
|
||||
with:
|
||||
script: |
|
||||
const execa = require("execa");
|
||||
const mergebot = require('./.github/workflows/android-merge.js').mergebot;
|
||||
process.chdir('${{ github.workspace }}');
|
||||
mergebot(github, context, execa);
|
||||
- name: Get tag name
|
||||
run: echo "GIT_TAG_NAME=$(cat tag-name.txt)" >> $GITHUB_ENV
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ccache apksigner glslang-dev glslang-tools
|
||||
- name: Build
|
||||
run: ./.ci/scripts/android/canarybuild.sh
|
||||
env:
|
||||
CANARY_PLAY_ANDROID_KEYSTORE_B64: ${{ secrets.PLAY_ANDROID_KEYSTORE_B64 }}
|
||||
PLAY_ANDROID_KEY_ALIAS: ${{ secrets.PLAY_ANDROID_KEY_ALIAS }}
|
||||
PLAY_ANDROID_KEYSTORE_PASS: ${{ secrets.PLAY_ANDROID_KEYSTORE_PASS }}
|
||||
CANARY_SERVICE_ACCOUNT_KEY_B64: ${{ secrets.CANARY_SERVICE_ACCOUNT_KEY_B64 }}
|
||||
STORE_TRACK: ${{ github.event.inputs.release-track }}
|
||||
AUTO_VERSIONED: true
|
||||
BUILD_CANARY: true
|
||||
- name: Create release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
tag_name: ${{ env.CANARY_TAG_NAME }}
|
||||
name: ${{ env.CANARY_TAG_NAME }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
repository: Citron-Project/citron-android
|
||||
token: ${{ secrets.CI_RELEASE_TOKEN }}
|
318
.github/workflows/android-merge.js
vendored
Executable file
318
.github/workflows/android-merge.js
vendored
Executable file
|
@ -0,0 +1,318 @@
|
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// Note: This is a GitHub Actions script
|
||||
// It is not meant to be executed directly on your machine without modifications
|
||||
|
||||
const fs = require("fs");
|
||||
// which label to check for changes
|
||||
const CHANGE_LABEL_MAINLINE = 'android-merge';
|
||||
const CHANGE_LABEL_EA = 'android-ea-merge';
|
||||
// how far back in time should we consider the changes are "recent"? (default: 24 hours)
|
||||
const DETECTION_TIME_FRAME = (parseInt(process.env.DETECTION_TIME_FRAME)) || (24 * 3600 * 1000);
|
||||
const BUILD_EA = process.env.BUILD_EA == 'true';
|
||||
const MAINLINE_TAG = process.env.MAINLINE_TAG;
|
||||
|
||||
async function checkBaseChanges(github) {
|
||||
// query the commit date of the latest commit on this branch
|
||||
const query = `query($owner:String!, $name:String!, $ref:String!) {
|
||||
repository(name:$name, owner:$owner) {
|
||||
ref(qualifiedName:$ref) {
|
||||
target {
|
||||
... on Commit { id pushedDate oid }
|
||||
}
|
||||
}
|
||||
}
|
||||
}`;
|
||||
const variables = {
|
||||
owner: 'yuzu-emu',
|
||||
name: 'yuzu',
|
||||
ref: 'refs/heads/master',
|
||||
};
|
||||
const result = await github.graphql(query, variables);
|
||||
const pushedAt = result.repository.ref.target.pushedDate;
|
||||
console.log(`Last commit pushed at ${pushedAt}.`);
|
||||
const delta = new Date() - new Date(pushedAt);
|
||||
if (delta <= DETECTION_TIME_FRAME) {
|
||||
console.info('New changes detected, triggering a new build.');
|
||||
return true;
|
||||
}
|
||||
console.info('No new changes detected.');
|
||||
return false;
|
||||
}
|
||||
|
||||
async function checkAndroidChanges(github) {
|
||||
if (checkBaseChanges(github)) return true;
|
||||
const pulls = getPulls(github, false);
|
||||
for (let i = 0; i < pulls.length; i++) {
|
||||
let pull = pulls[i];
|
||||
if (new Date() - new Date(pull.headRepository.pushedAt) <= DETECTION_TIME_FRAME) {
|
||||
console.info(`${pull.number} updated at ${pull.headRepository.pushedAt}`);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
console.info("No changes detected in any tagged pull requests.");
|
||||
return false;
|
||||
}
|
||||
|
||||
async function tagAndPush(github, owner, repo, execa, commit=false) {
|
||||
let altToken = process.env.ALT_GITHUB_TOKEN;
|
||||
if (!altToken) {
|
||||
throw `Please set ALT_GITHUB_TOKEN environment variable. This token should have write access to ${owner}/${repo}.`;
|
||||
}
|
||||
const query = `query ($owner:String!, $name:String!) {
|
||||
repository(name:$name, owner:$owner) {
|
||||
refs(refPrefix: "refs/tags/", orderBy: {field: TAG_COMMIT_DATE, direction: DESC}, first: 10) {
|
||||
nodes { name }
|
||||
}
|
||||
}
|
||||
}`;
|
||||
const variables = {
|
||||
owner: owner,
|
||||
name: repo,
|
||||
};
|
||||
const tags = await github.graphql(query, variables);
|
||||
const tagList = tags.repository.refs.nodes;
|
||||
let lastTag = 'android-1';
|
||||
for (let i = 0; i < tagList.length; ++i) {
|
||||
if (tagList[i].name.includes('android-')) {
|
||||
lastTag = tagList[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const tagNumber = /\w+-(\d+)/.exec(lastTag)[1] | 0;
|
||||
const channel = repo.split('-')[1];
|
||||
const newTag = `${channel}-${tagNumber + 1}`;
|
||||
console.log(`New tag: ${newTag}`);
|
||||
if (commit) {
|
||||
let channelName = channel[0].toUpperCase() + channel.slice(1);
|
||||
console.info(`Committing pending commit as ${channelName} ${tagNumber + 1}`);
|
||||
await execa("git", ['commit', '-m', `${channelName} ${tagNumber + 1}`]);
|
||||
}
|
||||
console.info('Pushing tags to GitHub ...');
|
||||
await execa("git", ['tag', newTag]);
|
||||
await execa("git", ['remote', 'add', 'target', `https://${altToken}@github.com/${owner}/${repo}.git`]);
|
||||
await execa("git", ['push', 'target', 'master', '-f']);
|
||||
await execa("git", ['push', 'target', 'master', '--tags']);
|
||||
console.info('Successfully pushed new changes.');
|
||||
}
|
||||
|
||||
async function tagAndPushEA(github, owner, repo, execa) {
|
||||
let altToken = process.env.ALT_GITHUB_TOKEN;
|
||||
if (!altToken) {
|
||||
throw `Please set ALT_GITHUB_TOKEN environment variable. This token should have write access to ${owner}/${repo}.`;
|
||||
}
|
||||
const query = `query ($owner:String!, $name:String!) {
|
||||
repository(name:$name, owner:$owner) {
|
||||
refs(refPrefix: "refs/tags/", orderBy: {field: TAG_COMMIT_DATE, direction: DESC}, first: 10) {
|
||||
nodes { name }
|
||||
}
|
||||
}
|
||||
}`;
|
||||
const variables = {
|
||||
owner: owner,
|
||||
name: repo,
|
||||
};
|
||||
const tags = await github.graphql(query, variables);
|
||||
const tagList = tags.repository.refs.nodes;
|
||||
let lastTag = 'ea-1';
|
||||
for (let i = 0; i < tagList.length; ++i) {
|
||||
if (tagList[i].name.includes('ea-')) {
|
||||
lastTag = tagList[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const tagNumber = /\w+-(\d+)/.exec(lastTag)[1] | 0;
|
||||
const newTag = `ea-${tagNumber + 1}`;
|
||||
console.log(`New tag: ${newTag}`);
|
||||
console.info('Pushing tags to GitHub ...');
|
||||
await execa("git", ["remote", "add", "android", "https://github.com/yuzu-emu/yuzu-android.git"]);
|
||||
await execa("git", ["fetch", "android"]);
|
||||
|
||||
await execa("git", ['tag', newTag]);
|
||||
await execa("git", ['push', 'android', `${newTag}`]);
|
||||
|
||||
fs.writeFile('tag-name.txt', newTag, (err) => {
|
||||
if (err) throw 'Could not write tag name to file!'
|
||||
})
|
||||
|
||||
console.info('Successfully pushed new changes.');
|
||||
}
|
||||
|
||||
async function generateReadme(pulls, context, mergeResults, execa) {
|
||||
let baseUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/`;
|
||||
let output =
|
||||
"| Pull Request | Commit | Title | Author | Merged? |\n|----|----|----|----|----|\n";
|
||||
for (let pull of pulls) {
|
||||
let pr = pull.number;
|
||||
let result = mergeResults[pr];
|
||||
output += `| [${pr}](${baseUrl}/pull/${pr}) | [\`${result.rev || "N/A"}\`](${baseUrl}/pull/${pr}/files) | ${pull.title} | [${pull.author.login}](https://github.com/${pull.author.login}/) | ${result.success ? "Yes" : "No"} |\n`;
|
||||
}
|
||||
output +=
|
||||
"\n\nEnd of merge log. You can find the original README.md below the break.\n\n-----\n\n";
|
||||
output += fs.readFileSync("./README.md");
|
||||
fs.writeFileSync("./README.md", output);
|
||||
await execa("git", ["add", "README.md"]);
|
||||
}
|
||||
|
||||
async function fetchPullRequests(pulls, repoUrl, execa) {
|
||||
console.log("::group::Fetch pull requests");
|
||||
for (let pull of pulls) {
|
||||
let pr = pull.number;
|
||||
console.info(`Fetching PR ${pr} ...`);
|
||||
await execa("git", [
|
||||
"fetch",
|
||||
"-f",
|
||||
"--no-recurse-submodules",
|
||||
repoUrl,
|
||||
`pull/${pr}/head:pr-${pr}`,
|
||||
]);
|
||||
}
|
||||
console.log("::endgroup::");
|
||||
}
|
||||
|
||||
async function mergePullRequests(pulls, execa) {
|
||||
let mergeResults = {};
|
||||
console.log("::group::Merge pull requests");
|
||||
await execa("git", ["config", "--global", "user.name", "yuzubot"]);
|
||||
await execa("git", [
|
||||
"config",
|
||||
"--global",
|
||||
"user.email",
|
||||
"yuzu\x40yuzu-emu\x2eorg", // prevent email harvesters from scraping the address
|
||||
]);
|
||||
let hasFailed = false;
|
||||
for (let pull of pulls) {
|
||||
let pr = pull.number;
|
||||
console.info(`Merging PR ${pr} ...`);
|
||||
try {
|
||||
const process1 = execa("git", [
|
||||
"merge",
|
||||
"--squash",
|
||||
"--no-edit",
|
||||
`pr-${pr}`,
|
||||
]);
|
||||
process1.stdout.pipe(process.stdout);
|
||||
await process1;
|
||||
|
||||
const process2 = execa("git", ["commit", "-m", `Merge yuzu-emu#${pr}`]);
|
||||
process2.stdout.pipe(process.stdout);
|
||||
await process2;
|
||||
|
||||
const process3 = await execa("git", ["rev-parse", "--short", `pr-${pr}`]);
|
||||
mergeResults[pr] = {
|
||||
success: true,
|
||||
rev: process3.stdout,
|
||||
};
|
||||
} catch (err) {
|
||||
console.log(
|
||||
`::error title=#${pr} not merged::Failed to merge pull request: ${pr}: ${err}`
|
||||
);
|
||||
mergeResults[pr] = { success: false };
|
||||
hasFailed = true;
|
||||
await execa("git", ["reset", "--hard"]);
|
||||
}
|
||||
}
|
||||
console.log("::endgroup::");
|
||||
if (hasFailed) {
|
||||
throw 'There are merge failures. Aborting!';
|
||||
}
|
||||
return mergeResults;
|
||||
}
|
||||
|
||||
async function resetBranch(execa) {
|
||||
console.log("::group::Reset master branch");
|
||||
let hasFailed = false;
|
||||
try {
|
||||
await execa("git", ["remote", "add", "source", "https://github.com/yuzu-emu/yuzu.git"]);
|
||||
await execa("git", ["fetch", "source"]);
|
||||
const process1 = await execa("git", ["rev-parse", "source/master"]);
|
||||
const headCommit = process1.stdout;
|
||||
|
||||
await execa("git", ["reset", "--hard", headCommit]);
|
||||
} catch (err) {
|
||||
console.log(`::error title=Failed to reset master branch`);
|
||||
hasFailed = true;
|
||||
}
|
||||
console.log("::endgroup::");
|
||||
if (hasFailed) {
|
||||
throw 'Failed to reset the master branch. Aborting!';
|
||||
}
|
||||
}
|
||||
|
||||
async function getPulls(github) {
|
||||
const query = `query ($owner:String!, $name:String!, $label:String!) {
|
||||
repository(name:$name, owner:$owner) {
|
||||
pullRequests(labels: [$label], states: OPEN, first: 100) {
|
||||
nodes {
|
||||
number title author { login }
|
||||
}
|
||||
}
|
||||
}
|
||||
}`;
|
||||
const mainlineVariables = {
|
||||
owner: 'yuzu-emu',
|
||||
name: 'yuzu',
|
||||
label: CHANGE_LABEL_MAINLINE,
|
||||
};
|
||||
const mainlineResult = await github.graphql(query, mainlineVariables);
|
||||
const pulls = mainlineResult.repository.pullRequests.nodes;
|
||||
if (BUILD_EA) {
|
||||
const eaVariables = {
|
||||
owner: 'yuzu-emu',
|
||||
name: 'yuzu',
|
||||
label: CHANGE_LABEL_EA,
|
||||
};
|
||||
const eaResult = await github.graphql(query, eaVariables);
|
||||
const eaPulls = eaResult.repository.pullRequests.nodes;
|
||||
return pulls.concat(eaPulls);
|
||||
}
|
||||
return pulls;
|
||||
}
|
||||
|
||||
async function getMainlineTag(execa) {
|
||||
console.log(`::group::Getting mainline tag android-${MAINLINE_TAG}`);
|
||||
let hasFailed = false;
|
||||
try {
|
||||
await execa("git", ["remote", "add", "mainline", "https://github.com/yuzu-emu/yuzu-android.git"]);
|
||||
await execa("git", ["fetch", "mainline", "--tags"]);
|
||||
await execa("git", ["checkout", `tags/android-${MAINLINE_TAG}`]);
|
||||
await execa("git", ["submodule", "update", "--init", "--recursive"]);
|
||||
} catch (err) {
|
||||
console.log('::error title=Failed pull tag');
|
||||
hasFailed = true;
|
||||
}
|
||||
console.log("::endgroup::");
|
||||
if (hasFailed) {
|
||||
throw 'Failed pull mainline tag. Aborting!';
|
||||
}
|
||||
}
|
||||
|
||||
async function mergebot(github, context, execa) {
|
||||
// Reset our local copy of master to what appears on yuzu-emu/yuzu - master
|
||||
await resetBranch(execa);
|
||||
|
||||
const pulls = await getPulls(github);
|
||||
let displayList = [];
|
||||
for (let i = 0; i < pulls.length; i++) {
|
||||
let pull = pulls[i];
|
||||
displayList.push({ PR: pull.number, Title: pull.title });
|
||||
}
|
||||
console.info("The following pull requests will be merged:");
|
||||
console.table(displayList);
|
||||
await fetchPullRequests(pulls, "https://github.com/yuzu-emu/yuzu", execa);
|
||||
const mergeResults = await mergePullRequests(pulls, execa);
|
||||
|
||||
if (BUILD_EA) {
|
||||
await tagAndPushEA(github, 'yuzu-emu', `yuzu-android`, execa);
|
||||
} else {
|
||||
await generateReadme(pulls, context, mergeResults, execa);
|
||||
await tagAndPush(github, 'yuzu-emu', `yuzu-android`, execa, true);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.mergebot = mergebot;
|
||||
module.exports.checkAndroidChanges = checkAndroidChanges;
|
||||
module.exports.tagAndPush = tagAndPush;
|
||||
module.exports.checkBaseChanges = checkBaseChanges;
|
||||
module.exports.getMainlineTag = getMainlineTag;
|
57
.github/workflows/android-publish.yml
vendored
Executable file
57
.github/workflows/android-publish.yml
vendored
Executable file
|
@ -0,0 +1,57 @@
|
|||
# SPDX-FileCopyrightText: 2024 yuzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
name: yuzu-android-publish
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '37 0 * * *'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
android:
|
||||
description: 'Whether to trigger an Android build (true/false/auto)'
|
||||
required: false
|
||||
default: 'true'
|
||||
|
||||
jobs:
|
||||
android:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.inputs.android != 'false' && github.repository == 'yuzu-emu/yuzu' }}
|
||||
steps:
|
||||
# this checkout is required to make sure the GitHub Actions scripts are available
|
||||
- uses: actions/checkout@v3
|
||||
name: Pre-checkout
|
||||
with:
|
||||
submodules: false
|
||||
- uses: actions/github-script@v6
|
||||
id: check-changes
|
||||
name: 'Check for new changes'
|
||||
env:
|
||||
# 24 hours
|
||||
DETECTION_TIME_FRAME: 86400000
|
||||
with:
|
||||
script: |
|
||||
if (context.payload.inputs && context.payload.inputs.android === 'true') return true;
|
||||
const checkAndroidChanges = require('./.github/workflows/android-merge.js').checkAndroidChanges;
|
||||
return checkAndroidChanges(github);
|
||||
- run: npm install execa@5
|
||||
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
||||
- uses: actions/checkout@v3
|
||||
name: Checkout
|
||||
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
||||
with:
|
||||
path: 'yuzu-merge'
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
token: ${{ secrets.ALT_GITHUB_TOKEN }}
|
||||
- uses: actions/github-script@v5
|
||||
name: 'Check and merge Android changes'
|
||||
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
||||
env:
|
||||
ALT_GITHUB_TOKEN: ${{ secrets.ALT_GITHUB_TOKEN }}
|
||||
with:
|
||||
script: |
|
||||
const execa = require("execa");
|
||||
const mergebot = require('./.github/workflows/android-merge.js').mergebot;
|
||||
process.chdir('${{ github.workspace }}/yuzu-merge');
|
||||
mergebot(github, context, execa);
|
59
.github/workflows/android-stable-play-release.yml
vendored
Executable file
59
.github/workflows/android-stable-play-release.yml
vendored
Executable file
|
@ -0,0 +1,59 @@
|
|||
# SPDX-FileCopyrightText: 2024 Citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
name: citron-android-stable-play-release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
release-tag:
|
||||
description: 'Tag # from citron-android that you want to build and publish'
|
||||
required: true
|
||||
default: '100'
|
||||
release-track:
|
||||
description: 'Play store release track (internal/alpha/beta/production)'
|
||||
required: true
|
||||
default: 'alpha'
|
||||
|
||||
jobs:
|
||||
android:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'Citron-Project/Cit' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
name: Checkout
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
token: ${{ secrets.CI_RELEASE_TOKEN }}
|
||||
- run: npm install execa@5
|
||||
- uses: actions/github-script@v5
|
||||
name: 'Pull stable tag'
|
||||
env:
|
||||
STABLE_TAG: ${{ github.event.inputs.release-tag }}
|
||||
with:
|
||||
script: |
|
||||
const execa = require("execa");
|
||||
const mergebot = require('./.github/workflows/android-merge.js').getStableTag;
|
||||
process.chdir('${{ github.workspace }}');
|
||||
mergebot(execa);
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ccache apksigner glslang-dev glslang-tools
|
||||
- name: Build
|
||||
run: |
|
||||
echo "GIT_TAG_NAME=android-${{ github.event.inputs.releast-tag }}" >> $GITHUB_ENV
|
||||
./.ci/scripts/android/stablebuild.sh
|
||||
env:
|
||||
STABLE_PLAY_ANDROID_KEYSTORE_B64: ${{ secrets.PLAY_ANDROID_KEYSTORE_B64 }}
|
||||
PLAY_ANDROID_KEY_ALIAS: ${{ secrets.PLAY_ANDROID_KEY_ALIAS }}
|
||||
PLAY_ANDROID_KEYSTORE_PASS: ${{ secrets.PLAY_ANDROID_KEYSTORE_PASS }}
|
||||
STABLE_SERVICE_ACCOUNT_KEY_B64: ${{ secrets.STABLE_SERVICE_ACCOUNT_KEY_B64 }}
|
||||
STORE_TRACK: ${{ github.event.inputs.release-track }}
|
||||
AUTO_VERSIONED: true
|
33
.github/workflows/ci.yml
vendored
Executable file
33
.github/workflows/ci.yml
vendored
Executable file
|
@ -0,0 +1,33 @@
|
|||
# SPDX-FileCopyrightText: 2024 Citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
name: citron-ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
tags: [ "*" ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
transifex:
|
||||
runs-on: ubuntu-latest
|
||||
container: yuzuemu/build-environments:linux-transifex
|
||||
if: ${{ github.repository == 'Citron-Project/Cit' && !github.head_ref }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
- name: Update Translation
|
||||
run: ./.ci/scripts/transifex/docker.sh
|
||||
env:
|
||||
TX_TOKEN: ${{ secrets.TRANSIFEX_API_TOKEN }}
|
||||
|
||||
reuse:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository == 'Citron-Project/Cit' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: fsfe/reuse-action@v1
|
17
.github/workflows/codespell.yml
vendored
Executable file
17
.github/workflows/codespell.yml
vendored
Executable file
|
@ -0,0 +1,17 @@
|
|||
# SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# GitHub Action to automate the identification of common misspellings in text files.
|
||||
# https://github.com/codespell-project/actions-codespell
|
||||
# https://github.com/codespell-project/codespell
|
||||
name: codespell
|
||||
on: pull_request
|
||||
permissions: {}
|
||||
jobs:
|
||||
codespell:
|
||||
name: Check for spelling errors
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: codespell-project/actions-codespell@master
|
190
.github/workflows/verify.yml
vendored
Executable file
190
.github/workflows/verify.yml
vendored
Executable file
|
@ -0,0 +1,190 @@
|
|||
# SPDX-FileCopyrightText: 2024 Citron Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
name: 'citron verify'
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
env:
|
||||
PR_NUMBER: pr${{ github.event.number }}
|
||||
|
||||
jobs:
|
||||
format:
|
||||
name: 'verify format'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: false
|
||||
- name: set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
- name: 'Verify Formatting'
|
||||
run: bash -ex ./.ci/scripts/format/script.sh
|
||||
build:
|
||||
name: 'test build'
|
||||
needs: format
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- type: clang
|
||||
image: linux-fresh
|
||||
- type: linux
|
||||
image: linux-fresh
|
||||
- type: windows
|
||||
image: linux-mingw
|
||||
container:
|
||||
image: yuzu-emu-mirror/build-environments:${{ matrix.image }}
|
||||
options: -u 1001
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
- name: Set up cache
|
||||
uses: actions/cache@v3
|
||||
id: ccache-restore
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ${{ runner.os }}-${{ matrix.type }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-${{ matrix.type }}-
|
||||
- name: Create ccache directory
|
||||
if: steps.ccache-restore.outputs.cache-hit != 'true'
|
||||
run: mkdir -p ~/.ccache
|
||||
- name: Build
|
||||
run: ./.ci/scripts/${{ matrix.type }}/docker.sh
|
||||
env:
|
||||
ENABLE_COMPATIBILITY_REPORTING: "ON"
|
||||
- name: Pack
|
||||
run: ./.ci/scripts/${{ matrix.type }}/upload.sh
|
||||
env:
|
||||
NO_SOURCE_PACK: "YES"
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ matrix.type }}
|
||||
path: artifacts/
|
||||
build-mac:
|
||||
name: 'test build (macos)'
|
||||
needs: format
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
brew install autoconf automake boost ccache ffmpeg fmt glslang hidapi libtool libusb lz4 ninja nlohmann-json openssl pkg-config qt@5 sdl2 speexdsp zlib zlib zstd
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
export Qt5_DIR="$(brew --prefix qt@5)/lib/cmake"
|
||||
cmake .. -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCITRON_USE_BUNDLED_VCPKG=OFF -DCITRON_TESTS=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_LIBUSB=OFF
|
||||
ninja
|
||||
build-msvc:
|
||||
name: 'test build (windows, msvc)'
|
||||
needs: format
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
- name: Set up cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.buildcache
|
||||
key: ${{ runner.os }}-msvc-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-msvc-
|
||||
- name: Install dependencies
|
||||
shell: pwsh
|
||||
run: |
|
||||
$ErrorActionPreference = "Stop"
|
||||
$BuildCacheVer = "v0.28.4"
|
||||
$File = "buildcache-windows.zip"
|
||||
$Uri = "https://github.com/mbitsnbites/buildcache/releases/download/$BuildCacheVer/$File"
|
||||
$WebClient = New-Object System.Net.WebClient
|
||||
$WebClient.DownloadFile($Uri, $File)
|
||||
7z x $File
|
||||
$CurrentDir = Convert-Path .
|
||||
echo "$CurrentDir/buildcache/bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
- name: Install Vulkan SDK
|
||||
shell: pwsh
|
||||
run: .\.ci\scripts\windows\install-vulkan-sdk.ps1
|
||||
- name: Set up MSVC
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
- name: Configure
|
||||
env:
|
||||
CC: cl.exe
|
||||
CXX: cl.exe
|
||||
run: |
|
||||
glslangValidator --version
|
||||
mkdir build
|
||||
cmake . -B build -GNinja -DCMAKE_TOOLCHAIN_FILE="CMakeModules/MSVCCache.cmake" -DUSE_CCACHE=ON -DCITRON_USE_BUNDLED_QT=1 -DCITRON_USE_BUNDLED_SDL2=1 -DCITRON_USE_QT_WEB_ENGINE=ON -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DCITRON_ENABLE_COMPATIBILITY_REPORTING=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_QT_TRANSLATION=ON -DCMAKE_BUILD_TYPE=Release -DGIT_BRANCH=pr-verify -DCITRON_CRASH_DUMPS=ON
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
- name: Cache Summary
|
||||
run: buildcache -s
|
||||
- name: Pack
|
||||
shell: pwsh
|
||||
run: .\.ci\scripts\windows\upload.ps1
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: msvc
|
||||
path: artifacts/
|
||||
- name: Upload EXE
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ env.INDIVIDUAL_EXE }}
|
||||
path: ${{ env.INDIVIDUAL_EXE }}
|
||||
android:
|
||||
runs-on: ubuntu-latest
|
||||
needs: format
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
- name: set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
- name: Set up cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
~/.ccache
|
||||
key: ${{ runner.os }}-android-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-android-
|
||||
- name: Query tag name
|
||||
uses: olegtarasov/get-tag@v2.1.2
|
||||
id: tagName
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ccache apksigner glslang-dev glslang-tools
|
||||
- name: Build
|
||||
run: ./.ci/scripts/android/build.sh
|
||||
env:
|
||||
USE_DEBUG_KEYSTORE: "true"
|
||||
- name: Copy artifacts
|
||||
run: ./.ci/scripts/android/upload.sh
|
||||
- name: Upload
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: android
|
||||
path: artifacts/
|
|
@ -76,9 +76,19 @@ android {
|
|||
buildConfigField("String", "BRANCH", "\"${getBranch()}\"")
|
||||
}
|
||||
|
||||
// Always use debug keystore for CI builds when USE_DEBUG_KEYSTORE is set
|
||||
val useDebugKeystore = System.getenv("USE_DEBUG_KEYSTORE") == "true"
|
||||
val keystoreFile = System.getenv("ANDROID_KEYSTORE_FILE")
|
||||
|
||||
signingConfigs {
|
||||
if (keystoreFile != null) {
|
||||
create("default") {
|
||||
storeFile = file("$projectDir/debug.keystore")
|
||||
storePassword = "android"
|
||||
keyAlias = "androiddebugkey"
|
||||
keyPassword = "android"
|
||||
}
|
||||
|
||||
if (keystoreFile != null && !useDebugKeystore) {
|
||||
create("release") {
|
||||
storeFile = file(keystoreFile)
|
||||
storePassword = System.getenv("ANDROID_KEYSTORE_PASS")
|
||||
|
@ -86,12 +96,6 @@ android {
|
|||
keyPassword = System.getenv("ANDROID_KEYSTORE_PASS")
|
||||
}
|
||||
}
|
||||
create("default") {
|
||||
storeFile = file("$projectDir/debug.keystore")
|
||||
storePassword = "android"
|
||||
keyAlias = "androiddebugkey"
|
||||
keyPassword = "android"
|
||||
}
|
||||
}
|
||||
|
||||
// Define build types, which are orthogonal to product flavors.
|
||||
|
@ -99,7 +103,7 @@ android {
|
|||
|
||||
// Signed by release key, allowing for upload to Play Store.
|
||||
release {
|
||||
signingConfig = if (keystoreFile != null) {
|
||||
signingConfig = if (keystoreFile != null && !useDebugKeystore) {
|
||||
signingConfigs.getByName("release")
|
||||
} else {
|
||||
signingConfigs.getByName("default")
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<property name="title">
|
||||
<string>citron Web Service</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayoutYuzuWebService">
|
||||
<layout class="QVBoxLayout" name="verticalLayoutCitronWebService">
|
||||
<item>
|
||||
<widget class="QLabel" name="web_credentials_disclaimer">
|
||||
<property name="text">
|
||||
|
@ -33,7 +33,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayoutYuzuUsername">
|
||||
<layout class="QGridLayout" name="gridLayoutCitronUsername">
|
||||
<item row="2" column="3">
|
||||
<widget class="QPushButton" name="button_reset_token">
|
||||
<property name="sizePolicy">
|
||||
|
|
Loading…
Reference in a new issue