Semantic Versioning on multiple services in the same Github repository using GH Actions - github

Our team uses a mono-repo, with several microservices, and some common packages between them.
I am tasked with adding CI/CD automation, and traditionally I rely in Git tags for the sem-ver and utilize comments to decide on major/minor/patch. The semantic-release node library does an good job of automating this.
The problem here is that it is a mono-repo and thus commits and tags are only useful across a global sem-ver. However in my case I have multiple microservices that each will have their own sem-ver.
One thought I have is maintaining a json manifest to store the versions of the services. By blocking direct pushes to the main branch, I can guarentee this file would not be changed on master except by the CI/CD actions.
I also would like to get some ideas from the community on what they would do in this situation? Or what they have done similar to this in the past?

Related

How to manage logical grouping of microservice based application to ensure version compatibility for CI/CD Pipeline?

For the MicroService Architecture based application, I'm trying to understand a standard process about how to logically group and manage correct version compatibility among independently deployable microservices. Let me elaborate with practical scenario :
Say, I am building a software application which is composed of 10 microservices. All the microservices have their independent repositories(branching workflow etc.) and their separate CI/CD Pipeline.
The CI/CD Pipeline gets triggered whenever any change pushed to 'master' branch for respective microservice.
Considering Helm chart and Kubernetes based deployment, all the microservices will get deployed with version 1.0 for the very first deployment and our system would work. For subsequent releases, we might have only couple of services that will get deploy. So after couple of production releases, each microservice will be at different version to constituent an application at that point of time.
My question is :
How to logically group independently deployable microservices in order to deploy or rollback to earlier release i.e. how to determine what was the version of different microservices for earlier releases?
Is there any existing tool or standard practice to track versions of each microservice for given release to seamlessly rollback to expected release?
If not automated solution, what would be the right approach to address such requirement?
Appreciate your thoughts and suggestion on this.
With consideration kuberenets:
1. Helm is nice tool to deploy and track.
2. Native k8s deployment works nice, you need to use deployment properly especially look --record flag in k8s commands eg check this link
With AWS ECS clusters:
1. they have task definations and tasks. I think that works for you.
Not have pointers for docker-compose, swarm, and other tools. But you can always use the power of git and some scripting.
the idea is make a file that lists all versions of services/containers/code . and commit that file in git with code. Make tag out of it for simplicity. your script should compare this state file and current state and apply specific changes only. Look at git submodules also. it is nothing but a group of many git projects and it tracks status of each project with help of commit id of each project. This helped us in the situation you mention.
This is a fairly new problem, we just launched a new tool Reliza Hub to solve that. Also here is my post on the subject: Microservices – Combinatorial Explosion of Versions. Currently, we are at the MVP stage and a lot of work is going on - see this video tutorial if our direction makes sense for you https://www.youtube.com/watch?v=yDlf5fMBGuI
If you decide to implement and have any questions or need help with integration, just tag me on SO and I'd be very much willing to make it work for you.
To sum up few things that we are doing - we denote developer facing projects (those that map to source code) as Projects and customer facing projects (bundles that customer sees) as Products.
And we say that Products are essentially composition of Projects and provide tooling how you can compile different versions of Projects into what's called a Product bundle. You can then integrate this into any CI or CD tool out there or start manually if you haven't configured CICD yet.
Other than that, yes - I highly recommend helm and kubernetes - this is what we use on newer projects. (And I can also add ArgoCD and Spinnaker to the existing tooling). But it is not enough to track permutations of different versions of microservices and establishing which configurations are good and which are not between different environments.

What are the differences between GitHub Actions and other CI tools like Jenkins?

