Skip to content

Latest commit

 

History

History
328 lines (273 loc) · 10.8 KB

use_cases.md

File metadata and controls

328 lines (273 loc) · 10.8 KB

Common Use Cases

These are some of the common ways that you might want to use Versio in your own development. If you find a new or novel way to use Versio, please let us know!

Quick Start

Get up and running quickly with Versio in a new or existing project.

  • Create and commit a simple config file:
    $ git pull
    $ versio init  # this creates .versio.yaml
    $ git add .versio.yaml .gitignore
    $ git commit -m "build: add versio management"
    $ git push
    $ versio release
    
  • If you want to use the GitHub API for PR scanning, you'll need to update your ~/.versio/prefs.toml file: See the Reference.
  • After some conventional commits, update it:
    $ versio release
    Executing plan:
      project : 1.0.1 -> 1.1.0
    Changes committed and pushed.
    

Add Versio to an existing Repo

If you've been releasing your project for a while before switching to Versio, you might not want to scan your entire project history the first time you release. You can tag the commit of your latest release to indicate that's where Versio should pick up:

$ git tag -f versio-prev <last_release_commit>

You can add some JSON to indicate the current version of projects. This is especially useful for version: tags style projects that don't have a manifest file which lists their version.

$ git tag -f -a -m '{"versions":{"1":"0.1.2","2":"5.2.1"}}' \
      versio-prev <last_release_commit>

You can leave off the last_release_commit argument if you want to start releasing from the latest commit.

In lieu of (or in addition to) using JSON, you can create separate tags on the latest commit that indicate the versions of your projects, using the projects' tag prefixes.

$ git tag -f proj_1_tag_prefix-v0.1.2
$ git tag -f v5.2.1

View Project Versions

Since Versio knows where all your project versions are stored, it can output them for you. It can even tell you the versions of projects as they were set by the last execution of versio release.

  • View current versions in "wide" format (which shows project IDs):

    $ versio show -w
    1. myproject    : 1.0.1
    2. otherproject : 1.0.1
    
  • View a specific project version

    $ versio get --id 1
    myproject : 1.0.1
    
  • Print just the version number

    $ versio get --id 1 -v
    1.0.1
    
  • Show the latest-released versions:

    $ versio show --prev
    myproject    : 1.0.1
    otherproject : 1.0.1
    

    If you rely solely on Versio to update project numbers for you, then the last-released version will usually match the current version.

Change a Project Version

If you want to manually set a version.

$ versio set --value 1.2.3

If you have more than one project configured, and you must supply the ID or the name of the project you want to change.

$ versio set --id 1 --value 1.2.3
$ versio set --name my_proj --value 1.2.3
$ versio set --exact my_project --value 1.2.3

Tags projects

By default, set has a default VCS level of none (see VCS Levels), so it won't commit, tag, or push your new version to a remote. This works great for most projects, allowing to you make quick local changes to your manifest file. However, "version: tags" projects have no manifest, and keep version numbers only in tags; set by default performs no action for these. To change a version in the VCS, you can use a different VCS level, like this:

$ versio -l max set --id 1 --value 1.2.3

Create a New Configuration

To start using Versio, you should create a .versio.yaml config file in your repo. Use the following command to do so. Make sure you're in the top-level directory of your repository (or the top-level directory of your non-version-controlled monorepo) when you do so:

$ versio init

This will scan your repo for existing projects, and create a new config file with each of those projects listed. If you change later add, remove, or change the location of your projects, you should edit this file by hand to keep it up-to-date.

The init command will not scan hidden directories or file, or directories or files listed in any .gitignore files. If you want to include projects in hidden or ignored locations, you'll have to add those by hand to the resulting .versio.yaml file.

Gitflow / Oneflow

If you're using Gitflow, Oneflow, or a similar process, you may have separate branchs for hotfixes or maintained versions.

