diff --git a/Dockerfile b/Dockerfile index af9c6be..bb2b236 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,8 @@ RUN yum -y install git #Setup semver ADD / /semver WORKDIR /semver -RUN python setup.py sdist +RUN pip install wheel twine +RUN python setup.py sdist bdist_wheel RUN pip install dist/semver-*.tar.gz # Prep workspace diff --git a/Jenkinsfile b/Jenkinsfile index cbbd435..af29eea 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_token' SERVICE = 'auto-semver' SELF_SEMVER_TAG = "master" //Image tag to use for self-versioning @@ -38,12 +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} ." - - - sh "python setup.py sdist" - - stash includes: "dist/semver-${env.SEMVER_NEW_VERSION}.tar.gz", name: 'PACKAGE' + script + { + dockerImage = docker.build("rightbrainnetworks/auto-semver:${env.VERSION}") + } } post{ // Update Git with status of build stage. @@ -84,14 +83,13 @@ 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}") + } } - - // 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 { @@ -104,7 +102,7 @@ pipeline { } } } - stage('Publish Release') + stage('Release') { when { expression { @@ -113,25 +111,35 @@ pipeline { } steps { - unstash 'PACKAGE' + 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"]) - // Update DockerHub latest tag - sh(""" - docker tag rightbrainnetworks/auto-semver:${env.VERSION} rightbrainnetworks/auto-semver:latest - docker push rightbrainnetworks/auto-semver:latest - """) + + // Upload package to PyPi + 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 { // Update Git with status of release stage. success { - updateGithubCommitStatus(GITHUB_URL, 'Passed release stage', 'SUCCESS', 'Release') + updateGithubCommitStatus(GITHUB_URL, 'Passed release package stage', 'SUCCESS', 'Release') } failure { - updateGithubCommitStatus(GITHUB_URL, 'Failed release stage', 'FAILURE', 'Release') + updateGithubCommitStatus(GITHUB_URL, 'Failed release package stage', 'FAILURE', 'Release') } } } diff --git a/README.md b/README.md index 2125616..67e1287 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 @@ -150,7 +150,7 @@ Provides a build number for pre-release versions. 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 { diff --git a/setup.py b/setup.py index 151c142..840a7f0 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,76 +50,30 @@ 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=[ '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', diff --git a/vars/runAutoSemver.groovy b/vars/runAutoSemver.groovy index 2f8f825..8b6e2ed 100644 --- a/vars/runAutoSemver.groovy +++ b/vars/runAutoSemver.groovy @@ -1,4 +1,3 @@ - #!/usr/bin/env groovy /**