Skip to content
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

Automate release on merge in develop #590

Merged
merged 31 commits into from
Dec 29, 2023
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
0c07203
Add first version of github merge workflow
mukulmishra18 Dec 27, 2023
674921f
Add helper function to define release version
mukulmishra18 Dec 27, 2023
9fc5da1
Add helper function to update change during merge workflow
mukulmishra18 Dec 27, 2023
531c5c2
Push tag without using github token
mukulmishra18 Dec 27, 2023
afd5736
Set upstream during push to origin
mukulmishra18 Dec 27, 2023
42b7482
Access output variables from outputs namespace
mukulmishra18 Dec 27, 2023
e75fa8f
Use temp branch for testing
mukulmishra18 Dec 27, 2023
af1b347
Use workflow_dispatch instead of pr merge event for testing
mukulmishra18 Dec 27, 2023
06f6320
Revert triggering of workflow on workflow_dispatch event
mukulmishra18 Dec 27, 2023
3719aa1
Use steps namespace to access the output
mukulmishra18 Dec 27, 2023
a96bd78
Use script instead of run
mukulmishra18 Dec 28, 2023
9997901
Move checkout step up in the workflow
mukulmishra18 Dec 28, 2023
4405794
Remove token usage
mukulmishra18 Dec 28, 2023
8d85dd3
Add semver in dev-dependencies
mukulmishra18 Dec 28, 2023
13eaea9
Restructure the workflow
mukulmishra18 Dec 28, 2023
c849cb4
Fix npm version command
mukulmishra18 Dec 28, 2023
4aae50a
Move git configure before bumping npm version
mukulmishra18 Dec 28, 2023
001adf5
Update workflow and job name
mukulmishra18 Dec 28, 2023
a527d5b
Remove triggering workflow on push event
mukulmishra18 Dec 28, 2023
f458495
Add unit test for defineVersion
mukulmishra18 Dec 28, 2023
a71d0bc
Use develop branch instead of testing branch
mukulmishra18 Dec 28, 2023
df64254
Fix indentation
mukulmishra18 Dec 28, 2023
9c7eb05
Rename file
mukulmishra18 Dec 28, 2023
42dba0c
Remove checkout step
mukulmishra18 Dec 28, 2023
ef2b9b5
Remove using inputs namespace
mukulmishra18 Dec 28, 2023
29c7716
Refactor defineVersion to remove prereleaseTag
mukulmishra18 Dec 28, 2023
63a80cf
Update commit message
mukulmishra18 Dec 29, 2023
fdba5fe
Update file name
mukulmishra18 Dec 29, 2023
e912e24
Change job name
mukulmishra18 Dec 29, 2023
43e6d24
Remove fallback to CI branch
mukulmishra18 Dec 29, 2023
294a431
Add changelog entry
mukulmishra18 Dec 29, 2023
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
57 changes: 57 additions & 0 deletions .github/scripts/defineVersion.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
const semver = require('semver');

function determinePreReleaseTag(existingVersion, targetReleaseLevel) {
const existingPreReleaseVersion = semver.prerelease(existingVersion);
if (existingPreReleaseVersion && existingPreReleaseVersion.length > 0) {
return `prerelease`;
}

return `pre${targetReleaseLevel}`;
}

function defineNewVersion(targetReleaseLevel, existingVersion, prereleaseTag) {
let releaseTag = targetReleaseLevel;

if (prereleaseTag) {
releaseTag = determinePreReleaseTag(existingVersion, targetReleaseLevel);
}

return semver.inc(existingVersion, releaseTag, prereleaseTag, undefined);
}

function getPlayerUiVersion(versionInput) {
let targetVersion = versionInput ?? process.env.CI_BRANCH;

if (!targetVersion) {
console.log('no version provided using CI_BRANCH');
process.exit(1);
}
offnertho marked this conversation as resolved.
Show resolved Hide resolved

const playerUiVersion = semver.valid(targetVersion);
if (!playerUiVersion) {
console.error(`${targetVersion} is not a valid semver`);
process.exit(1);
}

return {
major: semver.major(playerUiVersion),
minor: semver.minor(playerUiVersion),
patch: semver.patch(playerUiVersion),
prereleaseLabels: semver.prerelease(playerUiVersion),
full: playerUiVersion,
};
}

function defineReleaseVersion({ core }, targetReleaseLevel, prereleaseTag, givenVersion) {
core.info(
`Defining new release version for level ${targetReleaseLevel} and prereleaseTag ${prereleaseTag} given the version ${givenVersion}`,
);

const newVersion = defineNewVersion(targetReleaseLevel, givenVersion, prereleaseTag);

const parsedPlayerVersion = getPlayerUiVersion(newVersion);
core.info(`Using release version ${parsedPlayerVersion.full}`);
return parsedPlayerVersion;
}

module.exports.defineReleaseVersion = defineReleaseVersion;
17 changes: 17 additions & 0 deletions .github/scripts/updateChangelog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Updates the changelog by replacing the changelog header with the correct version
*
* @param {string} changelogString the content of the changelog file
* @param {string} version the player version to be released
* @param {string} releaseDate the release date to be written to the changelog
*/
function updateChangeLog(changelogString, version, releaseDate) {
const optionalBetaOrRc = '(-rc.d+)?(-(b|beta).d+)?';
const changelogVersionRegExp = new RegExp(
`\\[(development|develop|unreleased|${version})${optionalBetaOrRc}.*`,
'gi',
);
return changelogString.replace(changelogVersionRegExp, `[${version}] - ${releaseDate}`);
}

