Package: project-version
Explicit, strict and automatic project version management based on semantic versioning.Getting startedEnd usersSemantic versioningProject versionMotivationCommand line interfaceInstallationVersionHelpCheckBumpReleaseExamplesFAQContributingGetting startedIf you found this project useful, but it does not really fit your development and releasing processes,create an issuewith your proposals, please.Also, if you have any questions after reading the documentation, checkFAQ. If there are no answers,create an issuewith your question, please.End usersAn end user of the project is a software or DevOps-related engineer who develop, release and deploy projects that need
explicit, strict and automatic project version management for tags, images, API and/or libraries.Semantic versioningThere is thesemantic versioning. To make a long story short, it is versioning specification
with major, minor and patch numbers telling us what the current version of a project is and how to react on its new
versions' updates. Example of the project version following semantic versioning is1.3.12where the first digit is
major number, the second digit is minor number, and the third digit is patch number.These are the rules of increasing chose numbers:Increase major version when you make incompatible API changes such as change a name of a required function's or API
parameter.Beforechanges:1.3.12
Afterchanges:2.0.0Increase minor version when you add functionality in a backwards compatible manner such as add a new optional
function's or API parameter.Beforechanges:1.3.12
Afterchanges:1.4.0Increase match version when you make backwards compatible bug fixes.Beforechanges:1.3.12
Afterchanges:1.3.13You have probably seen semantic versioning in your programming language's packages such asJavaScript's axios(e.g. version0.24.0) orPython requests(e.g. version2.27.1).Project versionproject versionis just a set of principles to maintain project versioning andcommand line interfacethat helps not to forget about those principles such as a code style
and linters to check its compliance.project versionrequires having a file named.project-versionin the root directory containing a project version.
With this file, developers declare single source to fetch a project version from for things likeGittags orDockerimages.UsageNow you can reuse a project version from.project-versionfile for multiple release-related purposes:There may be situations when you deployed the new version of an application but do not have deployment logs, or you
deployed the new version of a application but logs tell nothing, or do not haveGitinformation. In all the cases
it may be useful to enter your application's runtime and check file.project-versionto know the exact version
which is related to the codebase.$cat.project-version1.3.12Instead of usingGitcommit SHA or its short version forDockerimages, you can use a project version.$dockerbuild--tagfacebook/react:v$(cat.project-version)-fDockerfile.Instead of usingGitcommit SHA or its short version forGitHubrelease version number, you can use a project
version.on:push:branches:-masterjobs:release:runs-on:[ubuntu-latest]steps:-uses:actions/checkout@v2-name:Create Releaseuses:actions/create-release@v1with:tag_name:$(cat .project-version)release_name:Release v$(cat .project-version)Instead of supporting package version (Python package,GemorJAR) in a dedicated file, you can automatically
use a project version.Python packagewith itssetup.pyfor building packages is illustrated below:withopen('.project-version','r')asproject_version_file:project_version=project_version_file.read().strip()setup(version=project_version,name='project-version',...)In case you manage an infrastructure as a code (e.g.Kubernetes), you may face challenges of supporting multiple
major version of your project (e.g.HTTP API). Without automation, you should create new major version
configurations manually.Let us consider the example where you have API's first version deployment configurations:$lsdeployment/
├──deployment
│├──v1
││└──deployment.yaml
││└──ingress.yaml
││└──service.yaml

