BearBoard #4 - DevOps

BearBoard #4 - DevOps

·

4 min read

Recent development was focused on building automated workflows that deal with the repetitive tasks related to the integration of new features into the codebase and streamlining updates to the app users.

preview of the created CI/CD pipeline

BB-branching-strategy.gif


Branching strategy

As a first step, it was important to decide on the branching strategy. I settled upon GitLab Flow with environment branches.

The other 2 popular workflows like GitHub Flow and GitFlow did not fit. As I needed something a bit more extensive than GitHub Flow and GitFlow seems a bit too complex when developing an app solo.

My branching setup below

  • main - used as an alpha version of an app (for testing, pre-production)
  • production - currently deployed version to end users

bb-gitlab-branching-strat.png

GitLab Flow has some nice conventions and rules that make it an interesting choice for me: (At least this is my interpretation of how it should work and how it is implemented)

  • Possibly all changes (features, hotfixes, etc) start from a feature branch and go through all environments first before landing in production
  • Everything pushed to production branch is deployed to users
  • no release / hotfix branches, straight and simple going from feature branch up to production through each environment

Semantic-release

Convenient package worth setting up. It simplifies application versioning according to the sem-ver standard. New changes introduced into the system should be commited with a proper commit message and the rest - figuring out the next app version number is handled by semantic-release.

semantic-release Docs

For commit messages, I use commitizen.

Once semantic-release is set up, triggering the command npx semantic-release analyzes commit messages and changes the version number inside of package.json . I believe, by default, it does only change the version number, but with plugins, the functionality can be extended.

Below, my current setup in .releaserc

{
  "branches": [
    {
      "name": "production"
    },
    {
      "name": "main",
      "prerelease": "alpha"
    }
  ],
  "debug": "true",
  "plugins": [
    "@semantic-release/commit-analyzer",
    "@semantic-release/release-notes-generator",
    [
      "@semantic-release/npm",
      {
        "npmPublish": false
      }
    ],
    "@semantic-release/github",
    [
      "@semantic-release/changelog",
      {
        "changelogFile": "CHANGELOG.md"
      }
    ],
    [
      "@semantic-release/git",
      {
        "assets": [
          "package.json",
          "CHANGELOG.md"
        ],
        "message": "chore(release): create v${nextRelease.version}"
      }
    ]
  ]
}

some of the above plugins are needed to allow semantic-release to automatically commit and push changes to the repository (needed for CI workflow).

branches configuration defines channels for different versioning:

  • production - main application versions (e.g. 1.0.0, 1.3.0, 2.0.1)
  • main - alpha channel for pre-release (e.g. 1.0.0-alpha.1 )

GitHub Actions

With branching structure and semantic-release in place, I setup multiple Github Actions triggered when a specific event happens on one of the branches such as:

  • on pull_request creation into main branch
  • on push into main and production branches
  • manual trigger on merging main branch into production (control over when deployment should happen)

All of the previously mentioned components work together to handle everything related to code integration to environment branches and deployment of application updates to end users. Development happens only at the bottom of the graph with feature branches (branching off of main), everything else: running automated tests, updating version number, building application bundles, and deployment is handled by workflows.

bb-branching-with-sr-updater.png

An example workflow I have set up for production release (whenever there is a push into the production branch)

  • Create Production release - triggers semantic-release to increase the app version number
  • Build App - builds applications for Windows, Linux, and macOS
  • Modify updater.json - updates a gist needed for notifying users about the available update
  • Merge production -> main - updates main (alpha) branch after semantic-release version bump

example-workflow-run.png


Additional notes

The closer the change to production, the more tests

Ideally, the closer the change to production, the more testing should be performed. For example when finished working on a new feature, a pull request could trigger only unit tests check for time efficiency. Moving up to the next environment to pre-production / production should run integration tests and e2e tests to be sure that the application main functionality still works properly and integration won't break the current version.

I tried to add cypress e2e tests but it does not seem to work. Official docs recommend using WebDriver Testing. Unfortunately, currently, I am not able to run tests on Mac as tauri-driver is not available on this platform (dependency needed for running application in test mode)