July 15, 2024

GitHub Action Script for Semantic Versioning


Overview

This code snippet generates:

  1. queries the most recent GitHub release for tag name
  2. calculates the new version number dependent on an environment variable RELEASE_TYPE (options are major, minor, or patch)
  3. creates a new GitHub release using new version number
.github/workflows/scripts/create-release.js
module.exports = async ({ github, context, core }) => {
  console.log("Release Type: ", process.env.RELEASE_TYPE);

  const latestRelease = await github.rest.repos.getLatestRelease({
    owner: context.repo.owner,
    repo: context.repo.repo,
  });

  const latestTag = latestRelease.data.tag_name;
  const versionParts = latestTag.replace(/^v/, "").split(".");

  console.log("Latest Release Tag: ", latestTag);

  let major = Number.parseInt(versionParts[0]);
  let minor = Number.parseInt(versionParts[1]);
  let patch = Number.parseInt(versionParts[2]);

  if (process.env.RELEASE_TYPE === "major") {
    major += 1;
    minor = 0;
    patch = 0;
  } else if (process.env.RELEASE_TYPE === "minor") {
    minor += 1;
    patch = 0;
  } else {
    patch += 1;
  }

  const nextVersion = `v${major}.${minor}.${patch}`;

  console.log("Creating Release: ", nextVersion);

  const response = await github.rest.repos.createRelease({
    owner: context.repo.owner,
    repo: context.repo.repo,
    tag_name: nextVersion,
    name: nextVersion,
    generate_release_notes: true,
    draft: false,
    prerelease: false,
  });

  core.setOutput("version", nextVersion);
  core.setOutput("release_url", response.data.html_url);
};
js

and can be used like this:

on: push

jobs:
  echo-input:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/github-script@v7
        with:                                                                         
          script: |
            const script = require('./.github/workflows/scripts/create-release.js')
            await script({github, context, core})
yaml

This is all documented at actions/github-script.

This was at one point useful when I was generating semantic versions for all my releases, but recently simplified to just using the shortened Git Sha and continuously releasing with every commit.