Jenkinsfile 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. pipeline {
  2. agent any
  3. /**
  4. * Build file for EliasDB
  5. *
  6. * Each build happens with 2 commits. The first commit is the actual
  7. * feature or fix commit. The commit message should follow conventional
  8. * commit messages (https://www.conventionalcommits.org/en/v1.0.0-beta.4/).
  9. * In a second commit a program called standard version
  10. * (https://github.com/conventional-changelog/standard-version) calculates
  11. * a new product version. The versioning will be according to the rules
  12. * of “Semantic Versioning” (https://semver.org/).
  13. *
  14. * Building is done using goreleaser (https://goreleaser.com/) for different
  15. * platforms.
  16. *
  17. * Testing produces code coverage badges which can be embedded on other
  18. * pages.
  19. *
  20. * Everything runs in docker containers to ensure isolation of the build
  21. * system and to allow painless upgrades.
  22. */
  23. stages {
  24. stage('Commit Analysis') {
  25. steps {
  26. // Read the commit message into a variable
  27. //
  28. script {
  29. commit_msg = sh(returnStdout: true, script: 'git log -1')
  30. }
  31. }
  32. }
  33. stage('Prepare Release Build') {
  34. // Check for a release build (a commit by standard-version)
  35. //
  36. when { expression { return commit_msg =~ /chore\(release\)\:/ } }
  37. steps {
  38. // Find out the tagged version
  39. //
  40. script {
  41. version = sh(returnStdout: true, script: 'git log -1 | grep chore | tr -d "\\n" | sed "s/.*chore(release): \\([0-9\\.]*\\)/\\1/"')
  42. }
  43. echo "Building version: ${version} ..."
  44. }
  45. }
  46. stage('Build') {
  47. when { expression { return commit_msg =~ /chore\(release\)\:/ } }
  48. steps {
  49. // Fetch all git tags and run goreleaser
  50. //
  51. checkout scm
  52. sshagent (credentials: ['Gogs']) {
  53. sh 'git fetch --tags'
  54. }
  55. sh 'mkdir -p .cache'
  56. sh 'docker run --rm --user $(id -u):$(id -g) -v $PWD/.cache:/.cache -v $PWD:/go/code -w /go/code goreleaser/goreleaser --snapshot --skip-publish --rm-dist'
  57. }
  58. }
  59. stage('Test') {
  60. // The tests are run in both stages - no release commit is made if the tests fail.
  61. // The output is the coverage data and the badge.
  62. //
  63. steps {
  64. echo 'Running tests ...'
  65. sh """echo '<svg width="88" height="20" xmlns="http://www.w3.org/2000/svg"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h41v20H0z"/><path fill="#fc1" d="M41 0h40v20H41z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="20.5" y="14">tests</text><text x="60" y="14">fail</text></g></svg>' > test_result.svg"""
  66. sh 'docker run --rm -e GOPATH=/tmp -v $PWD:/go golang go test -p 1 --coverprofile=coverage.out ./...'
  67. sh 'docker run --rm -e GOPATH=/tmp -v $PWD:/go golang go tool cover --html=coverage.out -o coverage.html'
  68. echo 'Determine overall coverage and writing badge'
  69. script {
  70. coverage = sh(returnStdout: true, script: 'docker run --rm -e GOPATH=/tmp -v $PWD:/go golang go tool cover -func=coverage.out | tee coverage.txt | tail -1 | grep -o "[0-9]*.[0-9]*%$" | tr -d "\\n"')
  71. echo "Overall coverage is: ${coverage}"
  72. if (coverage.equals("100.0%")) {
  73. sh """echo '<svg width="110" height="20" xmlns="http://www.w3.org/2000/svg"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h61v20H0z"/><path fill="#4c1" d="M61 0h50v20H61z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="30.5" y="14">coverage</text><text x="85" y="14">$coverage</text></g></svg>' > test_result.svg"""
  74. } else {
  75. sh """echo '<svg width="110" height="20" xmlns="http://www.w3.org/2000/svg"><g shape-rendering="crispEdges"><path fill="#555" d="M0 0h61v20H0z"/><path fill="#fc1" d="M61 0h50v20H61z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"><text x="30.5" y="14">coverage</text><text x="85" y="14">$coverage</text></g></svg>' > test_result.svg"""
  76. }
  77. }
  78. }
  79. }
  80. stage('Create Release Build Commit') {
  81. // Check for a non-release build to avoid a commit loop
  82. //
  83. when { not { expression { return commit_msg =~ /chore\(release\)\:/ } } }
  84. steps {
  85. // Before running standard-version it is important to fetch
  86. // the existing tags so next version can be calculated
  87. //
  88. echo 'Running standard version ...'
  89. sshagent (credentials: ['Gogs']) {
  90. sh 'git fetch --tags'
  91. }
  92. sh 'docker run --rm -v $PWD:/app standard-version'
  93. // The new version is inserted into the code
  94. //
  95. script {
  96. new_version = sh(returnStdout: true, script: 'git tag | tail -1 | tr -d "\\n"')
  97. }
  98. echo "Inserting version $new_version into the code"
  99. sh "find . -name '*.go' -exec sed -i -e 's/ProductVersion\\ =\\ \\\".*\\\"/ProductVersion = \\\"${new_version.substring(1)}\\\"/g' {} \\;"
  100. // The commit is amended to include the code change
  101. //
  102. echo "Tagging the build and push the changes into the origin repository"
  103. sshagent (credentials: ['Gogs']) {
  104. sh 'git config user.name "Matthias Ladkau"'
  105. sh 'git config user.email "webmaster@devt.de"'
  106. sh 'git commit -a --amend --no-edit'
  107. sh "git tag --force $new_version"
  108. sh 'git push --tags origin master'
  109. }
  110. }
  111. }
  112. stage('Upload Release Build Commit') {
  113. when { expression { return commit_msg =~ /chore\(release\)\:/ } }
  114. steps {
  115. echo "Uploading release build ..."
  116. // After a successful build the resulting artifacts are
  117. // uploaded for publication
  118. //
  119. sshagent (credentials: ['Gogs']) {
  120. // Clear distribution folder
  121. sh 'ssh -o StrictHostKeyChecking=no -p 7000 krotik@devt.de rm -fR pub/eliasdb'
  122. sh 'ssh -o StrictHostKeyChecking=no -p 7000 krotik@devt.de mkdir -p pub/eliasdb'
  123. // Copy distribution packages in place
  124. sh 'scp -P 7000 -o StrictHostKeyChecking=no dist/*.tar.gz krotik@devt.de:~/pub/eliasdb'
  125. // Copy coverage in place
  126. sh 'scp -P 7000 -o StrictHostKeyChecking=no coverage.* krotik@devt.de:~/pub/eliasdb'
  127. // Copy test result in place
  128. sh 'scp -P 7000 -o StrictHostKeyChecking=no test_result.svg krotik@devt.de:~/pub/eliasdb'
  129. }
  130. }
  131. }
  132. }
  133. }