CalVer for Release Drafter

Recently, I wanted to use CalVer with Release Drafter. This is for a project where the SemVer approach would result in a perpetually increasing patch version number, and a practically frozen major and minor version. Unfortunately, Release Drafter has no inbuilt support for CalVer, so we've gotta calculate version numbers ourselves.

function parseVersion(version) {
  if (!version) return;

  const regexp = /^v?(?<calVer>\d+\.\d+)\.(?<incremental>\d+)/i
  const matches = version.match(regexp);
  if (!matches) return;

  const { calVer, incremental } = matches.groups;

  return {
    incremental: parseInt(incremental)

function currentCalVer() {
  const date = new Date();
  return `${date.getUTCFullYear()}.${date.getUTCMonth() + 1}`

module.exports = async (github, context) => {
  const calVerDate = currentCalVer();

  const latestRelease = (await{ owner: context.repo.owner, repo: context.repo.repo })).data;
  const parsedVersion = parseVersion(latestRelease.tag_name);

  if (!parsedVersion) return `${calVerDate}.0`;

  if (parsedVersion.calVer === calVerDate) return `${calVerDate}.${parsedVersion.incremental + 1}`;

This script is meant to be used with Github's actions/script workflow, which allows you to use JavaScript inside an Actions workflow. You'd call it something like this:

name: Release Drafter

      contents: write
      pull-requests: read
    runs-on: ubuntu-latest
      - uses: actions/checkout@v4
      - name: "Generate CalVer"
        uses: actions/github-script@v6
        id: calver
          result-encoding: string
          script: |
            const genCalVer = require('./.github/workflow-scripts/calver.js');
            const version = await genCalVer(github, context);
            return version;
      - uses: release-drafter/release-drafter@v5
          GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
          prerelease: ${{ github.event_name != 'pull_request' }}
          publish: false
          version: "${{ steps.calver.outputs.result }}"

Note that the version input is provided to the release-drafter script. This overrides release drafter's internal version calculations, setting it to the output result of our script.

The article “CalVer for Release Drafter” was written on