$cat/deployment/v1/deployment.yaml
apiVersion:apps/v1
kind:Deployment
metadata:namespace:api-v1When it is time to create API's second version, you can simply copy previous version configurations and substitutev1tov2.$echo.project-version2.0.0
$exportPROJECT_PREVIOUS_MAJOR_VERSION=$(($cat.project-version)-1)$echo$PROJECT_MAJOR_VERSION1$exportPROJECT_MAJOR_VERSION=$(cut-d'.'-f1<<<"$(cat.project-version)")$echo$PROJECT_PREVIOUS_MAJOR_VERSION2$cp-r\deployment/v$PROJECT_PREVIOUS_MAJOR_VERSIONdeployment/v$PROJECT_MAJOR_VERSION$finddeployment/-typef-execsed-i\'s/namespace: v$PROJECT_PREVIOUS_MAJOR_VERSION/namespace: v$PROJECT_MAJOR_VERSION/g'{}+After, you automatically get deployment configurations for the new version:$ ls deployment/├── deployment│   ├── v1│   │   └── deployment.yaml│   │   └── ingress.yaml│   │   └── service.yaml│   ├── v2│   │   └── deployment.yaml│   │   └── ingress.yaml│   │   └── service.yaml$ cat /deployment/v2/deployment.yamlapiVersion:apps/v1kind:Deploymentmetadata:namespace:api-v2And there is much more cases when relying on a project version from its file makes software releasing easier.MaintenanceAll use cases described above requires a project version always be up-to-date and never corrupted. In case it is not,
you can release the same version twice, for example. To avoid this,project-versionis tightly bound to a branching
model with its release life-cycle. Let's consider howproject-versionworks with the most popular branching modelsGit flowandGitHub flow.InGit flow, developers do features in feature branches and merge them todevelopbranch. Whendevelopbranch
has a set of features merged, a release is created (with a separate branch for it) and deployed. To define a release
version,project-versionrequests a developer to make an additional commit intodevelopbranch that changes.project-versionfile.InGitHub flow, developers do features in feature branches and merge them todevelopbranch. Once a single feature
is merged todevelopbranch, a release is immediately created (with no separate branch) and deployed. To define a
release version,project-versionrequests a developer to make an additional commit into a feature branch that changes.project-versionfile.Command line interfaceThis chapter describes a set of command line interface (automation scripts) with descriptive explanation of its
use-cases that help to manage a project version. The command line interface is completely optional but helpful. It
helps developers not to forget about increasing a project version or auto-increase when needed.InstallationInstall usingpip3:$pip3installproject-versionVersionGet the version of the package —project-version --version:$project-version--version
project-version,version0.1.0HelpGet the detailed description of all supported commands by the package —project-version --help:$project-version--help
Usage:project-version[OPTIONS]COMMAND[ARGS]...Projectversioncommand-lineinterface.

Options:--versionShowtheversionandexit.--helpShowthismessageandexit.

