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

feat: add support for multiple project types #3

Merged
merged 2 commits into from
Jan 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# gh-action-dotnet-bump
GitHub action which bumps the AsyncAPI document version for following Semantic Versioning.
GitHub action which bumps the library version that follows Semantic Versioning.

> NOTICE: Pre-release functionality for `type=assembly` is untested and might not work as .NET versioning there does not follow semver.

This Action bumps the version in asyncapi.json and pushes it back to the repo.
It is meant to be used on every successful merge to master but
you'll need to configured that workflow yourself.

**Attention**

Expand All @@ -28,7 +27,7 @@ Remove the 'actions/setup-node@v1' step from your action.yml file
for most common commit metadata for feature additions: `"feat: new API"` and `"feature: new API"`.
* If a commit message contains the word "pre-alpha" or "pre-beta" or "pre-rc" then the pre-release version will be increased (for example specifying pre-alpha: 1.6.0-alpha.1 -> 1.6.0-alpha.2 or, specifying pre-beta: 1.6.0-alpha.1 -> 1.6.0-beta.0)
* All other changes will increment the patch version.
* Push the bumped version in asyncapi.json back into the repo.
* Push the bumped version back into the repo.
* Push a tag for the new version back into the repo.

### Usage:
Expand Down
6 changes: 5 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
---
name: Automated Version Bump for .NET libraries
description: Automated version bump for AsyncAPI documents to follow Semantic Versioning.
description: Automated version bump for .NET libraries to follow Semantic Versioning.
runs:
using: node12
main: src/index.js
inputs:
type:
description: 'Which type of project are you bumping version for? This is important as .NET Core projects store versions in .csproj files, and .NET framework use AssemblyInfo.cs. Use either "csproj" or "assembly"'
default: 'csproj'
required: false
tag-prefix:
description: 'Prefix that is used for the git tag'
default: ''
Expand Down
22 changes: 17 additions & 5 deletions src/bumper.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ const {
logInfo,
setGitConfigs,
getProjectContent,
getCurrentVersion,
getNewProjectContent
getCurrentVersionCsproj,
getNewProjectContentCsproj,
getCurrentVersionAssembly
} = require('./utils');

