Skip to content

Improve version bump PR creation process #1869

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .github/actions/bump-version/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: "Bump version"
inputs:
github-token:
description: GitHub token for authentication
required: true
version:
description: Optional version so action can skip checking separately
runs:
using: "composite"
steps:
- name: Get release draft version and set environment variable
if: "${{ inputs.version == '' }}"
run: |
VERSION_DETAILS=gh release -R ${{ github.repository }} ls -L 1 --json isDraft,tagName
echo "PKG_VERSION=$VERSION_DETAILS" >> "$GITHUB_ENV"
env:
GH_TOKEN: ${{ inputs.github-token }}
- name: Set environment variable to version
if: "${{ inputs.version != '' }}"
run: echo "PKG_VERSION=${{ inputs.version }}" >> "$GITHUB_ENV"
- name: Bump version of package
id: bump-version
run: |
PARSED_VERSION=node .\scripts\bump-version.js $PKG_VERSION
npm version $PARSED_VERSION --commit-hooks false --git-tag-version false
echo "PKG_VERSION=$PARSED_VERSION" >> "$GITHUB_OUTPUT"
- name: Create pull request with the changes
uses: peter-evans/create-pull-request@v7
with:
token: ${{ inputs.github-token }}
commit-message: Update files containing the version of the package
branch: bump-version
title: Update version for the next release (${{ steps.bump-version.outputs.PKG_VERSION }})
body: |
_This PR is auto-generated._

- updates package version to `"${{ steps.bump-version.outputs.PKG_VERSION }}"`

> [!IMPORTANT]
>
> Every time the main branch is updated and release drafter bumps the version of the new release draft, this PR is auto-updated!
labels: skip-changelog
16 changes: 16 additions & 0 deletions .github/workflows/create-version-bump-pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Create Version Bump PR
on:
workflow_dispatch:

jobs:
update_version:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
- name: Bump version in package files and create PR
uses: ./.github/actions/bump-version
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
20 changes: 19 additions & 1 deletion .github/workflows/release-drafter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,27 @@ on:
jobs:
update_release_draft:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: release-drafter/release-drafter@v6
- name: Draft release
id: draft-release
uses: release-drafter/release-drafter@v6
with:
config-name: release-draft-template.yml
env:
GITHUB_TOKEN: ${{ secrets.RELEASE_DRAFTER_TOKEN }}
- name: Get status of version bump PR
id: pr-status
run: |
PR_NOT_OPEN=gh pr -R ${{ github.repository }} view bump-version --json closed --jq '.closed' || echo true
echo "PR_NOT_OPEN=$PR_NOT_OPEN" >> "$GITHUB_OUTPUT"
- uses: actions/checkout@v4
if: steps.pr-status.outputs.PR_NOT_OPEN == 'false'
- name: Update PR with version bump
if: steps.pr-status.outputs.PR_NOT_OPEN == 'false'
uses: ./.github/actions/bump-version
with:
version: ${{ steps.draft-release.outputs.resolved_version }}
github-token: ${{ secrets.GITHUB_TOKEN }}
60 changes: 60 additions & 0 deletions scripts/bump-version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { argv, stdout } from "node:process";
import { writeFileSync } from "node:fs";

if (argv.length !== 3) {
throw new Error("expected one command line argument", {
cause: argv.slice(2),
});
}

/** @type {string | { isDraft: boolean; tagName: string }[]} */
const arrayWithLastReleaseOrVersion = JSON.parse(argv[2]);

const pkgVersion = (function () {
if (typeof arrayWithLastReleaseOrVersion === "string") {
return arrayWithLastReleaseOrVersion;
}

if (
!Array.isArray(arrayWithLastReleaseOrVersion) ||
arrayWithLastReleaseOrVersion.length !== 1
) {
throw new Error("expected an array with one element", {
cause: arrayWithLastReleaseOrVersion,
});
}

const lastRelease = arrayWithLastReleaseOrVersion[0];
const { isDraft, tagName } = lastRelease;

if (
Object.keys(lastRelease).length !== 2 ||
typeof isDraft !== "boolean" ||
typeof tagName !== "string"
) {
throw new Error(
'expected an object with keys "isDraft" as boolean and "tagName" as string',
{ cause: lastRelease },
);
}

if (!isDraft) {
throw new Error(
"expected a draft release to be present as the first element in the releases list",
);
}

// remove the "v" from "vX.X.X"
return tagName.substring(1);
})();

const pkgVersionFileContents = `export const PACKAGE_VERSION = "${pkgVersion}";\n`;

const pkgVersionFilePath = new URL(
"../src/package-version.ts",
import.meta.url,
);

writeFileSync(pkgVersionFilePath, pkgVersionFileContents);

stdout.write(pkgVersion);