From cb8087771b23605a62608a1a672b61b1859ac1e9 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 00:33:00 +0200 Subject: [PATCH 01/46] Add Jenkinsfile. --- Jenkinsfile | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 Jenkinsfile diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 00000000..ba9fb30e --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,90 @@ +#!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. +*/ + +@Field def configurations = [ + "Debug", + "DebugStatic", + "Release", + "ReleaseStatic" +] + +// Run a function for each platform and project to be built +def perConfiguration(suffix, f) { + def executions = [:] + for (int a = 0; a < configurations.size(); a++) { + def configuration = configurations[a] + executions["$configuration$suffix"] = { + f(goos, goarch, targetProject) + } + } + parallel executions +} + +// This will build the IW4x client. +// We need a Windows Server with Visual Studio 2015, Premake5 and Git on it. +def doBuild(premakeFlags, configuration) { + node("windows") { + checkout scm + + premakeHome = "${pwd()}\\src\\tools" + + withEnv(["PATH+=${premakeHome}"]) { + def outputDir = pwd() + dir("src") { + bat "premake5 vs2015 $premakeFlags" + bat "\"${tool 'MSBuild'}\" src\\build\\iw4x.sln \"/p:OutDir=$outputDir\\\" \"/p:Configuration=$configuration\"" + } + } + + archiveArtifacts artifacts: "*", fingerprint: true + stash name: "iw4x $configuration", includes: "*" + } +} + +// For each available configuration generate a normal build and a unit test build. +stage "Build" +def executions = [:] +for (int i = 0; i < configurations.size(); i++) +{ + configuration = configurations[i] + executions["$configuration"] = { + doBuild premakeFlags: "", configuration: configuration + } + executions["$configuration Unit-Testing"] = { + doBuild premakeFlags: "--force-unit-tests", configuration: configuration + } +} +parallel executions + From 2ed39f714a18ca846b6f0d83c76b8023f7fdddea Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 00:40:34 +0200 Subject: [PATCH 02/46] Jenkinsfile: Reuse SSH credentials through SSH agent (hopefully). --- Jenkinsfile | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index ba9fb30e..c790648f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -56,20 +56,23 @@ def perConfiguration(suffix, f) { // We need a Windows Server with Visual Studio 2015, Premake5 and Git on it. def doBuild(premakeFlags, configuration) { node("windows") { - checkout scm + sshagent (credentials: ["ba9ec261-deff-4fa0-a0e8-5d755f88d035"]) { + checkout scm - premakeHome = "${pwd()}\\src\\tools" + premakeHome = "${pwd()}\\src\\tools" - withEnv(["PATH+=${premakeHome}"]) { - def outputDir = pwd() - dir("src") { - bat "premake5 vs2015 $premakeFlags" - bat "\"${tool 'MSBuild'}\" src\\build\\iw4x.sln \"/p:OutDir=$outputDir\\\" \"/p:Configuration=$configuration\"" + withEnv(["PATH+=${premakeHome}"]) { + def outputDir = pwd() + dir("src") { + bat "premake5 vs2015 $premakeFlags" + bat "\"${tool 'MSBuild'}\" src\\build\\iw4x.sln \"/p:OutDir=$outputDir\\\" \"/p:Configuration=$configuration\"" + } } + + archiveArtifacts artifacts: "*", fingerprint: true + stash name: "iw4x $configuration", includes: "*" } - archiveArtifacts artifacts: "*", fingerprint: true - stash name: "iw4x $configuration", includes: "*" } } From a9c888d17bf1028ce6df067ae10b82da9880a9ca Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 01:34:31 +0200 Subject: [PATCH 03/46] Jenkinsfile: Do not use src subdirectory. --- Jenkinsfile | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index c790648f..3e22e924 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -59,18 +59,16 @@ def doBuild(premakeFlags, configuration) { sshagent (credentials: ["ba9ec261-deff-4fa0-a0e8-5d755f88d035"]) { checkout scm - premakeHome = "${pwd()}\\src\\tools" + premakeHome = "${pwd()}\\tools" withEnv(["PATH+=${premakeHome}"]) { def outputDir = pwd() - dir("src") { - bat "premake5 vs2015 $premakeFlags" - bat "\"${tool 'MSBuild'}\" src\\build\\iw4x.sln \"/p:OutDir=$outputDir\\\" \"/p:Configuration=$configuration\"" - } + bat "premake5 vs2015 $premakeFlags" + bat "\"${tool 'MSBuild'}\" src\\build\\iw4x.sln \"/p:OutDir=$outputDir\\\" \"/p:Configuration=$configuration\"" } - archiveArtifacts artifacts: "*", fingerprint: true - stash name: "iw4x $configuration", includes: "*" + archiveArtifacts artifacts: "*.dll,*.pdb", fingerprint: true + stash name: "iw4x $configuration", includes: "*.dll,*.pdb" } } From 20a8c35f1ff0c8977191bbc4775386661f87aaad Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 01:41:39 +0200 Subject: [PATCH 04/46] Jenkinsfile: Fix @Field annotation. --- Jenkinsfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 3e22e924..75ae24d7 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -33,6 +33,8 @@ is set up. For those who want to play around with this, here's a bit of informat - If you fuck this script up, I will kill you. */ +import groovy.transform.Field + @Field def configurations = [ "Debug", "DebugStatic", From 2293fda5f2c6903f89474ce2be95c4c881a72e58 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 01:47:13 +0200 Subject: [PATCH 05/46] Jenkinsfile: Fix configuration loop calls. --- Jenkinsfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 75ae24d7..4c7aa6e1 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -81,12 +81,12 @@ stage "Build" def executions = [:] for (int i = 0; i < configurations.size(); i++) { - configuration = configurations[i] + def configuration = configurations[i] executions["$configuration"] = { - doBuild premakeFlags: "", configuration: configuration + doBuild("", configuration) } executions["$configuration Unit-Testing"] = { - doBuild premakeFlags: "--force-unit-tests", configuration: configuration + doBuild("--force-unit-tests", configuration) } } parallel executions From 8a18c1288785d38caec25b26dfea8f465c932547 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 01:50:26 +0200 Subject: [PATCH 06/46] Jenkinsfile: Remove SSH agent as credentials have been fixed with recent Jenkins Git plugin version. --- Jenkinsfile | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 4c7aa6e1..bc4ddffd 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -58,21 +58,18 @@ def perConfiguration(suffix, f) { // We need a Windows Server with Visual Studio 2015, Premake5 and Git on it. def doBuild(premakeFlags, configuration) { node("windows") { - sshagent (credentials: ["ba9ec261-deff-4fa0-a0e8-5d755f88d035"]) { - checkout scm + checkout scm - premakeHome = "${pwd()}\\tools" + premakeHome = "${pwd()}\\tools" - withEnv(["PATH+=${premakeHome}"]) { - def outputDir = pwd() - bat "premake5 vs2015 $premakeFlags" - bat "\"${tool 'MSBuild'}\" src\\build\\iw4x.sln \"/p:OutDir=$outputDir\\\" \"/p:Configuration=$configuration\"" - } - - archiveArtifacts artifacts: "*.dll,*.pdb", fingerprint: true - stash name: "iw4x $configuration", includes: "*.dll,*.pdb" + withEnv(["PATH+=${premakeHome}"]) { + def outputDir = pwd() + bat "premake5 vs2015 $premakeFlags" + bat "\"${tool 'MSBuild'}\" src\\build\\iw4x.sln \"/p:OutDir=$outputDir\\\" \"/p:Configuration=$configuration\"" } + archiveArtifacts artifacts: "*.dll,*.pdb", fingerprint: true + stash name: "iw4x $configuration", includes: "*.dll,*.pdb" } } From 1b3c9d17f5ec0ce2ed276b49faad1c936596c5fa Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 01:59:47 +0200 Subject: [PATCH 07/46] Jenkinsfile: Fix MSBuild tool reference. --- Jenkinsfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index bc4ddffd..08b6f71c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -64,8 +64,9 @@ def doBuild(premakeFlags, configuration) { withEnv(["PATH+=${premakeHome}"]) { def outputDir = pwd() + def msbuild = tool "Microsoft.NET MSBuild 14.0" bat "premake5 vs2015 $premakeFlags" - bat "\"${tool 'MSBuild'}\" src\\build\\iw4x.sln \"/p:OutDir=$outputDir\\\" \"/p:Configuration=$configuration\"" + bat "\"${msbuild}\" src\\build\\iw4x.sln \"/p:OutDir=$outputDir\\\" \"/p:Configuration=$configuration\"" } archiveArtifacts artifacts: "*.dll,*.pdb", fingerprint: true From 5350b25a3eb6f4c30de86705e229d98a2f9a13ce Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 02:01:48 +0200 Subject: [PATCH 08/46] Jenkinsfile: Fix solution file path. --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 08b6f71c..71a646da 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -66,7 +66,7 @@ def doBuild(premakeFlags, configuration) { def outputDir = pwd() def msbuild = tool "Microsoft.NET MSBuild 14.0" bat "premake5 vs2015 $premakeFlags" - bat "\"${msbuild}\" src\\build\\iw4x.sln \"/p:OutDir=$outputDir\\\" \"/p:Configuration=$configuration\"" + bat "\"${msbuild}\" build\\iw4x.sln \"/p:OutDir=$outputDir\\\" \"/p:Configuration=$configuration\"" } archiveArtifacts artifacts: "*.dll,*.pdb", fingerprint: true From 1d8fb7249577851d11f3acbb88a5f0ff33da4bb6 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 02:03:50 +0200 Subject: [PATCH 09/46] Jenkinsfile: I think this needs another backslash. --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 71a646da..e912a728 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -66,7 +66,7 @@ def doBuild(premakeFlags, configuration) { 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\"" + bat "\"${msbuild}\" build\\iw4x.sln \"/p:OutDir=$outputDir\\\\\" \"/p:Configuration=$configuration\"" } archiveArtifacts artifacts: "*.dll,*.pdb", fingerprint: true From 717bb45d2173bad5d1078d93ba50abd80ee872b3 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 02:11:16 +0200 Subject: [PATCH 10/46] Jenkinsfile: Remove unused copypasta. --- Jenkinsfile | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index e912a728..18c7a78f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -42,18 +42,6 @@ import groovy.transform.Field "ReleaseStatic" ] -// Run a function for each platform and project to be built -def perConfiguration(suffix, f) { - def executions = [:] - for (int a = 0; a < configurations.size(); a++) { - def configuration = configurations[a] - executions["$configuration$suffix"] = { - f(goos, goarch, targetProject) - } - } - parallel executions -} - // This will build the IW4x client. // We need a Windows Server with Visual Studio 2015, Premake5 and Git on it. def doBuild(premakeFlags, configuration) { From b85ae0f764ab989a76aa2b737fb898bd20b26f96 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 02:11:41 +0200 Subject: [PATCH 11/46] Jenkinsfile: Fix overwritten stashes. --- Jenkinsfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 18c7a78f..471ab9d4 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -44,7 +44,7 @@ import groovy.transform.Field // This will build the IW4x client. // We need a Windows Server with Visual Studio 2015, Premake5 and Git on it. -def doBuild(premakeFlags, configuration) { +def doBuild(name, premakeFlags, configuration) { node("windows") { checkout scm @@ -58,7 +58,7 @@ def doBuild(premakeFlags, configuration) { } archiveArtifacts artifacts: "*.dll,*.pdb", fingerprint: true - stash name: "iw4x $configuration", includes: "*.dll,*.pdb" + stash name: "$name", includes: "*.dll,*.pdb" } } @@ -69,10 +69,10 @@ for (int i = 0; i < configurations.size(); i++) { def configuration = configurations[i] executions["$configuration"] = { - doBuild("", configuration) + doBuild("IW4x $configuration", "", configuration) } executions["$configuration Unit-Testing"] = { - doBuild("--force-unit-tests", configuration) + doBuild("IW4x $configuration with unit tests", "--force-unit-tests", configuration) } } parallel executions From ebad081b04021c24e660477e61984329d9883745 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 02:54:46 +0200 Subject: [PATCH 12/46] Jenkinsfile: Implement unit testing. --- Jenkinsfile | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 471ab9d4..3c14b55c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -62,6 +62,45 @@ def doBuild(name, premakeFlags, configuration) { } } +// This will run the unit tests for IW4x. +// We need a Windows Server with MW2 on it. +def doUnitTests(name) { + node("windows") { + checkout scm + + 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 + bat """ + mklink /J \"main\" \"$mw2dir\\main\" + 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 + bat "iw4x.exe -tests" + } + } finally { + // In all cases make sure to at least remove the directory junctions! + bat """ + rmdir \"main\" + rmdir \"zone\\dlc\" + rmdir \"zone\\$localization\" + """ + } + } +} + // For each available configuration generate a normal build and a unit test build. stage "Build" def executions = [:] @@ -71,9 +110,20 @@ for (int i = 0; i < configurations.size(); i++) executions["$configuration"] = { doBuild("IW4x $configuration", "", configuration) } - executions["$configuration Unit-Testing"] = { - doBuild("IW4x $configuration with unit tests", "--force-unit-tests", configuration) + executions["$configuration with unit tests"] = { + doBuild("IW4x $configuration (unit tests)", "--force-unit-tests", configuration) } } parallel executions +// Run unit tests on each configuration. +stage "Testing" +def executions = [:] +for (int i = 0; i < configurations.size(); i++) +{ + def configuration = configurations[i] + executions["$configuration"] = { + doUnitTests("IW4x $configuration with unit tests") + } +} +parallel executions From 7dd069fbc90d8818c73a279d74c1cd6ceee444c2 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 02:55:08 +0200 Subject: [PATCH 13/46] Jenkinsfile: Implement versioning. --- Jenkinsfile | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 3c14b55c..33000e85 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -101,6 +101,16 @@ def doUnitTests(name) { } } +// Change build name to correct version +stage "Versioning" +node("windows") { + checkout scm + + version = sh(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" def executions = [:] From 71ca2f9a58fa7da53659f29f3183e0bcf739d8cc Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 02:56:00 +0200 Subject: [PATCH 14/46] Jenkinsfile: Fix artifacts by putting binaries for each configuration into separate subfolders. --- Jenkinsfile | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 33000e85..1258925a 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -57,7 +57,6 @@ def doBuild(name, premakeFlags, configuration) { bat "\"${msbuild}\" build\\iw4x.sln \"/p:OutDir=$outputDir\\\\\" \"/p:Configuration=$configuration\"" } - archiveArtifacts artifacts: "*.dll,*.pdb", fingerprint: true stash name: "$name", includes: "*.dll,*.pdb" } } @@ -137,3 +136,16 @@ for (int i = 0; i < configurations.size(); i++) } } parallel executions + +// Collect all the binaries and give each configuration its own subfolder +stage "Publishing" +node("windows") { // any node will do + for (int i = 0; i < configurations.size(); i++) + { + def configuration = configurations[i] + dir("$configuration") { + unstash "IW4x $configuration" + } + } + archiveArtifacts artifacts: "**/*.dll,**/*.pdb", fingerprint: true +} \ No newline at end of file From 65a10144a7d47aedcd2ccd52d9dfa638dd0ab268 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 02:57:10 +0200 Subject: [PATCH 15/46] Jenkinsfile: "The current scope already contains a variable of the name executions" --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 1258925a..2c8beafd 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -127,7 +127,7 @@ parallel executions // Run unit tests on each configuration. stage "Testing" -def executions = [:] +executions = [:] for (int i = 0; i < configurations.size(); i++) { def configuration = configurations[i] From ee936a9a3ad1cdbe48572009519261babc0ee1a4 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 03:00:17 +0200 Subject: [PATCH 16/46] Jenkinsfile: This is Windows, not Linux. --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 2c8beafd..609247a7 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -105,7 +105,7 @@ stage "Versioning" node("windows") { checkout scm - version = sh(returnStdout: true, script: 'premake5 version').split("\r?\n")[1] + version = bat(returnStdout: true, script: 'premake5 version').split("\r?\n")[1] currentBuild.setDisplayName "$version (#${env.BUILD_NUMBER})" } From 7c554962eda64db892d3abd129a805a121135ca3 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 03:03:35 +0200 Subject: [PATCH 17/46] Jenkinsfile: Yeah, let's not use deprecated code patterns. --- Jenkinsfile | 80 ++++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 609247a7..8da40224 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -100,52 +100,56 @@ def doUnitTests(name) { } } -// Change build name to correct version -stage "Versioning" -node("windows") { - checkout scm +// First though let's give this build a proper name +stage "Checkout & Versioning" { + node("windows") { + checkout scm - version = bat(returnStdout: true, script: 'premake5 version').split("\r?\n")[1] + version = bat(returnStdout: true, script: 'premake5 version').split("\r?\n")[1] - currentBuild.setDisplayName "$version (#${env.BUILD_NUMBER})" + currentBuild.setDisplayName "$version (#${env.BUILD_NUMBER})" + } } // For each available configuration generate a normal build and a unit test build. -stage "Build" -def executions = [:] -for (int i = 0; i < configurations.size(); i++) -{ - def configuration = configurations[i] - executions["$configuration"] = { - doBuild("IW4x $configuration", "", configuration) - } - executions["$configuration with unit tests"] = { - doBuild("IW4x $configuration (unit tests)", "--force-unit-tests", configuration) - } -} -parallel executions - -// Run unit tests on each configuration. -stage "Testing" -executions = [:] -for (int i = 0; i < configurations.size(); i++) -{ - def configuration = configurations[i] - executions["$configuration"] = { - doUnitTests("IW4x $configuration with unit tests") - } -} -parallel executions - -// Collect all the binaries and give each configuration its own subfolder -stage "Publishing" -node("windows") { // any node will do +stage "Build" { + def executions = [:] for (int i = 0; i < configurations.size(); i++) { def configuration = configurations[i] - dir("$configuration") { - unstash "IW4x $configuration" + executions["$configuration"] = { + doBuild("IW4x $configuration", "", configuration) + } + executions["$configuration with unit tests"] = { + doBuild("IW4x $configuration (unit tests)", "--force-unit-tests", configuration) } } - archiveArtifacts artifacts: "**/*.dll,**/*.pdb", fingerprint: true + parallel executions +} + +// Run unit tests on each configuration. +stage "Testing" { + executions = [:] + for (int i = 0; i < configurations.size(); i++) + { + def configuration = configurations[i] + executions["$configuration"] = { + doUnitTests("IW4x $configuration with unit tests") + } + } + parallel executions +} + +// Collect all the binaries and give each configuration its own subfolder +stage "Publishing" { + node("windows") { // any node will do + for (int i = 0; i < configurations.size(); i++) + { + def configuration = configurations[i] + dir("$configuration") { + unstash "IW4x $configuration" + } + } + archiveArtifacts artifacts: "**/*.dll,**/*.pdb", fingerprint: true + } } \ No newline at end of file From 283a747352a38b7d2dbbbfaf188bbe66bf9e31ad Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 03:04:39 +0200 Subject: [PATCH 18/46] Jenkinsfile: ()()()()()()()()()()()()()()()() --- Jenkinsfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 8da40224..35f6aec3 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -101,7 +101,7 @@ def doUnitTests(name) { } // First though let's give this build a proper name -stage "Checkout & Versioning" { +stage("Checkout & Versioning") { node("windows") { checkout scm @@ -112,7 +112,7 @@ stage "Checkout & Versioning" { } // For each available configuration generate a normal build and a unit test build. -stage "Build" { +stage("Build") { def executions = [:] for (int i = 0; i < configurations.size(); i++) { @@ -128,7 +128,7 @@ stage "Build" { } // Run unit tests on each configuration. -stage "Testing" { +stage("Testing") { executions = [:] for (int i = 0; i < configurations.size(); i++) { @@ -141,7 +141,7 @@ stage "Testing" { } // Collect all the binaries and give each configuration its own subfolder -stage "Publishing" { +stage("Publishing") { node("windows") { // any node will do for (int i = 0; i < configurations.size(); i++) { From 45a633e672a241fe6a5d84012d4ad0ed15430722 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 03:07:56 +0200 Subject: [PATCH 19/46] Jenkinsfile: Put shipped Premake5 into PATH. --- Jenkinsfile | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 35f6aec3..dbc4055e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -42,15 +42,19 @@ import groovy.transform.Field "ReleaseStatic" ] +def useShippedPremake(f) { + def premakeHome = "${pwd()}\\tools" + + withEnv(["PATH+=${premakeHome}"], f) +} + // This will build the IW4x client. // We need a Windows Server with Visual Studio 2015, Premake5 and Git on it. def doBuild(name, premakeFlags, configuration) { node("windows") { checkout scm - premakeHome = "${pwd()}\\tools" - - withEnv(["PATH+=${premakeHome}"]) { + useShippedPremake { def outputDir = pwd() def msbuild = tool "Microsoft.NET MSBuild 14.0" bat "premake5 vs2015 $premakeFlags" @@ -105,9 +109,11 @@ stage("Checkout & Versioning") { node("windows") { checkout scm - version = bat(returnStdout: true, script: 'premake5 version').split("\r?\n")[1] + useShippedPremake { + def version = bat(returnStdout: true, script: 'premake5 version').split("\r?\n")[1] - currentBuild.setDisplayName "$version (#${env.BUILD_NUMBER})" + currentBuild.setDisplayName "$version (#${env.BUILD_NUMBER})" + } } } From ca190a3a807968db10c42841a418d57d98c4b481 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 03:10:33 +0200 Subject: [PATCH 20/46] Jenkinsfile: Versioning, mute the shell crap. --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index dbc4055e..b0d44feb 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -110,7 +110,7 @@ stage("Checkout & Versioning") { checkout scm useShippedPremake { - def version = bat(returnStdout: true, script: 'premake5 version').split("\r?\n")[1] + def version = bat(returnStdout: true, script: '@premake5 version').split("\r?\n")[1] currentBuild.setDisplayName "$version (#${env.BUILD_NUMBER})" } From baf1107a18d1a440865deafdfe85943d146f3fa5 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 03:17:02 +0200 Subject: [PATCH 21/46] Jenkinsfile: Allocate separate workspaces for each build configuration. --- Jenkinsfile | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index b0d44feb..19ad9427 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -50,18 +50,20 @@ def useShippedPremake(f) { // This will build the IW4x client. // We need a Windows Server with Visual Studio 2015, Premake5 and Git on it. -def doBuild(name, premakeFlags, configuration) { +def doBuild(name, wsid, premakeFlags, configuration) { node("windows") { - checkout scm + ws("./$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\"" + 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" } - - stash name: "$name", includes: "*.dll,*.pdb" } } @@ -124,10 +126,10 @@ stage("Build") { { def configuration = configurations[i] executions["$configuration"] = { - doBuild("IW4x $configuration", "", configuration) + doBuild("IW4x $configuration", "$configuration", "", configuration) } executions["$configuration with unit tests"] = { - doBuild("IW4x $configuration (unit tests)", "--force-unit-tests", configuration) + doBuild("IW4x $configuration (unit tests)", "$configuration+unittests", "--force-unit-tests", configuration) } } parallel executions From d6eed080177258df25eaa756cad44e3242f14925 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 07:15:22 +0200 Subject: [PATCH 22/46] Jenkinsfile: Fix unstashing for testing. --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 19ad9427..b3600f8d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -142,7 +142,7 @@ stage("Testing") { { def configuration = configurations[i] executions["$configuration"] = { - doUnitTests("IW4x $configuration with unit tests") + doUnitTests("IW4x $configuration (unit tests)") } } parallel executions From 1b9478bd26a57044db73ba993b091e5552fe8a2c Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 07:26:50 +0200 Subject: [PATCH 23/46] Jenkinsfile: Ensure zone folder exists. --- Jenkinsfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Jenkinsfile b/Jenkinsfile index b3600f8d..473fe401 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -85,6 +85,7 @@ def doUnitTests(name) { // Set up environment 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\" From 0531ac6d2de01ec8886c31bc593a99f217116cdd Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 22:47:27 +0200 Subject: [PATCH 24/46] Jenkinsfile: Use IW4x entrypoint executable from its respective job. --- Jenkinsfile | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 473fe401..6ba830cd 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -48,6 +48,21 @@ def useShippedPremake(f) { 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) { @@ -94,6 +109,7 @@ def doUnitTests(name) { """ // Run tests + getIW4xExecutable() bat "iw4x.exe -tests" } } finally { From afbd8f13caba2935fef8fb52a622e7956e808bab Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 23:07:48 +0200 Subject: [PATCH 25/46] Jenkinsfile: Fix map syntax error. --- Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 6ba830cd..455dde06 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -49,7 +49,7 @@ def useShippedPremake(f) { } def getIW4xExecutable() { - step [ + step([ $class: 'CopyArtifact', filter: '*', fingerprintArtifacts: true, @@ -60,7 +60,7 @@ def getIW4xExecutable() { fallbackToLastSuccessful: true, upstreamFilterStrategy: 'UseGlobalSetting' ] - ] + ]) } // This will build the IW4x client. From e18ac7be16b752f9216e40eb5092814fc35e1972 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Tue, 13 Sep 2016 23:52:15 +0200 Subject: [PATCH 26/46] Singleton: Allow multiple IW4x instances non-interactively when unit testing. --- src/Components/Modules/Singleton.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Modules/Singleton.cpp b/src/Components/Modules/Singleton.cpp index 1a50fa5b..1d5ba1b1 100644 --- a/src/Components/Modules/Singleton.cpp +++ b/src/Components/Modules/Singleton.cpp @@ -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); From 54f21d5a5dc514ef55c9f6e09b4a9efd0d4802d7 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Wed, 14 Sep 2016 08:08:48 +0200 Subject: [PATCH 27/46] Do not upload minidumps when running unit tests or zone builder. --- src/Components/Modules/BitMessage.cpp | 20 ++++++++++---------- src/Components/Modules/MinidumpUpload.cpp | 1 + 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/Components/Modules/BitMessage.cpp b/src/Components/Modules/BitMessage.cpp index 7a2e6cb4..76d44476 100644 --- a/src/Components/Modules/BitMessage.cpp +++ b/src/Components/Modules/BitMessage.cpp @@ -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 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 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 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; diff --git a/src/Components/Modules/MinidumpUpload.cpp b/src/Components/Modules/MinidumpUpload.cpp index 89da69a8..c50421fb 100644 --- a/src/Components/Modules/MinidumpUpload.cpp +++ b/src/Components/Modules/MinidumpUpload.cpp @@ -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 } From d53650dbe7ef213afa0cc572cfbbcacff6bb3385 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Wed, 14 Sep 2016 08:35:57 +0200 Subject: [PATCH 28/46] Jenkinsfile: Use separate workspaces and clean them up. --- Jenkinsfile | 79 +++++++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 455dde06..7ed4b29c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -67,7 +67,7 @@ def getIW4xExecutable() { // We need a Windows Server with Visual Studio 2015, Premake5 and Git on it. def doBuild(name, wsid, premakeFlags, configuration) { node("windows") { - ws("./$wsid") { + ws("IW4x/build/$wsid") { checkout scm useShippedPremake { @@ -84,41 +84,44 @@ def doBuild(name, wsid, premakeFlags, configuration) { // This will run the unit tests for IW4x. // We need a Windows Server with MW2 on it. -def doUnitTests(name) { +def doUnitTests(name, wsid) { node("windows") { - checkout scm + ws("IW4x/testing/$wsid") { + checkout scm - mw2dir = tool "Modern Warfare 2" + mw2dir = tool "Modern Warfare 2" - unstash "$name" + unstash "$name" - // Get installed localization for correct zonefiles directory junction - def localization = readFile("$mw2dir\\localization.txt").split("\r?\n")[0] + // 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 + try { + timeout(time: 180, unit: "MINUTES") { + // Set up environment + 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() + bat "iw4x.exe -tests" + } + } finally { + // In all cases make sure to at least remove the directory junctions! 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\" + rmdir \"main\" + rmdir \"zone\\dlc\" + rmdir \"zone\\$localization\" """ - - // Run tests - getIW4xExecutable() - bat "iw4x.exe -tests" + deleteDir() } - } finally { - // In all cases make sure to at least remove the directory junctions! - bat """ - rmdir \"main\" - rmdir \"zone\\dlc\" - rmdir \"zone\\$localization\" - """ } } } @@ -159,7 +162,7 @@ stage("Testing") { { def configuration = configurations[i] executions["$configuration"] = { - doUnitTests("IW4x $configuration (unit tests)") + doUnitTests("IW4x $configuration (unit tests)", configuration) } } parallel executions @@ -168,13 +171,19 @@ stage("Testing") { // Collect all the binaries and give each configuration its own subfolder stage("Publishing") { node("windows") { // any node will do - for (int i = 0; i < configurations.size(); i++) - { - def configuration = configurations[i] - dir("$configuration") { - unstash "IW4x $configuration" + 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 + } catch { + deleteDir() } } - archiveArtifacts artifacts: "**/*.dll,**/*.pdb", fingerprint: true } } \ No newline at end of file From 8eb34fbdb450dbd01010d124568e94d19d87413e Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Wed, 14 Sep 2016 08:38:29 +0200 Subject: [PATCH 29/46] Jenkinsfile: This is meant to say "finally", not "catch". --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 7ed4b29c..efe75e29 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -181,7 +181,7 @@ stage("Publishing") { } } archiveArtifacts artifacts: "**/*.dll,**/*.pdb", fingerprint: true - } catch { + } finally { deleteDir() } } From d0702cffc57210f0ec27caec71ca0a1612bc8fdd Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Wed, 14 Sep 2016 21:13:14 +0200 Subject: [PATCH 30/46] Jenkinsfile: Forward commit status to GitLab. --- Jenkinsfile | 74 +++++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index efe75e29..c82d44f3 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -128,61 +128,69 @@ def doUnitTests(name, wsid) { // First though let's give this build a proper name stage("Checkout & Versioning") { - node("windows") { - checkout scm + gitlabCommitStatus("Checkout & Versioning") { + node("windows") { + checkout scm - useShippedPremake { - def version = bat(returnStdout: true, script: '@premake5 version').split("\r?\n")[1] + useShippedPremake { + def version = bat(returnStdout: true, script: '@premake5 version').split("\r?\n")[1] - currentBuild.setDisplayName "$version (#${env.BUILD_NUMBER})" + currentBuild.setDisplayName "$version (#${env.BUILD_NUMBER})" + } } } } // For each available configuration generate a normal build and a unit test build. stage("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) + 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 } - parallel executions } // Run unit tests on each configuration. stage("Testing") { - executions = [:] - for (int i = 0; i < configurations.size(); i++) - { - def configuration = configurations[i] - executions["$configuration"] = { - doUnitTests("IW4x $configuration (unit tests)", configuration) + gitlabCommitStatus("Testing") { + executions = [:] + for (int i = 0; i < configurations.size(); i++) + { + def configuration = configurations[i] + executions["$configuration"] = { + doUnitTests("IW4x $configuration (unit tests)", configuration) + } } + parallel executions } - parallel executions } // Collect all the binaries and give each configuration its own subfolder stage("Publishing") { - 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" + gitlabCommitStatus("Publishing") { + 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() } - archiveArtifacts artifacts: "**/*.dll,**/*.pdb", fingerprint: true - } finally { - deleteDir() } } } From 9fc98ad5b0c8c19f3ee133c4d06eb5107b766fa8 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Wed, 14 Sep 2016 22:33:19 +0200 Subject: [PATCH 31/46] Jenkinsfile: Fix GitLab commit status forwarding. --- Jenkinsfile | 98 +++++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 48 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index c82d44f3..123bd6b6 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -126,70 +126,72 @@ def doUnitTests(name, wsid) { } } -// First though let's give this build a proper name -stage("Checkout & Versioning") { - gitlabCommitStatus("Checkout & Versioning") { - node("windows") { - checkout scm +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] + useShippedPremake { + def version = bat(returnStdout: true, script: '@premake5 version').split("\r?\n")[1] - currentBuild.setDisplayName "$version (#${env.BUILD_NUMBER})" + 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) + // 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 } - 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"] = { - doUnitTests("IW4x $configuration (unit tests)", configuration) + // 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"] = { + doUnitTests("IW4x $configuration (unit tests)", configuration) + } } + parallel executions } - parallel executions } -} -// Collect all the binaries and give each configuration its own subfolder -stage("Publishing") { - gitlabCommitStatus("Publishing") { - 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" + // 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() } - archiveArtifacts artifacts: "**/*.dll,**/*.pdb", fingerprint: true - } finally { - deleteDir() } } } From 078873436a31ee03cfc8345b137125ee98d5c93a Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Wed, 14 Sep 2016 22:43:29 +0200 Subject: [PATCH 32/46] Jenkinsfile: Add missing job property specifying GitLab connection to report build status to. --- Jenkinsfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index 123bd6b6..3bcd3c7d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -126,6 +126,11 @@ def doUnitTests(name, wsid) { } } +// 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") { From ab395559356e1ee1d41f7b0c9b5167e517fb0569 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Wed, 14 Sep 2016 22:52:59 +0200 Subject: [PATCH 33/46] Jenkinsfile: Fix job property definition. --- Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 3bcd3c7d..cef3cd1c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -127,9 +127,9 @@ def doUnitTests(name, wsid) { } // Job properties -properties: [ +properties([ [$class: "GitLabConnectionProperty", gitLabConnection: "sr0"] -] +]) gitlabBuilds(builds: ["Checkout & Versioning", "Build", "Testing", "Archiving"]) { // First though let's give this build a proper name From 93b408412f46566d99e7460f8ca78f4c91416857 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Thu, 15 Sep 2016 00:02:50 +0200 Subject: [PATCH 34/46] Jenkinsfile: SCM checkout is unnecessary during unit tests. --- Jenkinsfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index cef3cd1c..c386bf10 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -87,8 +87,6 @@ def doBuild(name, wsid, premakeFlags, configuration) { def doUnitTests(name, wsid) { node("windows") { ws("IW4x/testing/$wsid") { - checkout scm - mw2dir = tool "Modern Warfare 2" unstash "$name" From c8cf116a781a0f462dfeb5accd6d36bac82d3ea7 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Thu, 15 Sep 2016 00:07:21 +0200 Subject: [PATCH 35/46] Update README to point to new status badge. From 06561ac143c864b59b9ecc2268137f49bd749497 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Thu, 15 Sep 2016 08:25:12 +0200 Subject: [PATCH 36/46] Jenkinsfile: Attempt on unit testing on Linux. --- Jenkinsfile | 59 ++++++++++++++++++++++++++++----------- jenkins/wine32.Dockerfile | 37 ++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 17 deletions(-) create mode 100644 jenkins/wine32.Dockerfile diff --git a/Jenkinsfile b/Jenkinsfile index c386bf10..fe4c178b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -84,19 +84,29 @@ def doBuild(name, wsid, premakeFlags, configuration) { // This will run the unit tests for IW4x. // We need a Windows Server with MW2 on it. -def doUnitTests(name, wsid) { - node("windows") { - ws("IW4x/testing/$wsid") { - mw2dir = tool "Modern Warfare 2" +def doUnitTests(label, name, wsid) { + ws("IW4x/testing/$wsid") { + mw2dir = tool "Modern Warfare 2" - unstash "$name" + unstash "$name" - // Get installed localization for correct zonefiles directory junction - def localization = readFile("$mw2dir\\localization.txt").split("\r?\n")[0] + // 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 + 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\" @@ -106,20 +116,26 @@ def doUnitTests(name, wsid) { copy /y \"$mw2dir\\*.txt\" copy /y \"$mw2dir\\*.bmp\" """ + } - // Run tests - getIW4xExecutable() + // 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! + } + } 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() } + deleteDir() } } } @@ -170,8 +186,17 @@ gitlabBuilds(builds: ["Checkout & Versioning", "Build", "Testing", "Archiving"]) for (int i = 0; i < configurations.size(); i++) { def configuration = configurations[i] - executions["$configuration"] = { - doUnitTests("IW4x $configuration (unit tests)", configuration) + executions["$configuration on Windows"] = { + node("windows") { + doUnitTests("IW4x $configuration (unit tests)", configuration) + } + } + executions["$configuration on Linux"] = { + node("docker && linux && amd64") { + docker.build("", "--rm --force-rm -f jenkins/wine32.Dockerfile").inside { + doUnitTests("IW4x $configuration (unit tests)", configuration) + } + } } } parallel executions diff --git a/jenkins/wine32.Dockerfile b/jenkins/wine32.Dockerfile new file mode 100644 index 00000000..1061c8e5 --- /dev/null +++ b/jenkins/wine32.Dockerfile @@ -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 From 123665e0d144bad8410cf428c78f7d5e1c1b8d69 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Thu, 15 Sep 2016 08:40:51 +0200 Subject: [PATCH 37/46] Jenkinsfile: I guess we need a tag name for the built image for now. --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index fe4c178b..ec6a69d5 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -193,7 +193,7 @@ gitlabBuilds(builds: ["Checkout & Versioning", "Build", "Testing", "Archiving"]) } executions["$configuration on Linux"] = { node("docker && linux && amd64") { - docker.build("", "--rm --force-rm -f jenkins/wine32.Dockerfile").inside { + docker.build("github.com/IW4x/iw4x-client-testing-wine32", "--rm --force-rm -f jenkins/wine32.Dockerfile").inside { doUnitTests("IW4x $configuration (unit tests)", configuration) } } From 3cacb0ca768211456ad524b4dc33cae3a5e4ab38 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Thu, 15 Sep 2016 18:30:31 +0200 Subject: [PATCH 38/46] Jenkinsfile: Fix Docker image build parameters. --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index ec6a69d5..6fab82ce 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -193,7 +193,7 @@ gitlabBuilds(builds: ["Checkout & Versioning", "Build", "Testing", "Archiving"]) } executions["$configuration on Linux"] = { node("docker && linux && amd64") { - docker.build("github.com/IW4x/iw4x-client-testing-wine32", "--rm --force-rm -f jenkins/wine32.Dockerfile").inside { + docker.build("github.com/IW4x/iw4x-client-testing-wine32", "--rm --force-rm -f wine32.Dockerfile jenkins").inside { doUnitTests("IW4x $configuration (unit tests)", configuration) } } From 92b9a4b856de883dbca58696d7937deb817c6c67 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Thu, 15 Sep 2016 18:55:43 +0200 Subject: [PATCH 39/46] Jenkinsfile: Wrong function signature. --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 6fab82ce..1fe77dfa 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -84,7 +84,7 @@ def doBuild(name, wsid, premakeFlags, configuration) { // This will run the unit tests for IW4x. // We need a Windows Server with MW2 on it. -def doUnitTests(label, name, wsid) { +def doUnitTests(name, wsid) { ws("IW4x/testing/$wsid") { mw2dir = tool "Modern Warfare 2" From c90290992375ba5a4cef8a5ccb762fa523bc4b44 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Thu, 15 Sep 2016 19:05:33 +0200 Subject: [PATCH 40/46] Jenkinsfile: Make Dockerfile available at testing phase. --- Jenkinsfile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 1fe77dfa..75c34733 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -193,7 +193,13 @@ gitlabBuilds(builds: ["Checkout & Versioning", "Build", "Testing", "Archiving"]) } executions["$configuration on Linux"] = { node("docker && linux && amd64") { - docker.build("github.com/IW4x/iw4x-client-testing-wine32", "--rm --force-rm -f wine32.Dockerfile jenkins").inside { + def image = null + dir("src") { + checkout scm + image = docker.build("github.com/IW4x/iw4x-client-testing-wine32", "--rm --force-rm -f wine32.Dockerfile jenkins") + deleteDir() + } + image.inside { doUnitTests("IW4x $configuration (unit tests)", configuration) } } From f5f128313f976d1e0c72cbbc51984b9df9fd7c3c Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Thu, 15 Sep 2016 20:42:59 +0200 Subject: [PATCH 41/46] Jenkinsfile: Workaround for Jenkins bug regarding changing dir in Docker container and path fix. --- Jenkinsfile | 95 +++++++++++++++++++++++++++-------------------------- 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 75c34733..801dbca5 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -85,58 +85,57 @@ def doBuild(name, wsid, premakeFlags, configuration) { // This will run the unit tests for IW4x. // We need a Windows Server with MW2 on it. def doUnitTests(name, wsid) { - ws("IW4x/testing/$wsid") { - mw2dir = tool "Modern Warfare 2" + mw2dir = tool "Modern Warfare 2" - unstash "$name" + unstash "$name" - // Get installed localization for correct zonefiles directory junction - def localization = readFile("$mw2dir/localization.txt").split("\r?\n")[0] + // 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()) { + 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 """ - rmdir \"main\" - rmdir \"zone\\dlc\" - rmdir \"zone\\$localization\" + 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\" """ } - deleteDir() + + // Run tests + getIW4xExecutable() + if (isUnix()) { + sh "ls" + 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() } } @@ -188,7 +187,9 @@ gitlabBuilds(builds: ["Checkout & Versioning", "Build", "Testing", "Archiving"]) def configuration = configurations[i] executions["$configuration on Windows"] = { node("windows") { - doUnitTests("IW4x $configuration (unit tests)", configuration) + ws("IW4x/testing/$wsid") { + doUnitTests("IW4x $configuration (unit tests)", configuration) + } } } executions["$configuration on Linux"] = { @@ -196,7 +197,7 @@ gitlabBuilds(builds: ["Checkout & Versioning", "Build", "Testing", "Archiving"]) def image = null dir("src") { checkout scm - image = docker.build("github.com/IW4x/iw4x-client-testing-wine32", "--rm --force-rm -f wine32.Dockerfile jenkins") + image = docker.build("github.com/IW4x/iw4x-client-testing-wine32", "--rm --force-rm -f jenkins/wine32.Dockerfile jenkins") deleteDir() } image.inside { From 43aa45a95d2b004ffc397c5c51f28e4157230510 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Thu, 15 Sep 2016 20:54:10 +0200 Subject: [PATCH 42/46] Yay, new status badges! --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4d4c5409..51e08bf2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ -# IW4x: Client +# IW4x: Client + ## How to compile From 34950dde3bd3924c9dfdaed238ba0e6ab339b524 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Thu, 15 Sep 2016 21:09:40 +0200 Subject: [PATCH 43/46] Jenkinsfile: Variable fixes and removal of useless ls line. --- Jenkinsfile | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 801dbca5..c9d745b7 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -84,7 +84,7 @@ def doBuild(name, wsid, premakeFlags, configuration) { // This will run the unit tests for IW4x. // We need a Windows Server with MW2 on it. -def doUnitTests(name, wsid) { +def doUnitTests(name) { mw2dir = tool "Modern Warfare 2" unstash "$name" @@ -120,7 +120,6 @@ def doUnitTests(name, wsid) { // Run tests getIW4xExecutable() if (isUnix()) { - sh "ls" sh "wine-wrapper iw4x.exe -tests" } else { bat "iw4x.exe -tests" @@ -187,8 +186,8 @@ gitlabBuilds(builds: ["Checkout & Versioning", "Build", "Testing", "Archiving"]) def configuration = configurations[i] executions["$configuration on Windows"] = { node("windows") { - ws("IW4x/testing/$wsid") { - doUnitTests("IW4x $configuration (unit tests)", configuration) + ws("IW4x/testing/$configuration") { + doUnitTests("IW4x $configuration (unit tests)") } } } @@ -201,7 +200,7 @@ gitlabBuilds(builds: ["Checkout & Versioning", "Build", "Testing", "Archiving"]) deleteDir() } image.inside { - doUnitTests("IW4x $configuration (unit tests)", configuration) + doUnitTests("IW4x $configuration (unit tests)") } } } From 0c532c58f57afe4db612553c7c008a388d107268 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Thu, 15 Sep 2016 22:06:29 +0200 Subject: [PATCH 44/46] Jenkinsfile: Mark build as unstable and add warning text if test fails on Linux instead of failing the build. --- Jenkinsfile | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index c9d745b7..b13b19bb 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -181,8 +181,7 @@ gitlabBuilds(builds: ["Checkout & Versioning", "Build", "Testing", "Archiving"]) stage("Testing") { gitlabCommitStatus("Testing") { executions = [:] - for (int i = 0; i < configurations.size(); i++) - { + for (int i = 0; i < configurations.size(); i++) { def configuration = configurations[i] executions["$configuration on Windows"] = { node("windows") { @@ -205,7 +204,16 @@ gitlabBuilds(builds: ["Checkout & Versioning", "Build", "Testing", "Archiving"]) } } } - parallel executions + try { + parallel executions + } catch (Exception e) { + if (isUnix()) { + manager.buildUnstable() + manager.addWarningBadge "Unit tests failed on Linux" + } else { + throw e + } + } } } From a1de01474e013911bb99046e4138de3c675d98ac Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Thu, 15 Sep 2016 22:52:29 +0200 Subject: [PATCH 45/46] Jenkinsfile: Fix unstable status handling code. --- Jenkinsfile | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index b13b19bb..43e578c5 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -192,28 +192,28 @@ gitlabBuilds(builds: ["Checkout & Versioning", "Build", "Testing", "Archiving"]) } executions["$configuration on Linux"] = { node("docker && linux && amd64") { - 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)") + 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 + } } } } } - try { - parallel executions - } catch (Exception e) { - if (isUnix()) { - manager.buildUnstable() - manager.addWarningBadge "Unit tests failed on Linux" - } else { - throw e - } - } + parallel executions } } From 44c8b98283760112f36919eb4f0ee4b6ad0b7316 Mon Sep 17 00:00:00 2001 From: /dev/urandom Date: Thu, 15 Sep 2016 23:08:24 +0200 Subject: [PATCH 46/46] Remove jenkins branch from README. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 51e08bf2..383509be 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # IW4x: Client - ## How to compile - Run `premake5 vs2015` or use the delivered `generate.bat`.