Commands:checkCheckwhetherspecifiedprojectversionisincreasedproperly.CheckCheck whether specified project version is increased properly —project-version check.Environment variables:VariableTypeRequiredRestrictionsDescriptionACCESS_TOKENStringYes-The provider'sAPI access token.Parameters:ArgumentTypeRequiredRestrictionsDescriptionproviderStringYesOne of:GitHub.A provider of hosting for software development and version control name.organizationStringYes-The provider's organization name.repositoryStringYes-The provider's repository name.base-branchStringYes-A branch to compare a project version with. Usually, a default branch.head-branchStringYes-A branch to get its project version for comparison. Usually, a feature branch.Example of usage:$project-versioncheck\--provider=GitHub\--organization=facebook\--repository=react\--base-branch=master\--head-branch=map-children-componentsA use case:The use case of the command is to prevent merging feature branches todevelopormasterthat have not increased
a project version. As illustrated below: if bothmasterand feature branch have project version1.1.3, the command
exits with failed status code, if feature branch has1.2.0andmasterhas1.1.3(lower version), the command exits
with succeed status code.The example of a failed pipeline:The example of a pipeline configuration:---name:Pull request workflowon:pull_request_target:branches:-masterjobs:check-project-version:runs-on:[ubuntu-latest]steps:-uses:actions/checkout@v2-name:Install project versionrun:pip3 install project-version-name:Check a project versionenv:ACCESS_TOKEN:${{secrets.GIT_HUB_ACCESS_TOKEN}}run:|project-version check \--provider=GitHub \--organization=facebook \--repository=react \--base-branch=master \--head-branch=map-children-componentsBumpBump the minor version of a project version —project-version bump.Environment variables:VariableTypeRequiredRestrictionsDescriptionACCESS_TOKENStringYes-The provider'sAPI access token.Parameters:ArgumentTypeRequiredRestrictionsDescriptionproviderStringYesOne of:GitHub.A provider of hosting for software development and version control name.organizationStringYes-The provider's organization name.repositoryStringYes-The provider's repository name.base-branchStringYes-A branch to get a project version from. Usually, a default branch.head-branchStringYes-A branch to push bumped project version to. Usually, a feature branch.The example of usage:$project-versionbump\--provider=GitHub\--organization=facebook\--repository=react\--base-branch=master\--head-branch=dependabot/npm/core-js-3.6.4A use case:There are tools likeDependabotthat automatically do updates to your codebase.Dependabottracks your requirements' versions and keep them up-to-date through proposing pull requests. The example
of changes is illustrated below:Usually, codebase is covered with tests and there is no need to review such small changes and developers setup these
pull requests to be merged automatically. But it will be impossible withproject versionas it requires a project
version to be increased manually. The bump command can be applied here, you just configure that if a pull request
is opened byDependabotand then execute the bumping command.The example of a pipeline configuration:---name:Pull request workflowon:pull_request_target:branches:-masterjobs:check-project-version:runs-on:[ubuntu-latest]steps:-uses:actions/checkout@v2-name:Install project versionrun:pip3 install project-version-name:Bump project version if it is non-human pull requestif:${{ github.actor == 'dependabot[bot]' || github.actor == 'facebook-bot' }}env:ACCESS_TOKEN:${{secrets.GIT_HUB_ACCESS_TOKEN}}run:|project-version bump \--provider=GitHub \--organization=facebook \--repository=react \--base-branch=master \--head-branch=map-children-componentsReleaseMake a release —project-version release.Environment variables:VariableTypeRequiredRestrictionsDescriptionACCESS_TOKENStringYes-The provider'sAPI access token.Parameters:ArgumentTypeRequiredRestrictionsDescriptionproviderStringYesOne of:GitHub.A provider of hosting for software development and version control name.organizationStringYes-The provider's organization name.repositoryStringYes-The provider's repository name.branchStringYes-A branch to make a release forproject-versionStringYes-A project version to make a release with.access-tokenStringYes-The provider'sAPI access token.The example of usage:$project-versionrelease\--provider=GitHub\--organization=dmytrostriletskyi\--repository=project-version\--branch=master\--project-version=1.1.3A use case:When yousquash mergeyour feature branches, yourdevelopormastercommits history might looks like:Allow taxi drivers to schedule a break (#567)
Integrate Spotify (#566)
Create OpenAPI spification (#565)If you pick one and create a release with a commit as the title, you will haveAllow taxi drivers to schedule a break (#567).
If you add a release version, it will go uglier likeRelease v3.6.1: Allow taxi drivers to schedule a break (#567).
The release command remove all the mess and create the following titlev3.6.1: allow taxi drivers to schedule a break.The example of a pipeline configuration:---name:Master workflowon:push:branches:-masterjobs:release:runs-on:[ubuntu-latest]outputs:project_version:${{ steps.get_project_version.outputs.project_version }}steps:-uses:actions/checkout@v2-name:Install project versionrun:pip3 install project-version-name:Get a version of the projectid:get_project_versionrun:echo "::set-output name=project_version::$(cat .project-version)"-name:Releaseenv:ACCESS_TOKEN:${{secrets.GIT_HUB_ACCESS_TOKEN}}run:|project-version release \--provider=GitHub \--organization=facebook \--repository=react \--branch=master \--project-version=${{ steps.get_project_version.outputs.project_version }}FAQQ:project-versionis written inPython, but my project's stack is different. Why should I support Python` for
this?A:When you develop a project, you do not needPython, but only.project-versionfile. The only place you needPythonon is your pipelines runner such asGitHub Actions,JenkinsorGitLab CI/CDto run the command line
interface. You can use isolated environment such asDockercontainers:jobs:check-project-version:runs-on:[ubuntu-latest]container:image:python:3.9.0-slim...Q:Why should a developer increase a project version manually for a feature, or a set of features?A:When a developer does a change, the only they know a degree of change: either patch, minor or major. There is
no machine learning model or other software that can describe a degree of change instead of a person who made those
changes.Q:If we merge feature branches often, many concurrent feature branches should pull new project version often. Is
it fine?A:Yes, it is fine. It is a price you pay for the project management. Also, keep in mind that most time you
develop a feature, and only little time you pull other feature branches' changes and merge.ContributingClone the project and install requirements:$gitclonegit@github.com:dmytrostriletskyi/accessify.git&&cdaccessify
$makeinstall-requirementsAfter changes, ensure the code quality remains the same:$makecheck-requirements-safety
$makecheck-code-complexity
$makecheck-code-quality
$makecheck-yaml-standardsIf you are new for the contribution, please read:About pull requests —https://help.github.com/en/articles/about-pull-requestsCreate a pull request —https://help.github.com/en/articles/creating-a-pull-request-from-a-forkThe beginners guide to contributing —https://akrabat.com/the-beginners-guide-to-contributing-to-a-github-project/