module.exports.updateChangeLog = updateChangeLog;
69 changes: 69 additions & 0 deletions .github/workflows/merge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Trigger release on merge
mukulmishra18 marked this conversation as resolved.
Show resolved Hide resolved
run-name: Starting release for ${{ github.actor }} PR merge
offnertho marked this conversation as resolved.
Show resolved Hide resolved
on:
pull_request:
types:
- closed
branches:
- develop

jobs:
on_pr_merge:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Checkout develop
uses: actions/checkout@v4
with:
ref: develop
mukulmishra18 marked this conversation as resolved.
Show resolved Hide resolved

- name: Install dependencies
run: npm ci

- name: Read package.json version
uses: actions/github-script@v6
id: define-package-json-version
with:
script: |
const { version } = require('./package.json')
core.info(`performing a ${{ inputs.release-type }} release for existing version ${version}`)
mukulmishra18 marked this conversation as resolved.
Show resolved Hide resolved
core.setOutput('packageJsonVersion', version)

- name: Define release version
uses: actions/github-script@v6
id: define-release-version
with:
script: |
const { defineReleaseVersion } = require('./.github/scripts/defineVersion.js')
return defineReleaseVersion({core}, 'minor', undefined, "${{ steps.define-package-json-version.outputs.packageJsonVersion }}" )
offnertho marked this conversation as resolved.
Show resolved Hide resolved

- name: Bump package.json version
run: |
git config --global user.name 'Automated Release'
git config --global user.email '[email protected]'
npm version "${{ fromJson(steps.define-release-version.outputs.result).full }}"

- name: Update Changelog
offnertho marked this conversation as resolved.
Show resolved Hide resolved
uses: actions/github-script@v6
with:
script: |
const fs = require('fs');
const { updateChangeLog } = require('./.github/scripts/updateChangelog.js')

const stableVersion = '${{ fromJson(steps.define-release-version.outputs.result).full }}'.split('-')[0]
const releaseDate = new Date().toISOString().split('T')[0]

const data = fs.readFileSync('./CHANGELOG.md',{encoding:'utf8', flag:'r'});

core.info(`Updating ${stableVersion} with date ${releaseDate} in Changelog`);

const changelogFileContents = updateChangeLog(data, stableVersion, releaseDate);

fs.writeFileSync('./CHANGELOG.md', changelogFileContents, 'utf-8');

- name: Push changes
run: |
git add .
git commit -m "Bump version ${{ fromJson(steps.define-release-version.outputs.result).full }} and update changelog"
git push origin develop
git push origin --tags
108 changes: 51 additions & 57 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"merge2": "^1.4.1",
"postcss-svg": "^3.0.0",
"sass": "^1.59.3",
"semver": "^7.5.4",
"stream-combiner2": "^1.1.1",
"ts-jest": "^29.0.5",
"tsify": "^5.0.4",
Expand All @@ -59,4 +60,4 @@
"watchify": "^4.0.0",
"yargs": "^17.7.1"
}
}
}
31 changes: 31 additions & 0 deletions spec/release/defineVersion.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const { defineReleaseVersion } = require('../../.github/scripts/defineVersion');

describe('defineReleaseVersion', () => {
test.each`
existingVersion | desiredReleaseLevel | preReleaseTag | expectedVersion
${'1.0.0'} | ${'major'} | ${undefined} | ${'2.0.0'}
${'1.0.0'} | ${'minor'} | ${undefined} | ${'1.1.0'}
${'1.1.0'} | ${'minor'} | ${undefined} | ${'1.2.0'}
${'1.0.0'} | ${'patch'} | ${undefined} | ${'1.0.1'}
${'1.1.0'} | ${'patch'} | ${undefined} | ${'1.1.1'}
${'1.0.4'} | ${'patch'} | ${undefined} | ${'1.0.5'}
${'1.0.0'} | ${'minor'} | ${'rc'} | ${'1.1.0-rc.0'}
${'1.1.0-rc.0'} | ${'minor'} | ${undefined} | ${'1.1.0'}
${'1.0.0'} | ${'minor'} | ${'beta'} | ${'1.1.0-beta.0'}
${'1.1.0-beta.0'} | ${'minor'} | ${'beta'} | ${'1.1.0-beta.1'}
${'1.1.0-beta.5'} | ${'minor'} | ${'beta'} | ${'1.1.0-beta.6'}
${'1.0.0'} | ${'major'} | ${'beta'} | ${'2.0.0-beta.0'}
${'1.5.0'} | ${'major'} | ${'beta'} | ${'2.0.0-beta.0'}
${'1.5.0'} | ${'major'} | ${'rc'} | ${'2.0.0-rc.0'}
${'2.0.0-beta.0'} | ${'major'} | ${'rc'} | ${'2.0.0-rc.0'}
${'2.0.0-rc.1'} | ${'major'} | ${undefined} | ${'2.0.0'}
`(
'should return version $expectedVersion with version $existingVersion and $desiredReleaseLevel release level',
({ existingVersion, desiredReleaseLevel, preReleaseTag, expectedVersion }) => {
const core = { info() {} };
const result = defineReleaseVersion({ core }, desiredReleaseLevel, preReleaseTag, existingVersion);

expect(result.full).toEqual(expectedVersion);
},
);
});
Loading