To use Versio in these flows, you can use the "prev tag" option. What you want is have the hotfix branch use a different "prev tag" (default versio-prev) than your main branch. Here's what to do:

  1. Create a new branch as normal for a hotfix: this will be at a branch-point, where the branch diverges from the main release trunk. E.g. git switch -c hotfix-1234 v1.0.0 (git checkout -b hotfix-1234 v1.0.0 for older versions of git)
  2. Tag the branch-point with a unique "prev tag"; something based on the branch name would be ideal. E.g. git tag versio-prev-hotfix-1234. If there are specific project versions you want that branch to start from, you can help the process by annotating the tag: git tag -f -a -m '{"versions":{"1":"0.1.2","2":"5.2.1"}}' versio-prev-hotfix-1234. Otherwise, Versio will try to figure it out.
  3. Change the prev-tag option in the .versio.yaml file in the new branch to point to your new "prev tag":
    options:
      prev_tag: "versio-prev-hotfix-1234"
    
  4. Commit / push your change. git commit -am 'build: update versio for branch' ; git push -u origin hotfix-1234
  5. Now the hotfix branch will use versio-prev-hotfix-1234 instead of versio-prev as its "prev tag". But because you didn't change the .versio.yaml file on the main branch, main will still use versio-prev.
  6. You can versio release as normal on both the main branch and the hotfix branch independently. The first time you run it on the hotfix branch, it will re-calculate the version number based on your annotation, and/or whatever tags exist on or before the branch-point.

Warning: Using this strategy won't guard against re-using version numbers: it's possible that you could inadvertently release e.g. v1.0.3 on both the main branch and the hotfix branch: in that case, the tag will move to whichever is released last, which is probably not what you want. Be certain that you aren't clobbering your version numbers when you release. versio release --dry-run can be useful.

CI/CD

GitHub Action Matrixes

If you are using a monorepo, you may want to perform the same build step on all your (for example) Node.js projects. You can build GitHub dynamic matrixes using the versio info command, and then use those matrixes to execute multiple projects in your repo. For example, if you wanted to run 'npm test' in every project in your monorepo with the npm label:

jobs:
  project-matrixes:
    runs-on: ubuntu-latest
    outputs:
      npm-matrix: "${{ steps.find-npm-matrix.outputs.matrix }}"
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Get versio
        uses: chaaz/versio-actions/[email protected]
      - name: Find npm matrix
        id: find-npm-matrix
        run: echo matrix={\"include\":$(versio -l none info -l npm -R -N)} >> $GITHUB_OUTPUT
  npm-tests:
    needs: project-matrixes
    runs-on: ubuntu-latest
    strategy:
      matrix: "${{ fromJson(needs.project-matrixes.outputs.npm-matrix) }}"
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Run local tests
        run: npm test
        working-directory: "${{ matrix.root }}"

Authorization

In most CI/CD environments, you may not have a credentials agent available to negotiate credentials to your git repo and/or github APIs. Instead, your should set the GITHUB_USER and GITHUB_TOKEN environment variables. For example, GitHub Actions provides these values to you in various places:

env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  GITHUB_USER: ${{ github.actor }}

CI Pre-merge

You can use Versio to check that a branch is ready to be merged to your deployment branch. Your CI pipeline can run versio check to ensure that the .versio.yaml file is properly configured, and can versio plan to log the version changes which will be applied once merged.

GitHub Actions

Use the example snippet to build a workflow for pull requests that can verify that Versio is configured correctly for all projects, and which will print out all changes in the PR, and their possible effect on the project(s) version numbers.

Note the use of checkout@v3, and the following git fetch --unshallow command, which is necessary to fill in the git history before versio is asked to analyze it. Also, we've provided a versio-actions/[email protected] command which installs the versio command into the job. (Currently, the versio-actions/install action only works for linux-based runners.)

---
name: pr
on:
  - pull_request
env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  GITHUB_USER: ${{ github.actor }}

jobs:
  versio-checks:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Get versio
        uses: chaaz/versio-actions/[email protected]
      - name: Fetch history
        run: git fetch --unshallow
      - name: Check projects
        run: versio check
      - name: Print changes
        run: versio plan

CI Release

As part of your CI/CD pipeline, you can create an action to execute versio release, which will update the version numbers, generate changelogs, and commit and push all changes. You can set this action to run automatically when a branch has been merged to a release branch, or at any other time you want your software to be released.

About Timing

It's important to note that nothing can be pushed to the release branch during the short time that versio release is running, or else it will fail. There are a number of ways you can deal with this: from locking the branch while Versio is running; to creating a pre-release branch to separate merges from the release process; to simply ignoring the problem and manually re-running the CI action if it gets stuck; and more. The strategy you use is dependent on the specifics of your organization and CI/CD process.

GitHub Actions

A GitHub Actions job that releases your projects might look something like this:

jobs:
  versio-release:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Get versio
        uses: chaaz/versio-actions/[email protected]
      - name: Fetch history
        run: git fetch --unshallow
      - name: Generate release
        run: versio release