Merge branch 'jenkins' into 'develop'
Jenkins Pipeline This merge requests adds necessary changes in order to fully integrate Jenkins continuous integration (automated builds and deployment) into this repository. .
This commit is contained in:
commit
cf3ecedc5f
241
Jenkinsfile
vendored
Normal file
241
Jenkinsfile
vendored
Normal file
@ -0,0 +1,241 @@
|
||||
#!groovy
|
||||
|
||||
/*
|
||||
This is our new pipeline script to do all of the building in, of and around IW4x.
|
||||
|
||||
Here's what it is supposed to do:
|
||||
|
||||
- Make sure Modern Warfare 2 is installed (CI should provide the folder like a custom tool)
|
||||
- Check out code from iw4x-data
|
||||
- Build the IW4x client library (this code repository)
|
||||
- Use iw4x.exe from the iw4x-data repository in order to build the zone files in iw4x-data
|
||||
- Package the IW4x client with the newly built data files
|
||||
|
||||
At this point it is done building everything, however afterwards we want the build server to
|
||||
also push the newly built files to an update repository, depending on the branch we're on.
|
||||
|
||||
- For "develop", release to the "iw4x-dev" branch on the repository server.
|
||||
- For "master", release to the "iw4x" branch on the repository server.
|
||||
|
||||
I'm looking into how the logic of pipelining works in detail before deciding on whether to
|
||||
throw in the IW4x Updater and the IW4x Node binaries in as well or not.
|
||||
*/
|
||||
|
||||
/*
|
||||
Note that this is just a rewrite of the jobs as they are currently set up on the production
|
||||
Jenkins server. This will allow every developer to tinker around with how the build process
|
||||
is set up. For those who want to play around with this, here's a bit of information:
|
||||
|
||||
- This is a Groovy script. Essentially Java but with less bullshit (like brackets and verbose writing).
|
||||
- This gets directly translated into a Jenkins pipeline.
|
||||
- If you have no idea how to handle scripts, get your hands off this file.
|
||||
- If you do not use Jenkins, get your hands off this file.
|
||||
- If you fuck this script up, I will kill you.
|
||||
*/
|
||||
|
||||
import groovy.transform.Field
|
||||
|
||||
@Field def configurations = [
|
||||
"Debug",
|
||||
"DebugStatic",
|
||||
"Release",
|
||||
"ReleaseStatic"
|
||||
]
|
||||
|
||||
def useShippedPremake(f) {
|
||||
def premakeHome = "${pwd()}\\tools"
|
||||
|
||||
withEnv(["PATH+=${premakeHome}"], f)
|
||||
}
|
||||
|
||||
def getIW4xExecutable() {
|
||||
step([
|
||||
$class: 'CopyArtifact',
|
||||
filter: '*',
|
||||
fingerprintArtifacts: true,
|
||||
projectName: 'iw4x/iw4x-executable/master',
|
||||
selector: [
|
||||
$class: 'TriggeredBuildSelector',
|
||||
allowUpstreamDependencies: false,
|
||||
fallbackToLastSuccessful: true,
|
||||
upstreamFilterStrategy: 'UseGlobalSetting'
|
||||
]
|
||||
])
|
||||
}
|
||||
|
||||
// This will build the IW4x client.
|
||||
// We need a Windows Server with Visual Studio 2015, Premake5 and Git on it.
|
||||
def doBuild(name, wsid, premakeFlags, configuration) {
|
||||
node("windows") {
|
||||
ws("IW4x/build/$wsid") {
|
||||
checkout scm
|
||||
|
||||
useShippedPremake {
|
||||
def outputDir = pwd()
|
||||
def msbuild = tool "Microsoft.NET MSBuild 14.0"
|
||||
bat "premake5 vs2015 $premakeFlags"
|
||||
bat "\"${msbuild}\" build\\iw4x.sln \"/p:OutDir=$outputDir\\\\\" \"/p:Configuration=$configuration\""
|
||||
}
|
||||
|
||||
stash name: "$name", includes: "*.dll,*.pdb"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This will run the unit tests for IW4x.
|
||||
// We need a Windows Server with MW2 on it.
|
||||
def doUnitTests(name) {
|
||||
mw2dir = tool "Modern Warfare 2"
|
||||
|
||||
unstash "$name"
|
||||
|
||||
// Get installed localization for correct zonefiles directory junction
|
||||
def localization = readFile("$mw2dir/localization.txt").split("\r?\n")[0]
|
||||
|
||||
try {
|
||||
timeout(time: 180, unit: "MINUTES") {
|
||||
// Set up environment
|
||||
if (isUnix()) {
|
||||
sh """
|
||||
mkdir -p zone
|
||||
for f in main zone/dlc \"zone/$localization\"; do
|
||||
ln -sfv \"$mw2dir/\$f\" \"\$f\"
|
||||
done
|
||||
for f in \"$mw2dir\"/*.dll \"$mw2dir\"/*.txt \"$mw2dir\"/*.bmp; do
|
||||
ln -sfv \"\$f\" \"\$(basename \"\$f\")\"
|
||||
done
|
||||
"""
|
||||
} else {
|
||||
bat """
|
||||
mklink /J \"main\" \"$mw2dir\\main\"
|
||||
mkdir \"zone\"
|
||||
mklink /J \"zone\\dlc\" \"$mw2dir\\zone\\dlc\"
|
||||
mklink /J \"zone\\$localization\" \"$mw2dir\\zone\\$localization\"
|
||||
copy /y \"$mw2dir\\*.dll\"
|
||||
copy /y \"$mw2dir\\*.txt\"
|
||||
copy /y \"$mw2dir\\*.bmp\"
|
||||
"""
|
||||
}
|
||||
|
||||
// Run tests
|
||||
getIW4xExecutable()
|
||||
if (isUnix()) {
|
||||
sh "wine-wrapper iw4x.exe -tests"
|
||||
} else {
|
||||
bat "iw4x.exe -tests"
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
// In all cases make sure to at least remove the directory junctions!
|
||||
if (!isUnix()) {
|
||||
bat """
|
||||
rmdir \"main\"
|
||||
rmdir \"zone\\dlc\"
|
||||
rmdir \"zone\\$localization\"
|
||||
"""
|
||||
}
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
// Job properties
|
||||
properties([
|
||||
[$class: "GitLabConnectionProperty", gitLabConnection: "sr0"]
|
||||
])
|
||||
|
||||
gitlabBuilds(builds: ["Checkout & Versioning", "Build", "Testing", "Archiving"]) {
|
||||
// First though let's give this build a proper name
|
||||
stage("Checkout & Versioning") {
|
||||
gitlabCommitStatus("Checkout & Versioning") {
|
||||
node("windows") {
|
||||
checkout scm
|
||||
|
||||
useShippedPremake {
|
||||
def version = bat(returnStdout: true, script: '@premake5 version').split("\r?\n")[1]
|
||||
|
||||
currentBuild.setDisplayName "$version (#${env.BUILD_NUMBER})"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For each available configuration generate a normal build and a unit test build.
|
||||
stage("Build") {
|
||||
gitlabCommitStatus("Build") {
|
||||
def executions = [:]
|
||||
for (int i = 0; i < configurations.size(); i++)
|
||||
{
|
||||
def configuration = configurations[i]
|
||||
executions["$configuration"] = {
|
||||
doBuild("IW4x $configuration", "$configuration", "", configuration)
|
||||
}
|
||||
executions["$configuration with unit tests"] = {
|
||||
doBuild("IW4x $configuration (unit tests)", "$configuration+unittests", "--force-unit-tests", configuration)
|
||||
}
|
||||
}
|
||||
parallel executions
|
||||
}
|
||||
}
|
||||
|
||||
// Run unit tests on each configuration.
|
||||
stage("Testing") {
|
||||
gitlabCommitStatus("Testing") {
|
||||
executions = [:]
|
||||
for (int i = 0; i < configurations.size(); i++) {
|
||||
def configuration = configurations[i]
|
||||
executions["$configuration on Windows"] = {
|
||||
node("windows") {
|
||||
ws("IW4x/testing/$configuration") {
|
||||
doUnitTests("IW4x $configuration (unit tests)")
|
||||
}
|
||||
}
|
||||
}
|
||||
executions["$configuration on Linux"] = {
|
||||
node("docker && linux && amd64") {
|
||||
try {
|
||||
def image = null
|
||||
dir("src") {
|
||||
checkout scm
|
||||
image = docker.build("github.com/IW4x/iw4x-client-testing-wine32", "--rm --force-rm -f jenkins/wine32.Dockerfile jenkins")
|
||||
deleteDir()
|
||||
}
|
||||
image.inside {
|
||||
doUnitTests("IW4x $configuration (unit tests)")
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (isUnix()) {
|
||||
manager.buildUnstable()
|
||||
manager.addWarningBadge "$configuration unit test failed on Linux"
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
parallel executions
|
||||
}
|
||||
}
|
||||
|
||||
// Collect all the binaries and give each configuration its own subfolder
|
||||
stage("Archiving") {
|
||||
gitlabCommitStatus("Archiving") {
|
||||
node("windows") { // any node will do
|
||||
ws("IW4x/pub") {
|
||||
try {
|
||||
for (int i = 0; i < configurations.size(); i++)
|
||||
{
|
||||
def configuration = configurations[i]
|
||||
dir("$configuration") {
|
||||
unstash "IW4x $configuration"
|
||||
}
|
||||
}
|
||||
archiveArtifacts artifacts: "**/*.dll,**/*.pdb", fingerprint: true
|
||||
} finally {
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
37
jenkins/wine32.Dockerfile
Normal file
37
jenkins/wine32.Dockerfile
Normal file
@ -0,0 +1,37 @@
|
||||
# Requires a decent modern Docker version (v1.10.x at least ideally)
|
||||
|
||||
# Use semi-official Arch Linux image with fixed versioning
|
||||
FROM pritunl/archlinux:2016-09-10
|
||||
|
||||
# Environment variables
|
||||
ENV WINEPREFIX /wine32
|
||||
ENV WINEARCH win32
|
||||
ENV WINEDEBUG -all
|
||||
|
||||
# Install Wine (32-bit)
|
||||
RUN \
|
||||
echo -e "#!/bin/sh\nwine \$@\nretval=\$?\ntail --pid=\$(pidof wineserver 2>/dev/null||echo 0) -f /dev/null\nexit \$retval" > /usr/local/bin/wine-wrapper &&\
|
||||
chmod +x /usr/local/bin/wine-wrapper &&\
|
||||
\
|
||||
(\
|
||||
echo '' &&\
|
||||
echo '[multilib]' &&\
|
||||
echo 'Include = /etc/pacman.d/mirrorlist'\
|
||||
) >> /etc/pacman.conf &&\
|
||||
pacman -Sy --noconfirm wine wget xorg-server-xvfb &&\
|
||||
\
|
||||
wine-wrapper wineboot.exe -i &&\
|
||||
wget -Ovcredist_x86.exe https://download.microsoft.com/download/d/d/9/dd9a82d0-52ef-40db-8dab-795376989c03/vcredist_x86.exe &&\
|
||||
xvfb-run sh -c 'wine-wrapper vcredist_x86.exe /q' &&\
|
||||
rm vcredist_x86.exe &&\
|
||||
\
|
||||
pacman -Rs --noconfirm xorg-server-xvfb wget &&\
|
||||
\
|
||||
find /. -name "*~" -type f -delete &&\
|
||||
rm -rf /tmp/* /var/tmp/* /usr/share/man/* /usr/share/info/* /usr/share/doc/* &&\
|
||||
pacman -Scc --noconfirm &&\
|
||||
paccache -rk0 &&\
|
||||
pacman-optimize &&\
|
||||
rm -rf /var/lib/pacman/sync/*
|
||||
|
||||
USER 0
|
@ -13,10 +13,10 @@ namespace Components
|
||||
BitMessage::BitMessage()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Logger::Print("Initializing BitMessage...\n");
|
||||
Logger::Print("Initializing BitMessage...\n");
|
||||
#endif // DEBUG
|
||||
|
||||
|
||||
|
||||
|
||||
BitMessage::BMClient = new BitMRC(BITMESSAGE_OBJECT_STORAGE_FILENAME, BITMESSAGE_KEYS_FILENAME);
|
||||
BitMessage::BMClient->init();
|
||||
@ -36,7 +36,7 @@ Logger::Print("Initializing BitMessage...\n");
|
||||
BitMessage::BMClient->start();
|
||||
|
||||
#ifdef DEBUG
|
||||
Command::Add("bm_send", [](Command::Params params)
|
||||
Command::Add("bm_send", [](Command::Params params)
|
||||
{
|
||||
if (params.Length() < 3) return;
|
||||
|
||||
@ -70,7 +70,7 @@ Logger::Print("Initializing BitMessage...\n");
|
||||
Logger::Print("Broadcast done.\n");
|
||||
});
|
||||
|
||||
Command::Add("bm_check_messages", [](Command::Params)
|
||||
Command::Add("bm_check_messages", [](Command::Params)
|
||||
{
|
||||
while (BitMessage::BMClient->new_messages.size() > 0)
|
||||
{
|
||||
@ -79,7 +79,7 @@ Logger::Print("Initializing BitMessage...\n");
|
||||
}
|
||||
});
|
||||
|
||||
Command::Add("bm_check_connections", [](Command::Params)
|
||||
Command::Add("bm_check_connections", [](Command::Params)
|
||||
{
|
||||
std::shared_lock<std::shared_timed_mutex> mlock(BitMessage::BMClient->mutex_nodes);
|
||||
|
||||
@ -104,7 +104,7 @@ Logger::Print("Initializing BitMessage...\n");
|
||||
mlock.unlock();
|
||||
});
|
||||
|
||||
Command::Add("bm_check_privatekey", [](Command::Params)
|
||||
Command::Add("bm_check_privatekey", [](Command::Params)
|
||||
{
|
||||
std::shared_lock<std::shared_timed_mutex> mlock(BitMessage::BMClient->mutex_priv);
|
||||
|
||||
@ -123,7 +123,7 @@ Logger::Print("Initializing BitMessage...\n");
|
||||
mlock.unlock();
|
||||
});
|
||||
|
||||
Command::Add("bm_check_publickey", [](Command::Params)
|
||||
Command::Add("bm_check_publickey", [](Command::Params)
|
||||
{
|
||||
std::shared_lock<std::shared_timed_mutex> mlock(BitMessage::BMClient->mutex_pub);
|
||||
|
||||
@ -140,12 +140,12 @@ Logger::Print("Initializing BitMessage...\n");
|
||||
mlock.unlock();
|
||||
});
|
||||
|
||||
Command::Add("bm_save", [](Command::Params)
|
||||
Command::Add("bm_save", [](Command::Params)
|
||||
{
|
||||
BitMessage::Save();
|
||||
});
|
||||
|
||||
Command::Add("bm_address_public", [](Command::Params params)
|
||||
Command::Add("bm_address_public", [](Command::Params params)
|
||||
{
|
||||
if (params.Length() < 2) return;
|
||||
|
||||
@ -165,7 +165,7 @@ Logger::Print("Initializing BitMessage...\n");
|
||||
}
|
||||
});
|
||||
|
||||
Command::Add("bm_address_broadcast", [](Command::Params params)
|
||||
Command::Add("bm_address_broadcast", [](Command::Params params)
|
||||
{
|
||||
if (params.Length() < 2) return;
|
||||
|
||||
|
@ -157,6 +157,7 @@ namespace Components
|
||||
MinidumpUpload::MinidumpUpload()
|
||||
{
|
||||
#if !defined(DEBUG) || defined(FORCE_MINIDUMP_UPLOAD)
|
||||
if (Loader::PerformingUnitTests() || ZoneBuilder::IsEnabled()) return;
|
||||
this->uploadThread = std::thread([&]() { this->UploadQueuedMinidumps(); });
|
||||
#endif
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ namespace Components
|
||||
|
||||
Console::FreeNativeConsole();
|
||||
|
||||
if (Dedicated::IsEnabled() || ZoneBuilder::IsEnabled()) return;
|
||||
if (Loader::PerformingUnitTests() || Dedicated::IsEnabled() || ZoneBuilder::IsEnabled()) return;
|
||||
|
||||
Singleton::FirstInstance = (CreateMutexA(NULL, FALSE, "iw4x_mutex") && GetLastError() != ERROR_ALREADY_EXISTS);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user