From fbd76357de78dd3729c35e7a8c8923a0ce2ea864 Mon Sep 17 00:00:00 2001 From: Joseph Manley Date: Mon, 20 Jan 2020 11:10:03 -0500 Subject: [PATCH 1/7] Update package name Update to work with PyPI Fix pipeline Update pipeline Update pipeline Update pipeline --- Dockerfile | 3 +- Jenkinsfile | 50 ++++++++++++++++++++++++-------- README.md | 4 +-- requirements.txt | 3 +- setup.py | 75 ++++++++---------------------------------------- 5 files changed, 56 insertions(+), 79 deletions(-) diff --git a/Dockerfile b/Dockerfile index e271759..f112e24 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,8 @@ RUN yum -y install git2u-all #Setup semver ADD / /semver WORKDIR /semver -RUN python setup.py sdist +RUN pip install wheel +RUN python setup.py sdist bdist_wheel RUN pip install dist/semver-*.tar.gz # Prep workspace diff --git a/Jenkinsfile b/Jenkinsfile index db37f2a..818713c 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -8,6 +8,7 @@ pipeline { GITHUB_URL = 'git@github.com:RightBrain-Networks/auto-semver.git' GITHUB_KEY = 'rbn-ops github' DOCKER_CREDENTIALS = 'rbnopsDockerHubToken' + PYPI_CREDENTIALS = 'rbn_pypi_password' SERVICE = 'auto-semver' SELF_SEMVER_TAG = "master" //Image tag to use for self-versioning @@ -39,11 +40,6 @@ pipeline { // Docker build flags are set via the getDockerBuildFlags() shared library. sh "docker build ${getDockerBuildFlags()} -t rightbrainnetworks/auto-semver:${env.VERSION} ." - - - sh "python setup.py sdist" - - stash includes: "dist/semver-${env.SEMVER_NEW_VERSION}.tar.gz", name: 'PACKAGE' } post{ // Update Git with status of build stage. @@ -66,9 +62,7 @@ pipeline { docker push rightbrainnetworks/auto-semver:${env.VERSION} """) } - - // Copy artifact to S3 - sh "aws s3 cp `ls -t ./dist/semver-* | head -1` s3://rbn-ops-pkg-us-east-1/${env.SERVICE}/${env.SERVICE}-${env.VERSION}.tar.gz" + } post { @@ -81,20 +75,52 @@ pipeline { } } } - stage('Publish Release') + stage('Release Packages') { when { expression { "${env.SEMVER_STATUS}" == "0" && "${env.BRANCH_NAME}" == "master" } } + agent { + docker { + image "rightbrainnetworks/auto-semver:${env.VERSION}" + } + } steps { - unstash 'PACKAGE' // Create GitHub Release & Upload Artifacts createGitHubRelease('rbn-opsGitHubToken', 'RightBrain-Networks/auto-semver', "${env.SEMVER_RESOLVED_VERSION}", "${env.SEMVER_RESOLVED_VERSION}", ["auto-semver.tar.gz" : "dist/semver-${env.SEMVER_NEW_VERSION}.tar.gz"]) + + // Upload package to PyPi + withCredentials([usernamePassword(credentialsId: env.PYPI_CREDENTIALS, usernameVariable: 'PYPI_USERNAME', passwordVariable: 'PYPI_PASSWORD')]) { + sh("pip install twine") + sh("twine upload dist/* --verbose -u ${PYPI_USERNAME} -p ${PYPI_PASSWORD}") + } + + } + post + { + // Update Git with status of release stage. + success { + updateGithubCommitStatus(GITHUB_URL, 'Passed release package stage', 'SUCCESS', 'Release') + } + failure { + updateGithubCommitStatus(GITHUB_URL, 'Failed release package stage', 'FAILURE', 'Release') + } + } + } + stage('Push Docker Image') + { + when { + expression { + "${env.SEMVER_STATUS}" == "0" && "${env.BRANCH_NAME}" == "master" + } + } + steps + { // Update DockerHub latest tag sh(""" docker tag rightbrainnetworks/auto-semver:${env.VERSION} rightbrainnetworks/auto-semver:latest @@ -105,10 +131,10 @@ pipeline { { // Update Git with status of release stage. success { - updateGithubCommitStatus(GITHUB_URL, 'Passed release stage', 'SUCCESS', 'Release') + updateGithubCommitStatus(GITHUB_URL, 'Passed push docker stage', 'SUCCESS', 'Docker') } failure { - updateGithubCommitStatus(GITHUB_URL, 'Failed release stage', 'FAILURE', 'Release') + updateGithubCommitStatus(GITHUB_URL, 'Failed push docker stage', 'FAILURE', 'Docker') } } } diff --git a/README.md b/README.md index 5d891b7..7404a23 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![Release Version](https://img.shields.io/github/v/release/RightBrain-Networks/auto-semver) ![GitHub Downloads](https://img.shields.io/github/downloads/RightBrain-Networks/auto-semver/total) +![Release Version](https://img.shields.io/github/v/release/RightBrain-Networks/auto-semver) ![Python Version](https://img.shields.io/pypi/pyversions/semver-by-branch) ![PyPi Downloads](https://img.shields.io/pypi/dm/semver-by-branch) # Automatic Semantic Versioning @@ -11,7 +11,7 @@ The tool uses the git log to determine if the last commit was a merge into a mai auto-semver is a pip installable package to install, make sure pip is installed and simply run: -`pip install path/to/auto-semver-tar.gz` +`pip install semver-by-branch` ## Configuration diff --git a/requirements.txt b/requirements.txt index 94ed009..33d2d7f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ -bumpversion==0.5.3 +bump2version>=0.5.11 +argparse>=1.2.1 \ No newline at end of file diff --git a/setup.py b/setup.py index 51be44a..adb48d1 100644 --- a/setup.py +++ b/setup.py @@ -6,12 +6,12 @@ import re +from os import path -# Always prefer setuptools over distutils from setuptools import setup, find_packages # To use a consistent encoding from codecs import open -from os import path + here = path.abspath(path.dirname(__file__)) @@ -34,16 +34,11 @@ def find_version(*file_paths): raise RuntimeError("Unable to find version string.") setup( - name='semver', - - # Versions should comply with PEP440. For a discussion on single-sourcing - # the version across setup.py and the project code, see - # https://packaging.python.org/en/latest/single_source_version.html + name='semver-by-branch', version=find_version('semver','__init__.py'), - #version='0.0.1', - description='Automatic Semantic Versioner', long_description=long_description, + long_description_content_type="text/markdown", # The project's main homepage. url='https://github.com/RightBrain-Networks/auto-semver', @@ -55,77 +50,31 @@ def find_version(*file_paths): # Choose your license license='Apache2.0', - # See https://pypi.python.org/pypi?%3Aaction=list_classifiers + # See https://pypi.org/classifiers/ classifiers=[ - # How mature is this project? Common values are - # 3 - Alpha - # 4 - Beta - # 5 - Production/Stable - 'Development Status :: 3 - Alpha', - - # Indicate who your project is intended for + 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'Intended Audience :: System Administrators', 'Topic :: Software Development :: Build Tools', - - # Pick your license as you wish (should match "license" above) 'License :: OSI Approved :: Apache Software License', - - # Specify the Python versions you support here. In particular, ensure - # that you indicate whether you support Python 2, Python 3 or both. 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6' + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Topic :: Software Development :: Build Tools' ], - - # What does your project relate to? - keywords='Semantic Version', - - # You can just specify the packages manually here if your project is - # simple. Or you can use find_packages(). + keywords='Semantic,Version,CICD,Pipeline,Versioning', packages=find_packages(exclude=['contrib', 'docs', 'tests']), - - # Alternatively, if you want to distribute just a my_module.py, uncomment - # this: - # py_modules=["my_module"], - - # List run-time dependencies here. These will be installed by pip when - # your project is installed. For an analysis of "install_requires" vs pip's - # requirements files see: - # https://packaging.python.org/en/latest/requirements.html install_requires=[ 'bump2version>=0.5.11', 'argparse>=1.2.1' ], - - # List additional groups of dependencies here (e.g. development - # dependencies). You can install these using the following syntax, - # for example: - # $ pip install -e .[dev,test] - #extras_require={ - # 'dev': ['check-manifest'], - # 'test': ['coverage'], - #}, - - # If there are data files included in your packages that need to be - # installed, specify them here. If using Python 2.6 or less, then these - # have to be included in MANIFEST.in as well. - package_data={ - }, - - # Although 'package_data' is the preferred approach, in some case you may - # need to place data files outside of your packages. See: - # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # noqa - # In this case, 'data_file' will be installed into '/my_data' - #data_files=[('my_data', ['data/data_file'])], - - # To provide executable scripts, use entry points in preference to the - # "scripts" keyword. Entry points provide cross-platform support and allow - # pip to create the appropriate form of executable for the target platform. + package_data={}, entry_points={ 'console_scripts': [ 'semver = semver:main', From 34f58b7678d7650e90729c321586e9d365630023 Mon Sep 17 00:00:00 2001 From: Joseph Manley Date: Tue, 21 Jan 2020 14:58:54 -0500 Subject: [PATCH 2/7] PIPELINE: Use jenkin's docker library PIPELINE: Use jenkin's docker library PIPELINE: Use jenkin's docker library PIPELINE: Use jenkin's docker library PIPELINE: Use jenkin's docker library PIPELINE: Use jenkin's docker library PIPELINE: Use jenkin's docker library PIPELINE: Use jenkin's docker library PIPELINE: Use jenkin's docker library --- Jenkinsfile | 47 ++++++++++++++++------------------------------- 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 818713c..23c0237 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -39,7 +39,10 @@ pipeline { echo "Building ${env.SERVICE} docker image" // Docker build flags are set via the getDockerBuildFlags() shared library. - sh "docker build ${getDockerBuildFlags()} -t rightbrainnetworks/auto-semver:${env.VERSION} ." + script + { + dockerImage = docker.build("rightbrainnetworks/auto-semver:${env.VERSION}") + } } post{ // Update Git with status of build stage. @@ -57,10 +60,18 @@ pipeline { // Authenticate & push to DockerHub withCredentials([usernamePassword(credentialsId: env.DOCKER_CREDENTIALS, usernameVariable: 'DOCKER_USERNAME', passwordVariable: 'DOCKER_PASSWORD')]) { - sh(""" - docker login -u ${DOCKER_USERNAME} -p ${DOCKER_PASSWORD} - docker push rightbrainnetworks/auto-semver:${env.VERSION} - """) + sh("docker login -u ${DOCKER_USERNAME} -p ${DOCKER_PASSWORD}") + script + { + dockerImage.push("${env.VERSION}") + } + } + script + { + if("${env.SEMVER_STATUS}" == "0" && "${env.BRANCH_NAME}" == "master") + { + dockerImage.push('latest') + } } } @@ -112,32 +123,6 @@ pipeline { } } } - stage('Push Docker Image') - { - when { - expression { - "${env.SEMVER_STATUS}" == "0" && "${env.BRANCH_NAME}" == "master" - } - } - steps - { - // Update DockerHub latest tag - sh(""" - docker tag rightbrainnetworks/auto-semver:${env.VERSION} rightbrainnetworks/auto-semver:latest - docker push rightbrainnetworks/auto-semver:latest - """) - } - post - { - // Update Git with status of release stage. - success { - updateGithubCommitStatus(GITHUB_URL, 'Passed push docker stage', 'SUCCESS', 'Docker') - } - failure { - updateGithubCommitStatus(GITHUB_URL, 'Failed push docker stage', 'FAILURE', 'Docker') - } - } - } } post { success { updateGithubCommitStatus(GITHUB_URL, 'Passed build and test', 'SUCCESS') } From 1915ed41485c4b9f6a565a177aeb3da62b622ae4 Mon Sep 17 00:00:00 2001 From: Joseph Manley Date: Fri, 21 Feb 2020 11:18:53 -0500 Subject: [PATCH 3/7] Remove line for beginning of `runAutoSemver.groovy` --- vars/runAutoSemver.groovy | 1 - 1 file changed, 1 deletion(-) diff --git a/vars/runAutoSemver.groovy b/vars/runAutoSemver.groovy index 43d364f..d8d7a33 100644 --- a/vars/runAutoSemver.groovy +++ b/vars/runAutoSemver.groovy @@ -1,4 +1,3 @@ - #!/usr/bin/env groovy /** From 89a203531d990ff27e629731358e20f943facc12 Mon Sep 17 00:00:00 2001 From: Joseph Manley Date: Fri, 21 Feb 2020 11:26:39 -0500 Subject: [PATCH 4/7] Add `getVersion.groovy` file --- vars/getVersion.groovy | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 vars/getVersion.groovy diff --git a/vars/getVersion.groovy b/vars/getVersion.groovy new file mode 100644 index 0000000..cdf7156 --- /dev/null +++ b/vars/getVersion.groovy @@ -0,0 +1,13 @@ +#!/usr/bin/env groovy + +/** + * Run semver_get_version to return the current version of the repository + * + * @param flags Flags or arguments to pass to semver_get_version + * @return "1.9.2" + */ +def call(flags='') { + def VERSION + VERSION = sh(returnStdout: true, script: "semver_get_version ${flags}") + return VERSION.trim() +} \ No newline at end of file From 14619d9cb4695db6d83ae30f4ee38b3cf8591963 Mon Sep 17 00:00:00 2001 From: Joseph Manley Date: Fri, 21 Feb 2020 16:41:31 -0500 Subject: [PATCH 5/7] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7404a23..79a4a3d 100644 --- a/README.md +++ b/README.md @@ -134,7 +134,7 @@ Replaces `/` with `.` in branch names. For example, `feature/test` becomes `feat This repository is also home to a Jenkins shared library to assit in running auto-semver. ```groovy -library('auto-semver') +library('auto-semver') // Global shared library for Semver-by-Branch pipeline { From e07b9f0b3cc2f275f5ef4a6d13106f19d3874f2d Mon Sep 17 00:00:00 2001 From: Joseph Manley Date: Tue, 16 Jun 2020 21:13:43 -0400 Subject: [PATCH 6/7] Move push latest & move to use PyPi token --- Jenkinsfile | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 68d4c2f..af29eea 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -8,7 +8,7 @@ pipeline { GITHUB_URL = 'git@github.com:RightBrain-Networks/auto-semver.git' GITHUB_KEY = 'rbn-ops github' DOCKER_CREDENTIALS = 'rbnopsDockerHubToken' - PYPI_CREDENTIALS = 'rbn_pypi_password' + PYPI_CREDENTIALS = 'rbn_pypi_token' SERVICE = 'auto-semver' SELF_SEMVER_TAG = "master" //Image tag to use for self-versioning @@ -89,13 +89,6 @@ pipeline { dockerImage.push("${env.VERSION}") } } - script - { - if("${env.SEMVER_STATUS}" == "0" && "${env.BRANCH_NAME}" == "master") - { - dockerImage.push('latest') - } - } } post @@ -109,31 +102,35 @@ pipeline { } } } - stage('Release Packages') + stage('Release') { when { expression { "${env.SEMVER_STATUS}" == "0" && "${env.BRANCH_NAME}" == "master" } } - agent { - docker { - image "rightbrainnetworks/auto-semver:${env.VERSION}" - } - } steps { + script + { + dockerImage.push('latest') + } + // Create GitHub Release & Upload Artifacts createGitHubRelease('rbn-opsGitHubToken', 'RightBrain-Networks/auto-semver', "${env.SEMVER_RESOLVED_VERSION}", "${env.SEMVER_RESOLVED_VERSION}", ["auto-semver.tar.gz" : "dist/semver-${env.SEMVER_NEW_VERSION}.tar.gz"]) // Upload package to PyPi - withCredentials([usernamePassword(credentialsId: env.PYPI_CREDENTIALS, usernameVariable: 'PYPI_USERNAME', passwordVariable: 'PYPI_PASSWORD')]) { - sh("pip install twine") - sh("twine upload dist/* --verbose -u ${PYPI_USERNAME} -p ${PYPI_PASSWORD}") + script + { + docker.image("rightbrainnetworks/auto-semver:${env.VERSION}").inside() + { + withCredentials([string(credentialsId: env.PYPI_CREDENTIALS, variable: 'PYPI_PASSWORD')]) { + sh("twine upload dist/* --verbose -u __token__ -p ${PYPI_PASSWORD}") + } + } } - } post { From c414515a3828f3b2955c7c1fa58fc3cf90ba7cc8 Mon Sep 17 00:00:00 2001 From: Joseph Manley Date: Tue, 16 Jun 2020 21:20:49 -0400 Subject: [PATCH 7/7] Install twine --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 60191cf..bb2b236 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ RUN yum -y install git #Setup semver ADD / /semver WORKDIR /semver -RUN pip install wheel +RUN pip install wheel twine RUN python setup.py sdist bdist_wheel RUN pip install dist/semver-*.tar.gz