Release.Jenkinsfile 12 KB

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