Release.Jenkinsfile 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. #!groovy
  2. def dockerVersions = ['19.03.8', '18.09.9']
  3. def baseImages = ['alpine', 'debian']
  4. def pythonVersions = ['py37']
  5. pipeline {
  6. agent none
  7. options {
  8. skipDefaultCheckout(true)
  9. buildDiscarder(logRotator(daysToKeepStr: '30'))
  10. timeout(time: 2, unit: 'HOURS')
  11. timestamps()
  12. }
  13. stages {
  14. stage('Build test images') {
  15. // TODO use declarative 1.5.0 `matrix` once available on CI
  16. parallel {
  17. stage('alpine') {
  18. agent {
  19. label 'linux && docker && ubuntu-2004'
  20. }
  21. steps {
  22. buildImage('alpine')
  23. }
  24. }
  25. stage('debian') {
  26. agent {
  27. label 'linux && docker && ubuntu-2004'
  28. }
  29. steps {
  30. buildImage('debian')
  31. }
  32. }
  33. }
  34. }
  35. stage('Test') {
  36. agent {
  37. label 'linux && docker && ubuntu-2004'
  38. }
  39. steps {
  40. // TODO use declarative 1.5.0 `matrix` once available on CI
  41. script {
  42. def testMatrix = [:]
  43. baseImages.each { baseImage ->
  44. dockerVersions.each { dockerVersion ->
  45. pythonVersions.each { pythonVersion ->
  46. testMatrix["${baseImage}_${dockerVersion}_${pythonVersion}"] = runTests(dockerVersion, pythonVersion, baseImage)
  47. }
  48. }
  49. }
  50. parallel testMatrix
  51. }
  52. }
  53. }
  54. stage('Generate Changelog') {
  55. agent {
  56. label 'linux && docker && ubuntu-2004'
  57. }
  58. steps {
  59. checkout scm
  60. withCredentials([string(credentialsId: 'github-compose-release-test-token', variable: 'GITHUB_TOKEN')]) {
  61. sh "./script/release/generate_changelog.sh"
  62. }
  63. archiveArtifacts artifacts: 'CHANGELOG.md'
  64. stash( name: "changelog", includes: 'CHANGELOG.md' )
  65. }
  66. }
  67. stage('Package') {
  68. parallel {
  69. stage('macosx binary') {
  70. agent {
  71. label 'mac-python'
  72. }
  73. environment {
  74. DEPLOYMENT_TARGET="10.11"
  75. }
  76. steps {
  77. checkout scm
  78. sh './script/setup/osx'
  79. sh 'tox -e py37 -- tests/unit'
  80. sh './script/build/osx'
  81. dir ('dist') {
  82. checksum('docker-compose-Darwin-x86_64')
  83. checksum('docker-compose-Darwin-x86_64.tgz')
  84. }
  85. archiveArtifacts artifacts: 'dist/*', fingerprint: true
  86. dir("dist") {
  87. stash name: "bin-darwin"
  88. }
  89. }
  90. }
  91. stage('linux binary') {
  92. agent {
  93. label 'linux && docker && ubuntu-2004'
  94. }
  95. steps {
  96. checkout scm
  97. sh ' ./script/build/linux'
  98. dir ('dist') {
  99. checksum('docker-compose-Linux-x86_64')
  100. }
  101. archiveArtifacts artifacts: 'dist/*', fingerprint: true
  102. dir("dist") {
  103. stash name: "bin-linux"
  104. }
  105. }
  106. }
  107. stage('windows binary') {
  108. agent {
  109. label 'windows-python'
  110. }
  111. environment {
  112. PATH = "$PATH;C:\\Python37;C:\\Python37\\Scripts"
  113. }
  114. steps {
  115. checkout scm
  116. bat 'tox.exe -e py37 -- tests/unit'
  117. powershell '.\\script\\build\\windows.ps1'
  118. dir ('dist') {
  119. checksum('docker-compose-Windows-x86_64.exe')
  120. }
  121. archiveArtifacts artifacts: 'dist/*', fingerprint: true
  122. dir("dist") {
  123. stash name: "bin-win"
  124. }
  125. }
  126. }
  127. stage('alpine image') {
  128. agent {
  129. label 'linux && docker && ubuntu-2004'
  130. }
  131. steps {
  132. buildRuntimeImage('alpine')
  133. }
  134. }
  135. stage('debian image') {
  136. agent {
  137. label 'linux && docker && ubuntu-2004'
  138. }
  139. steps {
  140. buildRuntimeImage('debian')
  141. }
  142. }
  143. }
  144. }
  145. stage('Release') {
  146. when {
  147. buildingTag()
  148. }
  149. parallel {
  150. stage('Pushing images') {
  151. agent {
  152. label 'linux && docker && ubuntu-2004'
  153. }
  154. steps {
  155. pushRuntimeImage('alpine')
  156. pushRuntimeImage('debian')
  157. }
  158. }
  159. stage('Creating Github Release') {
  160. agent {
  161. label 'linux && docker && ubuntu-2004'
  162. }
  163. environment {
  164. GITHUB_TOKEN = credentials('github-release-token')
  165. }
  166. steps {
  167. checkout scm
  168. sh 'mkdir -p dist'
  169. dir("dist") {
  170. unstash "bin-darwin"
  171. unstash "bin-linux"
  172. unstash "bin-win"
  173. unstash "changelog"
  174. sh("""
  175. curl -SfL https://github.com/github/hub/releases/download/v2.13.0/hub-linux-amd64-2.13.0.tgz | tar xzv --wildcards 'hub-*/bin/hub' --strip=2
  176. ./hub release create --draft --prerelease=${env.TAG_NAME !=~ /v[0-9\.]+/} \\
  177. -a docker-compose-Darwin-x86_64 \\
  178. -a docker-compose-Darwin-x86_64.sha256 \\
  179. -a docker-compose-Darwin-x86_64.tgz \\
  180. -a docker-compose-Darwin-x86_64.tgz.sha256 \\
  181. -a docker-compose-Linux-x86_64 \\
  182. -a docker-compose-Linux-x86_64.sha256 \\
  183. -a docker-compose-Windows-x86_64.exe \\
  184. -a docker-compose-Windows-x86_64.exe.sha256 \\
  185. -a ../script/run/run.sh \\
  186. -F CHANGELOG.md \${TAG_NAME}
  187. """)
  188. }
  189. }
  190. }
  191. stage('Publishing Python packages') {
  192. agent {
  193. label 'linux && docker && ubuntu-2004'
  194. }
  195. environment {
  196. PYPIRC = credentials('pypirc-docker-dsg-cibot')
  197. }
  198. steps {
  199. checkout scm
  200. sh """
  201. rm -rf build/ dist/
  202. pip3 install wheel
  203. python3 setup.py sdist bdist_wheel
  204. pip3 install twine
  205. ~/.local/bin/twine upload --config-file ${PYPIRC} ./dist/docker-compose-*.tar.gz ./dist/docker_compose-*-py2.py3-none-any.whl
  206. """
  207. }
  208. }
  209. }
  210. }
  211. }
  212. }
  213. def buildImage(baseImage) {
  214. def scmvar = checkout(scm)
  215. def imageName = "dockerbuildbot/compose:${baseImage}-${scmvar.GIT_COMMIT}"
  216. image = docker.image(imageName)
  217. withDockerRegistry(credentialsId:'dockerbuildbot-index.docker.io') {
  218. try {
  219. image.pull()
  220. } catch (Exception exc) {
  221. ansiColor('xterm') {
  222. sh """docker build -t ${imageName} \\
  223. --target build \\
  224. --build-arg BUILD_PLATFORM="${baseImage}" \\
  225. --build-arg GIT_COMMIT="${scmvar.GIT_COMMIT}" \\
  226. .\\
  227. """
  228. sh "docker push ${imageName}"
  229. }
  230. echo "${imageName}"
  231. return imageName
  232. }
  233. }
  234. }
  235. def runTests(dockerVersion, pythonVersion, baseImage) {
  236. return {
  237. stage("python=${pythonVersion} docker=${dockerVersion} ${baseImage}") {
  238. node("linux && docker && ubuntu-2004") {
  239. def scmvar = checkout(scm)
  240. def imageName = "dockerbuildbot/compose:${baseImage}-${scmvar.GIT_COMMIT}"
  241. def storageDriver = sh(script: "docker info -f \'{{.Driver}}\'", returnStdout: true).trim()
  242. echo "Using local system's storage driver: ${storageDriver}"
  243. withDockerRegistry(credentialsId:'dockerbuildbot-index.docker.io') {
  244. sh """docker run \\
  245. -t \\
  246. --rm \\
  247. --privileged \\
  248. --volume="\$(pwd)/.git:/code/.git" \\
  249. --volume="/var/run/docker.sock:/var/run/docker.sock" \\
  250. -e "TAG=${imageName}" \\
  251. -e "STORAGE_DRIVER=${storageDriver}" \\
  252. -e "DOCKER_VERSIONS=${dockerVersion}" \\
  253. -e "BUILD_NUMBER=${env.BUILD_NUMBER}" \\
  254. -e "PY_TEST_VERSIONS=${pythonVersion}" \\
  255. --entrypoint="script/test/ci" \\
  256. ${imageName} \\
  257. --verbose
  258. """
  259. }
  260. }
  261. }
  262. }
  263. }
  264. def buildRuntimeImage(baseImage) {
  265. scmvar = checkout scm
  266. def imageName = "docker/compose:${baseImage}-${env.BRANCH_NAME}"
  267. ansiColor('xterm') {
  268. sh """docker build -t ${imageName} \\
  269. --build-arg BUILD_PLATFORM="${baseImage}" \\
  270. --build-arg GIT_COMMIT="${scmvar.GIT_COMMIT.take(7)}" \\
  271. .
  272. """
  273. }
  274. sh "mkdir -p dist"
  275. sh "docker save ${imageName} -o dist/docker-compose-${baseImage}.tar"
  276. stash name: "compose-${baseImage}", includes: "dist/docker-compose-${baseImage}.tar"
  277. }
  278. def pushRuntimeImage(baseImage) {
  279. unstash "compose-${baseImage}"
  280. sh "docker load -i dist/docker-compose-${baseImage}.tar"
  281. withDockerRegistry(credentialsId: 'dockerhub-dockerdsgcibot') {
  282. sh "docker push docker/compose:${baseImage}-${env.TAG_NAME}"
  283. if (baseImage == "alpine" && env.TAG_NAME != null) {
  284. sh "docker tag docker/compose:alpine-${env.TAG_NAME} docker/compose:${env.TAG_NAME}"
  285. sh "docker push docker/compose:${env.TAG_NAME}"
  286. }
  287. }
  288. }
  289. def checksum(filepath) {
  290. if (isUnix()) {
  291. sh "openssl sha256 -r -out ${filepath}.sha256 ${filepath}"
  292. } else {
  293. powershell "(Get-FileHash -Path ${filepath} -Algorithm SHA256 | % hash).ToLower() + ' *${filepath}' | Out-File -encoding ascii ${filepath}.sha256"
  294. }
  295. }