Skip to content
This repository has been archived by the owner on Apr 17, 2019. It is now read-only.

New CI pipeline #1392

Merged
merged 9 commits into from
Jun 29, 2018
Merged

New CI pipeline #1392

merged 9 commits into from
Jun 29, 2018

Conversation

tyvision
Copy link
Contributor

@tyvision tyvision commented May 29, 2018

Description of the Change

This PR is created to finally make our CI satisfy proposed requirements by our developers team.

1 Major changes

1.1 Pipeline stages

Since now, the Pipeline consists of 6 stages. You can see the ascii-art pipeline version in the Jenkinsfile

Stage Description
Pre-build Cancels previous build job (except if current branch is develop)
Build Build step for all platforms (currently ARMv7, ARMv8, x86_64, MacOS are present)
Pre-coverage Launch coverage target before running tests
Tests Run required tests for specified platforms
Post-Coverage Run coverage after tests step
Build rest Build (if required): 1) documentation 2) bindings 3) release version of iroha

This division is made to improve visibility of the CI build process.
Stage separation is implemented in Jenkinsfile. All stage methods are implemented in .jenkinsci/debug-build.groovy, .jenkinsci/release-build.groovy, .jenkinsci/mac-debug-build.groovy, .jenkinsci/mac-release-build.groovy (note that MacOS build goes on the physical machine, not in the docker container, that's why there's another file for MacOS platform)

1.2 On-demand Jenkins agents

Since now x86_64 agents are moved to AWS EC2. There are 4 different labels added to the pipeline (note that it could be easily modified in Jenkins configuration):

  • x86_64_aws_build -- general purpose instance with 8 CPU, 32 Gb RAM (x86_64 builds in 8 threads)
  • x86_64_aws_test -- general purpose instance with 1 CPU, 2 Gb RAM for running tests
  • x86_64_aws_cov -- general purpose instance with 1 CPU, 2 Gb RAM for running coverage
  • x86_64_aws_sonar -- general purpose instance with 1 CPU, 2 Gb RAM for running sonarscanner

Now, the amount of x86_64 agents will be float, as their amount is managed by Jenkins.

Note: With migration to Amazon AWS EC2 on-demand agents the logic of some methods has been changed. The text below describes this change.

On-demand agent start-up process
Before freshly created and launched new AWS instance becomes the Jenkins agent, init script is executed. It mounts 4 folders via NFS share (AWS EFS - Amazon Elastic Filesystem).

  • Jenkins workspace (/var/jenkins)
  • cmake build cache (/opt/.ccache)
  • cmake release build cache (/opt/.ccache-release)
  • docker images storage (/tmp/docker)

On-demand agent pipeline lifecycle
In case the build occures on the x86_64* agent, the created docker image (stage Build) is saved to AWS EFS (Amazon Elastic Filesystem) using docker save -o command with file name /tmp/docker/<branch_name_sha1>. (see file .jenkinsci/docker-pull-or-build.groovy, method dockerPullOrUpdate()). When going to the next stage, new x86_64* agent is created, docker image is loaded from the file /tmp/docker/<branch_name_sha1> using docker load command.

After the stage finishes, the docker container is stopped and removed, results are saved to the Jenkins workspace (and to the AWS EFS respectively), thus, none of the data is lost.

1.3 Merge availability

To make CI available to perform automatic merge process the list of features should be implemented:

  • check merge requirements compliance
  • merge strategy

Merge requirements set in hyperledger/iroha repository:

  • at least 2 APPROVED reviews
  • CI checks are passed (armv7, armv8 are turned off in case of MergePR is chosen)
  • all commits are sign-off

Merge strategy regarding the branches:

  • trunk + develop -- squash & merge
  • master -- merge

All checks are made using Github API. To see the implementation, go to .jenkinsci/github-api.groovy file.

To merge, developer should go to Jenkins -> iroha -> iroha-hyperledger -> Pull Requests -> PR # -> Build with Parameters and set checkpoint for Merge_PR.