module.exports = async (
Expand All @@ -26,15 +27,21 @@ module.exports = async (
pathToDocument,
targetBranch,
preReleaseId,
commitMessageToUse) => {
commitMessageToUse,
type) => {
// eslint-disable-next-line security/detect-non-literal-require
const gitEvents = process.env.GITHUB_EVENT_PATH ? require(process.env.GITHUB_EVENT_PATH) : {};
logInfo(`Found the following git events: ${JSON.stringify(gitEvents, null, 4)}`);
const workspace = process.env.GITHUB_WORKSPACE;
await setGitConfigs();
pathToDocument = path.join(workspace, pathToDocument);
const projectFile = getProjectContent(pathToDocument);
const currentVersion = getCurrentVersion(projectFile);
let currentVersion;
if (type === 'csproj') {
currentVersion = getCurrentVersionCsproj(projectFile);
} else if (type === 'assembly') {
currentVersion = getCurrentVersionAssembly(projectFile);
}

const commitMessages = getRelatedGitCommits(gitEvents);

Expand Down Expand Up @@ -88,7 +95,12 @@ module.exports = async (

//Bump version
const newVersion = bumpVersion(currentVersion, doMajorVersion, doMinorVersion, doPatchVersion, doPreReleaseVersion, preReleaseId);
const newContent = getNewProjectContent(newVersion, projectFile);
let newContent;
if (type === 'csproj') {
newContent = getNewProjectContentCsproj(newVersion, projectFile);
} else if (type === 'assembly') {
currentVersion = getCurrentVersionAssembly(projectFile);
}
// eslint-disable-next-line security/detect-non-literal-fs-filename
await promises.writeFile(pathToDocument, newContent);
await commitChanges(newVersion, skipCommit, skipTag, skipPush, commitMessageToUse);
Expand Down
4 changes: 3 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const { exitSuccess, logError, exitFailure } = require('./utils');
const defaultBumpVersion = core.getInput('default-bump-version');
const preReleaseId = core.getInput('pre-release-id');
const commitMessageToUse = core.getInput('commit-message');
const type = core.getInput('type');
const newVersion = await bumpVersion(tagPrefix,
minorWording,
majorWording,
Expand All @@ -29,7 +30,8 @@ const { exitSuccess, logError, exitFailure } = require('./utils');
targetBranch,
defaultBumpVersion,
preReleaseId,
commitMessageToUse);
commitMessageToUse,
type);
if (newVersion) {
core.setOutput('newVersion', newVersion);
exitSuccess('Version bumped!');
Expand Down
54 changes: 45 additions & 9 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function logError(error) {
function getProjectContent(pathToDocument) {
return readFileSync(pathToDocument);
}
function getCurrentVersion(csprojDocument) {
function getCurrentVersionCsproj(csprojDocument) {
const doc = new DOMParser().parseFromString(
csprojDocument,
'text/xml'
Expand All @@ -51,7 +51,7 @@ function getCurrentVersion(csprojDocument) {
return undefined;
}

function getNewProjectContent(newVersion, csprojDocument) {
function getNewProjectContentCsproj(newVersion, csprojDocument) {
const doc = new DOMParser().parseFromString(
csprojDocument,
'text/xml'
Expand Down Expand Up @@ -81,6 +81,43 @@ function getNewProjectContent(newVersion, csprojDocument) {
return new XMLSerializer().serializeToString(rootNode);
}

//Lets make sure we can match everything with exec
RegExp.prototype.execAllGen = function*(input) {
// eslint-disable-next-line security/detect-child-process
for (let match; (match = this.exec(input)) !== null;)
yield match;
}; RegExp.prototype.execAll = function(input) {
return [...this.execAllGen(input)];
};
function getCurrentVersionAssembly(assemblyDocument) {
// eslint-disable-next-line security/detect-unsafe-regex
const matchAssemblyVersion = /\[assembly: AssemblyVersion\(\"(?<version>.*)\"\)\]/gm;
const matches = matchAssemblyVersion.execAll(assemblyDocument);
if (matches.length > 0) {
// If multiple matches found, lets just assume last match is the value we are looking for...
const assemblyVersion = matches[matches.length-1].groups.version;
// Because assembly version matches major.minor.build.patch we need to convert to semver (remove build)
const versionSplit = assemblyVersion.split('.');
return `${versionSplit[0]}.${versionSplit[1]}.${versionSplit[3]}`;
}
return undefined;
}

function getNewProjectContentAssembly(newSemverVersion, assemblyDocument) {
// eslint-disable-next-line security/detect-unsafe-regex
const matchAssemblyVersion = /\[assembly: AssemblyVersion\(\"(?<version>.*)\"\)\]/gm;
const matches = matchAssemblyVersion.execAll(assemblyDocument);
const semverSplit = newSemverVersion.split('.');
const newAssemblyVersion = `${semverSplit[0]}.${semverSplit[1]}.0.${semverSplit.slice(2)}`;
if (matches.length > 0) {
//Remove and add version info, as it is easier.
assemblyDocument = assemblyDocument.replace(matchAssemblyVersion, '');
}
return `${assemblyDocument}
[assembly: AssemblyVersion("${newAssemblyVersion}")]
`;
}

function runInWorkspace(command, args) {
const workspace = process.env.GITHUB_WORKSPACE;
return new Promise((resolve, reject) => {
Expand Down Expand Up @@ -130,10 +167,7 @@ function bumpVersion(currentVersion, bumpMajorVersion, bumpMinorVersion, bumpPat

function getRelatedGitCommits(gitEvents) {
const commitMessages = gitEvents.commits;
if (commitMessages) {
if (commitMessages.length === 0) {
exitFailure('After filtering commits, none matched the AsyncAPI document or referenced files');
}
if (commitMessages && commitMessages.length > 0) {
return commitMessages;
}
exitFailure('Could not find any commits, existing');
Expand Down Expand Up @@ -197,7 +231,7 @@ async function setGitConfigs() {
await runInWorkspace('git', [
'config',
'user.email',
`"${process.env.GITHUB_EMAIL || 'gh-action-asyncapi-bump-version@users.noreply.github.com'}"`,
`"${process.env.GITHUB_EMAIL || 'gh-action-dotnet-bump@users.noreply.github.com'}"`,
]);

await runInWorkspace('git', ['fetch']);
Expand Down Expand Up @@ -241,6 +275,8 @@ module.exports = {
findPreReleaseId,
setGitConfigs,
commitChanges,
getCurrentVersion,
getNewProjectContent
getCurrentVersionCsproj,
getNewProjectContentCsproj,
getCurrentVersionAssembly,
getNewProjectContentAssembly
};
72 changes: 72 additions & 0 deletions test/__snapshots__/utils.spec.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Utils getNewProjectContentAssembly should return undefined when no version present 1`] = `
"using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle(\\"GamingEventPlugins\\")]
[assembly: AssemblyDescription(\\"Rust plugins for sharing events with the GamingEventAPI network\\")]
[assembly: AssemblyConfiguration(\\"\\")]
[assembly: AssemblyCompany(\\"\\")]
[assembly: AssemblyProduct(\\"GamingEventPlugins\\")]
[assembly: AssemblyCopyright(\\"Copyright © 2018\\")]
[assembly: AssemblyTrademark(\\"\\")]
[assembly: AssemblyCulture(\\"\\")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid(\\"e3b20e54-acff-4cb1-a5ec-97eb6ab462ef\\")]

[assembly: AssemblyVersion(\\"3.2.0.1\\")]
"
`;

exports[`Utils getNewProjectContentAssembly should return version 1`] = `
"using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle(\\"GamingEventPlugins\\")]
[assembly: AssemblyDescription(\\"Rust plugins for sharing events with the GamingEventAPI network\\")]
[assembly: AssemblyConfiguration(\\"\\")]
[assembly: AssemblyCompany(\\"\\")]
[assembly: AssemblyProduct(\\"GamingEventPlugins\\")]
[assembly: AssemblyCopyright(\\"Copyright © 2018\\")]
[assembly: AssemblyTrademark(\\"\\")]
[assembly: AssemblyCulture(\\"\\")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid(\\"e3b20e54-acff-4cb1-a5ec-97eb6ab462ef\\")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
//

[assembly: AssemblyFileVersion(\\"1.0.0.0\\")]

[assembly: AssemblyVersion(\\"3.2.0.1\\")]
"
`;