GitHub announced an upcoming feature, GitHub Actions.
I'm positive on the benefits of CI tools like Jenkins for automatic building or testing, which GitHub Actions is aimed to be used for in the future.
Having a repository on GitHub and using an external CI tool has the huge benefit of allowing to move the repository to another Git repository platform (or even local) without rewriting of the whole CI process. With GitHub Actions, you're more or less tied to the GitHub ecosystem.
I assume the integration of GitHub's Actions will be more fluent in the native environment, but are there any other advantages or disadvantages besides that?
I've been working with GitHub actions full time for a couple of months now.
It's still early days (June 2019), but here's my list:
Advantages:
GitHub actions are just consecutive docker runs. Very easy to reason about and debug.
Reproducing the build environment for container-based Travis is
possible,
but more difficult.
On GitHub actions it's just a docker build docker run away.
The individual actions in a workflow are isolated by default.
You can use a completely different computing environment for, say, compilation and testing.
Travis CI (and I think other "traditional" CI) would run all "stages" (~ actions) in the same computing environment.
Again, GitHub actions are much easier to reason about and debug.
The main.workflow spec (a subset of the HCL and really just a directed acyclic graph) is open source.
The whole thing is a pretty thin wrapper around Docker anyway, so platform lock-in is arguably minimal.
There are already open-source reimplementations of GitHub actions, such as act for local testing.
You have ready access to the GitHub API with (somewhat limited) authentication out of the box.
There might be a vibrant community (marketplace?) where people can share actions.
For example, I'm reusing deploy actions build by different people in different ecosystems.
A directed acyclic graph (DAG) and the visual editor for main.workflows is perhaps a good way to model CI/CD in particular and workflows in general.
Takes some getting used to, but generalises well.
GitHub actions can do a whole lot more than just CI! You've got basically the whole API at your fingertips as inputs and outputs.
Disadvantages:
GitHub actions (still?) has sometimes surprisingly foundational limitations at this point (june 2019).
No native caching.
You get image and layer caching (it's complicated), but nothing else.
For build artefacts, you have to roll your own cache (via AWS, Azure, etc. ...), which can be a lot of work. (You can see a hacky setup here.
Surprisingly, no support for pull requests from forks.
It's again a bit complicated, and understandable from a security standpoint, but it's currently not possible to run actions a) against the secrets of the receiving repo of a fork PR (base), and/or b) against the would-be merge result of a fork PR (that's what travis does).
For a workflow that involves forks, that makes GitHub actions largely unuseable as CI/CD tool.
Single platform, it's just whatever you can run inside docker, so some Linux distro. That seems unlikely to change, but might be an acceptable limitation.
You can always add an action to call other cross-platfrom CI/CD services.
The documentation is still pretty sparse.
Not much in the way of best practices or scaffolding.
The quality and breadth of published GitHub actions (at least on the marketplace) is still pretty low / limited.
We'll see whether that takes off.
No great way to unit-test actions. (I hacked something together, but I'm not too sure about it).
Having a repository on GitHub and using an external CI tool has the huge benefit of allowing to move the repository to another Git repository platform (or even local) without rewriting of the whole CI process.
With GitHub Actions, you're more or less tied to the GitHub ecosystem.
Yes, and starting November 2019, slightly less so:
See Joe Bourne's annoucement "Self-hosted runners for GitHub Actions is now in beta".
You can have self-hosted runners, which means:
Your environment, your tools,
Any size machine or configuration,
Secure access and networking,
Large workload support.
To support using self-hosted runners in your workflows, we’ve expanded the experience of using the runs-on key.
When registering your self-hosted runners, they’re each given a read-only label self-hosted which you can use with runs-on.
Here’s an example:
# Use Any available Self-hosted runners connected to repo
runs-on: self-hosted
See the documentation at "Hosting your own runners".

Single CI config for multiple repositories

seeking for advice about such problem.
We have stack of microservices written on NodeJs and running on Kubernetes cluster. We have separate GitHub repository for each of them and currently using Circleci for our CI/CD process. As of now we have about 25-30 repos, but their number will increase and problem that we faced now is that we need to have Circleci config yaml in each repository and if we need to change something globally in our ci/cd pipeline, we need to update this in each repository, which is obviously pretty painful process and Circleci doesn't support to have one config file for multiple repos.
I believe our situation/setup in terms of multiple repos is not unique, does anybody have experience/ideas of which CI tool support described scenario of having one config file for multiple repos?
Below are 2 approaches that I considered when had to deal with similar situation. You'd need to define for yourself what you want to optimize for and make a decision based on that
Optimizing for flexibility and isolation. In this scenario instead of making all repos use the same config file, you're keeping the file in each repo and automating how you manage this file.
For example: you'll have to create a CLI tool or a script to automate copying circle file and committing to appropriate repos (whenever a change needs to happen)
PROS: isolation - all repos have their own configuration, if you ever going to have a golang microservice or different config in one of your nodejs services, modifying CI pipeline wouldn't be an issue
CONS: a bit of extra work to write automation around managing this config separately
Optimizing for easier maintainability. Figure how to share single pipeline configuration across your repos.
For example: use git submodules for keeping circle.yml file, or use separate npm package with circle.yml file. Another alternative is to use a CI tool that supports templating, then define pipeline template and re-use it for each individual pipeline (one of the CI tools that supports it - Teamcity)
I personally picked approach #1 in similar situation. IMHO, this is a price one have to pay when one decides to go with microservices to not end up with a platform that is rather a distributed monolith :) also I really liked when all repos are descriptive and self contained and CI pipeline as code is one of the ways to help achieve that
In my mind you have 2 options - you could have a single CI job/config that can deploy any single/multiple services (if all the services are the same). Or if every service is different than you need a separate job/config for each. If it's somewhere in the middle it's a question of whether you want a single job that has a bunch of if/then statements e.g. "if repo = user then do this special thing." The if/then approach worked fine for me up to a point, but eventually, there were too many special cases at it was easier to just go with the unique config for each service.
I solved the issue of it "being hard to make a 1 line change across 30 git repos" by having a git superuser. Basically, normal users can only merge using PRs, but the superuser can commit directly. Since I'm only changing things like config files there are rarely merge conflicts or broken test cases so it works. Here's some sample code:
#!/usr/bin/env bash
for dir in /temp/*/
do
cd $dir
git pull
sed 's/Nick/John/g' report.txt > report_new.txt
git commit -m "CI change" && git push
cd ..
done

Is using multiple continuous integration services for a single project a good idea?

Currently there's plenty of CI services available like CodeShip, CircleCI and Travis and also other services to check dependencies, security, etc
Using a CI and other services that check other software quality apart from testing makes sense, but it's also possible for a single project to use multiple CI services which will execute the same tests.
What are the advantages and disadvantages of using multiple CI services for a single project?
Is there anyone using multiple CI's for a single project?
This can be on GitHub, BitBucket or any other code hosting.
Rather off-topic on SO, maybe better suited on Programmers or the proposed DevOps (if/when successful) sister SE sites.
I see advantages:
can cover combinations of verifications which a single CI system might not be able to, for one reason or another (typically technical reasons)
the project might be shared by multiple teams/individuals having different interests/methodologies/CI system preferences/requirements
I see disadvantages:
pollution of the VCS label/tag space, even potential conflicts
extra costs for each CI system

How to manage multiple components with IBM Bluemix Track & Plan

We have an application that is comprised of multiple distinct components (different functions / languages).
Is it possible in IBM Bluemix to use a single Track & Plan feature to manage the work items for the components but keep the source code in separate git repositories? For example, I would like to have one backlog for the overall application which is then backed by 5 separate git repos which house the individual components (project-frontend, project-backend, project-queue etc..).
If this is not possible does anybody have a pattern that has worked in streamlining the overall Track & Plan and still enabling the delivery pipeline / managing individual git repos? Ideally I'd like to centralize task management but keep the code distributed.
As of now, there is not a way to manage distributed git repos from a single Track & Plan project in an integrated fashion. That is not to say that it cannot be done manually, but you would need to link to commits in the remote repos in a given work item.
This can be done through the Links tab of any given work item and using the Add SVN Revisions or Add Related Artifacts. This would allow you to link to the remote repos (whether in IDS, GitHub, or private SCM tooling), while still leveraging Track & Plan as an overall planning repo.
Some of this is due to the way projects are constructed in IBM Bluemix DevOps Services today. A single project has the notion of a single git repo, a single Track & Plan instance, and a single Build Pipeline. Some of these requirements are expanding, but the platform provides integration capabilities to work with your code the way you need to right now. For example, project owners can build from remote GitHub repos in the project's Build Pipeline, so that code can be managed as you see fit, but built and deployed on IBM Bluemix.