1.4 CI notifications

Build result notifications were added. Table below describes the notification scenario:

Scenario Behavior
Branch commit sends e-mail to git commit author
Open or Commit Pull Request posts comment with PR reviewers mention on the PR page
Merge to trunk sends e-mail to git commit author
Merge to develop sends e-mail to git commit author + Andrei + Fyodor
Merge to master sends e-mail to iroha-maintainers team

Notification e-mail contains compressed log in attachmens + build status.
see .jenkinsci/notifications.groovy,Jenkinsfile (cleanup post-step at the end of the file)

1.5 Tests launch separation

This feature is implemented as a method that returns regex string (file .jenkinsci/test-launcher.groovy)
This method is called in the Jenkinsfile stage Tests and its return string is passed as a parameter to the doTestStep() method. More detailed description of test types execution according to the build strategy is provided in the next section (1.6)

1.6 Default order of execution

Table contains requirements for order of pipeline execution.

Scenario Build Behavior Coverage Tests Packages Docs Bindings
Branch commit x86_64 gcc-5.4 build by request module tests by request by request by request
Open Pull Request x86_64 gcc-5.4, MacOS build for x86_64 module by request by request by request
Commit Pull Request x86_64 gcc-5.4 by request module by request by request by request
Merge to trunk all platforms by request module for all platforms. for x86_64 gcc-5.4 run integration, system, cmake, regression tests by request by request by request
Merge to develop all platforms by request module for all platforms. for x86_64 gcc-5.4 run integration, system, cmake, regression tests docker dev all all
Merge to master all platforms x86_64 gcc-5.4 module for all platforms. for x86_64 gcc-5.4 run integration, system, cmake, regression tests all all all
Nightly all platforms x86_64 gcc-5.4 for all platforms run integration, system, cmake, regression tests. for x86_64 gcc-5.4 run all tests *.deb, *.tar none all

2 Minor changes

  • Fixed absence of --output-on-failure flag on MacOS tests.
  • Modified post-step for whole CI allowed to fix execution logic
  • Fixed clean-up procedures:
    • separated linuxPostStep() method from jenkinsci/linux-post-step.groovy into postStep() and cleanUp() methods. postStep() method is authoritative for uploading artifacts after release build, when cleanUp() removes folders created during builds
    • fixed the call cases for the doDockerCleanup(). Now this method been called only from the pipeline's cleanup post-step, at armv7, armv8 agents.
    • fixed the stale docker images cleanup (IR-1293, IR-1451)

Benefits

  • reduced build time (~15-20 mins for branch commit, except branch commit with changes dockerfile, it takes additional 30-50 minutes)
  • automatic merge by CI
  • defined workflow that covers all scenario

Usage Examples or Tests [optional]

