Skip to content

Tagging Releases and Automated Builds

Alan Cleary edited this page Nov 24, 2021 · 1 revision

This repository is a monorepo, meaning it houses multiple applications (microservices) that are independently versioned. As such, there is a Standard Operating Procedure (SOP) for creating tags in order to differentiate between services. A GitHub Workflow has been setup to automate building Docker images for microservices that are tagged follow this procedure.

Tagging Releases

Per the Repository Organization page, each microservice is contained in its own top-level directory in the repository, and global Protocol Buffers are contained in the top-level proto/ directory:

root/
├── <microservice_1>/
├── <microservice_2>/
├── ...
├── <microservice_n>/
└── proto/

Since each microservice is independently versioned and GitHub releases and tags are associated with the entire repository, releases and tags must specify which microservices they are associated with. The SOP for this repository is for there to be a one-to-one relationship between releases/tags and microservices and global Protocol Buffers.

Microservices

Microservice tags must have the following structure:

<microservice>@vMAJOR.MINOR.PATCH

The <microservice> portion of the tag must exactly match the name of the directory that contains the microservice. And the MAJOR.MINOR.PATCH portion of the tag must always include MAJOR, MINOR, and PATCH values and they must be integers. For example, the Chromosome Region Python microservice would be in the top-level chromosome_region/ directory:

root/
└── chromosome_region/

So any tagged release for this microservice would start with "chromosome_region", meaning if version 1.2.0 was being released, then its release tag would be:

Note that a microservice's Protocol Buffers should be organized as described in the Protocol Buffers page. However, their version is the same as their microservice's version, which means a microservice's version should be reflected in its Protocol Buffers' file structure. For example, the Protocol Buffers for version 1.2.0 of the Chromosome Region Python microservice would be organized as follows:

root/
└── chromosome_region/
    └── proto/
        ├── chromosomeregion_service/
        │   └── v1/
        │       └── chromosomeregion.proto
        └── region/
            └── v1/
                └── region.proto

See the Protocol Buffers page for more information on this file structure and Protocol Buffer naming conventions.

Global Protocol Buffers

Per the Protocol Buffers page, each Protocol Buffer that describes a different data type has its own directory in the top-level proto/ directory:

root/
└── proto/
    ├── <datatype1>/
    ├── <datatype2>/
    ├── ...
    └── <datatypeN/

Similar to the microservices, there is a one-to-one relationship between release tags and Protocol Buffer directories. Specifically, Protocol Buffer tags must have the following structure:

proto-<datatype>@vMAJOR.MINOR.PATCH

The <datatype> portion of the tag must exactly match the name of the directory that contains the data type's Protocol Buffers. And the MAJOR.MINOR.PATCH portion of the tag must always include MAJOR, MINOR, and PATCH values and they must be integers. The MAJOR value must also match the major version encoded in the Protocol Buffers' filepath. For example, version 1.2.0 of the Region data type's Protocol Buffers would be in the region/v1/ directory:

root/
└── proto/
    └── region/
        └── v1/
            └── region.proto

Altogether, this means any tagged release for the Region data type would start with "proto-region" and the MAJOR portion of the tag would match the version encoded in the file structure, meaning if version 1.2.0 was being released, then its release tag would be:

See the Protocol Buffers page for more information on the relationship between semantic version and file structure.

Automated Builds

This repository contains a GitHub Workflow that utilizes the previously described tagging SOP to build and publish container images for each microservice when a tag is pushed.

To prepare a microservice for automated builds, the microservice must contain a Dockerfile at the top-level of its directory, as described in the Repository Organization page; the GitHub Workflow assumes this is where every microservice's Dockerfile is located. The service must then be specifically added to the Workflow file:

# .github/workflows/build-push-on-tag.yml

name: Build container image on microservice release

on:
  push:
    tags:
      - ...
      - '<microservice>@v[0-9]+.[0-9]+.[0-9]+'
      - ...

...

As previously described, the <microservice> portion of the tag must exactly match the top-level directory the microservice is in. This is because the Workflow uses this to determine where the microservice being built is located in the repository. Additionally, this will be used when naming the built image. Specifically, all built images have the following name structure:

microservices-<microservice>

Since these container images are published with all other packages from the LegumeInfo organization on the GitHub Package registry, the microservices- prefix is added to the image name to indicate what repository they were generated from. The <microservice> suffix is used to ensure each microservice has its own, versioned container image.

The following tags are given to each image built:

  • latest
  • <MAJOR>
  • <MAJOR.MINOR>
  • <MAJOR.MINOR.PATCH>

For example, if a release has the tag [email protected], the image built would be named microservices-chromosome_region and it would have the following tags:

  • latest
  • 1
  • 1.2
  • 1.2.0
Clone this wiki locally