@tyvision tyvision requested review from muratovv, bakhtin and lebdron May 29, 2018 10:39
// This is a known bug. See https://issues.jenkins-ci.org/browse/JENKINS-41929
if (!parallelism) {
if (parallelism == null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, revert to !parallelism as it was fixed in previous commits. You have not merged properly, I suppose

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I've not rebased properly. It will be fixed in the next commit

@@ -19,7 +19,13 @@ def buildOptionsString(options) {

def dockerPullOrUpdate(imageName, currentDockerfileURL, previousDockerfileURL, referenceDockerfileURL, buildOptions=null) {
buildOptions = buildOptionsString(buildOptions)
// GIT_PREVIOUS_COMMIT is null for first PR build
if (!previousDockerfileURL) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition always returns true

@@ -53,62 +112,49 @@ def doDebugBuild(coverageEnabled=false) {
+ " -e IROHA_POSTGRES_USER=${env.IROHA_POSTGRES_USER}"
+ " -e IROHA_POSTGRES_PASSWORD=${env.IROHA_POSTGRES_PASSWORD}"
+ " --network=${env.IROHA_NETWORK}"
+ " -v /var/jenkins/ccache:${CCACHE_DIR}"
+ " -v ${CCACHE_DIR}:${CCACHE_DIR}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CCache here has no effect. It does not speed up tests

@@ -53,62 +112,49 @@ def doDebugBuild(coverageEnabled=false) {
+ " -e IROHA_POSTGRES_USER=${env.IROHA_POSTGRES_USER}"
+ " -e IROHA_POSTGRES_PASSWORD=${env.IROHA_POSTGRES_PASSWORD}"
+ " --network=${env.IROHA_NETWORK}"
+ " -v /var/jenkins/ccache:${CCACHE_DIR}"
+ " -v ${CCACHE_DIR}:${CCACHE_DIR}"
+ " -v /tmp/${GIT_COMMIT}-${BUILD_NUMBER}:/tmp/${GIT_COMMIT}") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to mount artifacts folder for tests stage

if ( env.NODE_NAME.contains('x86_64') ) {
sh "docker load -i ${JENKINS_DOCKER_IMAGE_DIR}/${dockerImageFile}"
}
def iC = docker.image("${dockerAgentImage}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable is only assigned if NODE_NAME contains x86_64. Thus, will not work on other agents. Review also other functions

Jenkinsfile Outdated
if ( params.BUILD_TYPE == 'Debug' || params.Merge_PR ) {
def debugBuild = load ".jenkinsci/debug-build.groovy"
def coverage = load ".jenkinsci/selected-branches-coverage.groovy"
if ( params.Merge_PR ) { debugBuild.doDebugBuild(true) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would coverage be collected twice: first on PR open and then on actual merge?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for master branch --> yes, it is according to the docs. Conditions are fixed in the next commit

Jenkinsfile Outdated
anyOf {
allOf {
expression { return env.CHANGE_ID != null }
not { expression { return env.GIT_PREVIOUS_COMMIT != null } }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double negation can be replaced with
{ expression { return ! env.GIT_PREVIOUS_COMMIT }
Also, seems that GIT_PREVIOUS_COMMIT variable value is not set on a newer versions of Jenkins' Git plugin on PR open. See Jenkins docs: older version vs newer version

Jenkinsfile Outdated
when {
expression { params.BUILD_TYPE == 'Release' }
beforeAgent true
anyOf {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be omitted

Jenkinsfile Outdated
steps {
script {
def cov_platform = ''
if (params.Linux) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe implement this platform selection as a separate function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

implemented in the .jenkinsci/choose-platform.groovy

Jenkinsfile Outdated
allOf {
expression { return env.CHANGE_ID != null}
expression { return env.GIT_PREVIOUS_COMMIT != null }
expression { return params.Merge_PR }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expression { return env.CHANGE_TARGET ==~ /(master|develop|trunk)/ } is not required here, why?

Copy link
Contributor Author

@tyvision tyvision May 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually we can remove the whole section when in parallel stages in Post-coverage as it is needless after when in Post-coverage

@l4l l4l added needs-review pr awaits review from maintainers infrastructure anything related to continious integration, building infrastructure, or cmake labels May 30, 2018
@tyvision tyvision force-pushed the feature/new-ci-pipeline branch 2 times, most recently from 3e808bd to 429fd96 Compare June 1, 2018 14:03
// params are always null unless job is started
// this is the case for the FIRST build only.
// So just set this to same value as default.
// So just set this to same value as default.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant space.


def choosePlatform() {
if (params.Merge_PR) {
return 'x86_64_aws_cov'
Copy link
Contributor

@muratovv muratovv Jun 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of string literals better to use enums. This change improves readability and reduces type errors based on the type system.

#!/usr/bin/env groovy

def choosePlatform() {
if (params.Merge_PR) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix indentation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bakhtin fixed

@@ -19,65 +19,59 @@ def buildOptionsString(options) {

def dockerPullOrUpdate(imageName, currentDockerfileURL, previousDockerfileURL, referenceDockerfileURL, buildOptions=null) {
buildOptions = buildOptionsString(buildOptions)
def uploadExitCode = 0
// GIT_PREVIOUS_COMMIT is null for first PR build
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think you can simply remove this block. You should check whether previousDockerfileURL is null. Otherwise, you end up querying URL with literal null string in it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bakhtin I think we can as previousDockerfileURL passed to the dockerPullOrBuild() method is built from pCommit variable, which cannot be null, otherwise it's out of scope of method dockerPullOrBuild() and should be fixed in the .jenkinsci/previous-commit.groovy previousCommitOrCurrent() method

sh "echo 'Reference image ${DOCKER_REGISTRY_BASENAME}:${imageName} doesn't exist on the EFS"
}
}
def pullExitCode = sh(script: "docker pull ${DOCKER_REGISTRY_BASENAME}:${imageName}", returnStatus: true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docker.image in the last else block makes implicit pull. No need to call it earlier explicitly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bakhtin no, it doesn't actually. No other docker pull commands are used inside dockerPullOrBuild() method

}
cleanWs()
}
// def linuxPostStep() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented out lines if they're not needed anymore

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bakhtin removed in the next commit

@@ -0,0 +1,113 @@
#!/usr/bin/env groovy

def mergePullRequest() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pls, add some description of methods because now it is not so obvious what really this method does.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@muratovv added

}
}

def checkMergeAcceptance() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, pls, add a description of the current method and for methods below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@muratovv added

jsonResponseReview = slurper.parseText(jsonResponseReview)
if (jsonResponseReview.size() > 0) {
jsonResponseReview.each {
if ("${it.state}" == "APPROVED") {
Copy link
Contributor

@muratovv muratovv Jun 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, we must forbid merge when someone "request changes" for the pull request.
Generally, we require 2 approves and zero "request changes" for pull requests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@muratovv good point, I will add this feature at the next commit


def getMergeMethod() {
if ( env.CHANGE_TARGET == 'master') {
return "merge"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, better to use enums for performing business logic instead of string literals.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@muratovv fixed

def slurper = new groovy.json.JsonSlurperClassic()
def jsonResponseComment = sh(script: """
curl -H "Authorization: token ${sorabot}" \
-H "Accept: application/vnd.github.v3+json" \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe better to make a separate function that will call Github API?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@muratovv no, as each API call is different:

  • GET, PUT, POST query
  • with or w/o token

// }
// }

def postStep() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add documentation for methods here.

def doDebugBuild(coverageEnabled=false) {
def parallelism = params.PARALLELISM
if (!parallelism) {
parallelism = 4
Copy link
Contributor

@muratovv muratovv Jun 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code looks suspicious. What is the point to make 4 threads in the non-parallel build?
Also, better to pass a number of threads in the function and create another one for calculating a number.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@muratovv now unique method in the file.jenkinsci/choose-platform.groovy called setParallelism is created. It is a silver bullet for the whole pipeline execution branches

}
}

def doPostCoverageCoberturaStep() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the point to duplicate code here and in debug-build file?

Copy link
Contributor Author

@tyvision tyvision Jun 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in debug-build.groovy the post-coverage is launched inside a docker-container. in mac-debug-build.groovy the post-coverage is launched on the host OS with the same logic.

Thus, in debug-build.groovy I can call doPostCoverageCoberturaStep from mac-debug-build.groovy to keep DRY. Will be changed in the next commit

@@ -1,6 +1,10 @@
#!/usr/bin/env groovy

def doReleaseBuild(coverageEnabled=false) {
def parallelism = params.PARALLELISM
if (!parallelism) {
parallelism = 4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same about threads.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@muratovv fixed

def chooseTestType() {
if (params.Merge_PR) {
if (env.NODE_NAME.contains('x86_64')) {
return "(module|integration|system|cmake|regression)*"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, better to write direct types in enums and operate on it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@muratovv fixed in the next commit

def printRange(start, end) {
def output = ""
for (type in start..end) {
output = [output, (type.name() != start.toString() ? "|" : ""), type.name()].join('')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

join() already implements the logic of not putting delimeter after the last element in the list.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bakhtin join() cannot work with enum. So we can either do as I proposed in the commit, either transform enum to string collection/tuple and use join() which is even more complex

}
}
return "module*"
// just choose module tests
return printRange(TestTypes.module, TestTypes.module)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A typo? Should be just return printRange(TestTypes.module) ?

# Check whether the image is the last-standing man
# i.e., no other tags exist for this image
docker rmi \$(docker images --no-trunc --format '{{.Repository}}:{{.Tag}}\\t{{.ID}}' | grep \$(docker images --no-trunc --format '{{.ID}}' ${iC.id}) | head -n -1 | cut -f 1) || true
sleep 5
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the point of sleep? Can we rework it with the synchronous check of rmi?
Maybe rework it in separate PR, if it is, pls add a task for that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@muratovv this is a required delay for docker engine to proceed the image removal. Actually, it's a kind of legacy from previous pipeline and left untouched

@@ -0,0 +1,10 @@
enum TestTypes {
module, integration, system, cmake, regression, benchmark, framework
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add explanation of types here.

}

enum CoveragePlatforms {
x86_64_aws_cov, mac, armv8, armv7
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add explanation of types here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@muratovv done

@@ -1,5 +1,16 @@
#!/usr/bin/env groovy

enum GithubPRStatus {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a documentation for this enum and enums below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@muratovv done

if (params.Merge_PR) {
return 'x86_64_aws_cov'
if (params.Merge_PR) {
return CoveragePlatforms.x86_64_aws_cov.toString()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the point of type erasure (return a string) instead of returning an enum value?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@muratovv agent label is a string type, thus, we need to return string

@@ -84,14 +103,15 @@ def getPullRequestReviewers() {
jsonResponseReview = slurper.parseText(jsonResponseReview)
if (jsonResponseReview.size() > 0) {
jsonResponseReview.each {
if ("${it.state}" == "APPROVED") {
if ("${it.state}" == GithubPRStatus.APPROVED.toString() || "${it.state}" == GithubPRStatus.CHANGES_REQUESTED.toString()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to clean up like this:

if( "${it.state}" in [GithubPRStatus.APPROVED.toString(), GithubPRStatus.CHANGES_REQUESTED.toString()])

@tyvision tyvision force-pushed the feature/new-ci-pipeline branch from e73340e to 5ede358 Compare June 16, 2018 09:06
Copy link
Contributor

@lebdron lebdron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would love to see the changes based on this review before another round of review, because it should reduce the code.

return CoveragePlatforms.x86_64_aws_cov.toString()
}
if (!params.Linux && params.MacOS) {
return CoveragePlatforms.mac.toString()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The requirement is to collect coverage only on gcc/Linux, so maybe mac, armv8, and armv7 can be removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lebdron according to the requirements, this file is not needed anymore. It's removed in the next commit

}
def iC = docker.image("${DOCKER_AGENT_IMAGE}")
iC.inside() {
def step = load ".jenkinsci/mac-debug-build.groovy"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for coverage, I don't think any other platform besides gcc/Linux is required.


// list of agent labels (build platforms) to count coverage (the choice depends on the build parameters)
enum CoveragePlatforms {
x86_64_aws_cov, mac, armv8, armv7
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for coverage, just leave x86_64_aws_cov ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lebdron removed. good point

@@ -0,0 +1,70 @@
def doDebugBuild(coverageEnabled=false) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flag should not be required ^^

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lebdron also fixed in the next commit

}

def doPostCoverageSonarStep() {
sh "cmake --build build --target cppcheck"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for cppcheck, the code analysis output should be the same if sent from mac os or Linux, so it should be only run in gcc/Linux.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All methods related to coverage are removed from the mac-debug-build.groovy file.

Jenkinsfile Outdated
booleanParam(defaultValue: false, description: '', name: 'ARMv7'),
booleanParam(defaultValue: false, description: '', name: 'ARMv8'),
booleanParam(defaultValue: false, description: '', name: 'MacOS'),
booleanParam(defaultValue: false, description: 'Whether it is a triggered build', name: 'Nightly'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove "whether" from titles, because the switches themselves imply this word, so it does not add any information.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

Jenkinsfile Outdated
if ( params.BUILD_TYPE == 'Debug' || params.Merge_PR ) {
def debugBuild = load ".jenkinsci/debug-build.groovy"
def coverage = load ".jenkinsci/selected-branches-coverage.groovy"
debugBuild.doDebugBuild( (!params.Linux && !params.MacOS || !params.Merge_PR) ? coverage.selectedBranchesCoverage() : false )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This conditional could be removed because of reasons above, same for calls for mac, armv7.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, now we can get rid of these complex conditions

Copy link
Contributor

@bakhtin bakhtin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GBTPR (God bless this PR)

"""
// cleanup docker images which weren't used for more that 20 days and image for this PR in case of successful PR
def doStaleDockerImagesCleanup() {
sh "find ${JENKINS_DOCKER_IMAGE_DIR} -type f -mtime +20 -exec rm -f {}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fails with an error on Ubuntu 16.04. Did you check this really works? I think it should end with \; after curly braces.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bakhtin Thanks for the report, I've missed \;. I've just checked it on the real files (AWS EFS) and it WORKS!

agent { label 'master' }
steps {
script {
load ".jenkinsci/enums.groovy"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Output of load is not used, consider removing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lebdron no, this is required to load static variable of enum. Output shouldn't be used here

Jenkinsfile Outdated
expression { return params.armv7_linux }
anyOf {
expression { return params.ARMv7 }
// allOf {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a TODO to fix issues and uncomment, with Jira task id. Same for ARMv8 below.

Jenkinsfile Outdated
cobertura autoUpdateHealth: false, autoUpdateStability: false, coberturaReportFile: '**/build/reports/coverage.xml', conditionalCoverageTargets: '75, 50, 0', failUnhealthy: false, failUnstable: false, lineCoverageTargets: '75, 50, 0', maxNumberOfBuilds: 50, methodCoverageTargets: '75, 50, 0', onlyStable: false, zoomCoverageChart: false
if ( params.BUILD_TYPE == 'Debug' || params.Merge_PR ) {
def macDebugBuild = load ".jenkinsci/mac-debug-build.groovy"
def coverage = load ".jenkinsci/selected-branches-coverage.groovy"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coverage is unused, please remove.

}

// upload artifacts in release builds (for mac)
def macPostStep() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File name is confusing (linux, but also contains mac methods), maybe rename the file or move the methods?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lebdron I've fixed the filename

Jenkinsfile Outdated
}
finally {
sh "rm -rf /tmp/${env.GIT_COMMIT}"
// cleanWs()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove if it is not required.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lebdron it was commented out by an accident

if (PRCoverage) {
return env.GIT_LOCAL_BRANCH in branches || env.CHANGE_ID != null
def pCommit = load ".jenkinsci/previous-commit.groovy"
def prevCommit = pCommit.previousCommitOrCurrent()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PREVIOUS_COMMIT environment variable defined in Jenkinsfile can be used intstead.

Jenkinsfile Outdated
else {
if ( params.BUILD_TYPE == 'Debug' || params.Merge_PR ) {
def debugBuild = load ".jenkinsci/debug-build.groovy"
def coverage = load ".jenkinsci/selected-branches-coverage.groovy"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove because it is unused.

Jenkinsfile Outdated
expression { return !env.GIT_PREVIOUS_COMMIT }
}
allOf {
expression { return env.CHANGE_ID != null }
Copy link
Contributor

@lebdron lebdron Jun 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After discussion with @tyvision we decided to move these complex conditions to separate variables as SOME_VAR = [[ env.CHANGE_ID != null && env.CHANGE_TARGET ==~ /(master|develop|trunk)/ ]], and then use them here. These variables will have documentation where they are defined, and the logic will not be duplicated in different stages.

@tyvision tyvision force-pushed the feature/new-ci-pipeline branch 2 times, most recently from 05c1810 to d4a43e4 Compare June 21, 2018 17:15
Copy link
Contributor

@muratovv muratovv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am very scared about this PR, but I don't have critical issues. I hope we will not revert this pr in develop branch.

if (!defaultParameter) {
return 4
}
if (env.NODE_NAME.contains('arm7')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like here is possible to use the enum with machine types

// return tests list regex that will be launched by ctest
def chooseTestType() {
if (params.merge_pr) {
if (env.NODE_NAME.contains('x86_64')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same about enums

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@muratovv My concern is to leave this update for the next PR on CI (not as major as this one)

expression { return params.armv7_linux }
anyOf {
expression { return params.armv7_linux }
// expression { return MERGE_CONDITIONS_SATISFIED == "true" }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the point of this line?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is disabled because current armv7 builds fail due to insufficient memory. Builds should be possible with cross-compilation, so this can serve as a reminder.

@tyvision tyvision force-pushed the feature/new-ci-pipeline branch from e4acb38 to ffdf15c Compare June 28, 2018 08:49
tyvision added 2 commits June 28, 2018 13:53
Signed-off-by: tyvision <[email protected]>
tyvision added 3 commits June 28, 2018 17:00
Signed-off-by: tyvision <[email protected]>
Signed-off-by: tyvision <[email protected]>
Signed-off-by: tyvision <[email protected]>
@l4l l4l removed the needs-review pr awaits review from maintainers label Jun 29, 2018
tyvision added 2 commits June 29, 2018 13:47
Signed-off-by: tyvision <[email protected]>
@sorabot sorabot merged commit 30cc22e into develop Jun 29, 2018
tyvision added a commit that referenced this pull request Jun 29, 2018
Signed-off-by: tyvision <[email protected]>
tyvision added a commit that referenced this pull request Jun 29, 2018
tyvision added a commit that referenced this pull request Jun 29, 2018
Signed-off-by: tyvision <[email protected]>
tyvision added a commit that referenced this pull request Jun 29, 2018
Signed-off-by: tyvision <[email protected]>
tyvision added a commit that referenced this pull request Jun 29, 2018
Signed-off-by: tyvision <[email protected]>
tyvision added a commit that referenced this pull request Jun 29, 2018
Signed-off-by: tyvision <[email protected]>
@tyvision tyvision deleted the feature/new-ci-pipeline branch June 30, 2018 10:22
tyvision added a commit that referenced this pull request Jul 3, 2018
tyvision added a commit that referenced this pull request Jul 3, 2018
l4l pushed a commit that referenced this pull request Jul 25, 2018
l4l pushed a commit that referenced this pull request Jul 25, 2018
Signed-off-by: tyvision <[email protected]>
l4l pushed a commit that referenced this pull request Jul 25, 2018
l4l pushed a commit that referenced this pull request Jul 25, 2018
l4l pushed a commit that referenced this pull request Jul 25, 2018
Signed-off-by: tyvision <[email protected]>
l4l pushed a commit that referenced this pull request Jul 25, 2018
l4l pushed a commit that referenced this pull request Jul 25, 2018
l4l pushed a commit that referenced this pull request Jul 25, 2018
Signed-off-by: tyvision <[email protected]>
l4l pushed a commit that referenced this pull request Jul 25, 2018
l4l pushed a commit that referenced this pull request Jul 25, 2018
l4l pushed a commit that referenced this pull request Jul 25, 2018
Stayer pushed a commit that referenced this pull request Jul 27, 2018
Signed-off-by: tyvision <[email protected]>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
infrastructure anything related to continious integration, building infrastructure, or cmake
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants