Skip to content

Commit

Permalink
Merge pull request #10 from GauzStudio/fred-update-semantic-versioning
Browse files Browse the repository at this point in the history
change retry dynamics
  • Loading branch information
FredericoGauz authored Mar 3, 2021
2 parents d893dd5 + a055612 commit ce7ff95
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 161 deletions.
116 changes: 48 additions & 68 deletions .github/actions/bumpVersion/bumpVersion.js
Original file line number Diff line number Diff line change
@@ -1,75 +1,55 @@
const {exec} = require('child_process');

// const fs = require('fs');
const core = require('@actions/core');
const github = require('@actions/github');
const functions = require('./functions');

// Use Github Actions' default environment variables to get repo information
// https://docs.github.com/en/free-pro-team@latest/actions/reference/environment-variables#default-environment-variables
// const [repoOwner, repoName] = process.env.GITHUB_REPOSITORY.split('/');

const MAX_RETRIES = 10;
let errCount = 0;
let shouldRetry;

do {
shouldRetry = false;
// eslint-disable-next-line no-loop-func
exec('npm version prerelease -m "Update version to %s"', (err, stdout, stderr) => {
console.log(stdout);
if (err) {
console.log(stderr);

// It's possible that two PRs were merged in rapid succession.
// In this case, both PRs will attempt to update to the same npm version.
// This will cause the deploy to fail with an exit code 128
// saying the git tag for that version already exists.
if (errCount < MAX_RETRIES) {
console.log(
'Err: npm version conflict, attempting to automatically resolve',
`retryCount: ${++errCount}`,
);
shouldRetry = true;

// const { version } = JSON.parse(fs.readFileSync('./package.json'));

// const currentPatchVersion = `v${version.slice(0, -4)}`;
// console.log('Current patch version:', currentPatchVersion);

console.log('Fetching tags from github...');
const octokit = github.getOctokit(core.getInput('GITHUB_TOKEN', {required: true}));
octokit.repos.listTags({
owner: github.context.repo.owner,
repo: github.context.repo.repo,
})
.then((response) => {
const tags = response.data.map(tag => tag.name);

// tags come from latest to oldest
const highestVersion = tags[0];
console.log(`Highest version found: ${highestVersion}.`);

let semanticVersionLevel = core.getInput('SEMVER_LEVEL', {require: true});

// SEMVER_LEVEL defaults to BUILD
// it actually would fall to build anyway, but I think it is better to make it explicity
if (!semanticVersionLevel || !Object.values(functions.semanticVersionLevels)
.find(v => v === semanticVersionLevel)) {
// eslint-disable-next-line max-len, semi
console.log(`Invalid input for 'SEMVER_LEVEL': ${semanticVersionLevel},defaulting to: ${functions.semanticVersionLevels.build}`)
semanticVersionLevel = functions.semanticVersionLevels.build;
}
const newVersion = functions.incrementVersion(highestVersion, semanticVersionLevel);

core.setOutput('VERSION', newVersion);

functions.execUpdateToNewVersion(newVersion);
})
.catch(exception => core.setFailed(exception));
} else {
core.setFailed(err);
}
}
const octokit = github.getOctokit(core.getInput('GITHUB_TOKEN', {required: true}));
let semanticVersionLevel = core.getInput('SEMVER_LEVEL', {require: true});

// SEMVER_LEVEL defaults to BUILD
// it actually would fall to build anyway, but I think it is better to make it explicitly
if (!semanticVersionLevel || !Object.values(functions.semanticVersionLevels).find(v => v === semanticVersionLevel)) {
// eslint-disable-next-line max-len, semi
console.log(`Invalid input for 'SEMVER_LEVEL': ${semanticVersionLevel}, defaulting to: ${functions.semanticVersionLevels.build}`)
semanticVersionLevel = functions.semanticVersionLevels.build;
}

// eslint-disable-next-line no-shadow
const bumpVersion = async (core, github, semanticVersionLevel) => {
console.log('Fetching tags from github...');
const response = await octokit.repos.listTags({
owner: github.context.repo.owner,
repo: github.context.repo.repo,
});
} while (shouldRetry);
const tags = response.data.map(tag => tag.name);

// tags come from latest to oldest
const highestVersion = tags[0];
console.log(`Highest version found: ${highestVersion}.`);

const newVersion = functions.incrementVersion(highestVersion, semanticVersionLevel);

core.setOutput('VERSION', newVersion);

const {stdout} = await functions.execUpdateToNewVersion(newVersion);
console.log(stdout);
};


// It's possible that two PRs were merged in rapid succession.
// In this case, both PRs will attempt to update to the same npm version.
// This will cause the deploy to fail with an exit code 128
// saying the git tag for that version already exists.
for (let retry = 0; retry < MAX_RETRIES; retry++) {
try {
bumpVersion(core, github, semanticVersionLevel);
break;
} catch (error) {
console.log(
'Err: npm version conflict, attempting to automatically resolve',
`retryCount: ${retry}`,
);
console.log(error);
}
}
18 changes: 5 additions & 13 deletions .github/actions/bumpVersion/functions.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const {exec} = require('child_process');
const utils = require('util');
const exec = utils.promisify(require('child_process').exec);

const semanticVersionLevels = {
major: 'MAJOR',
Expand Down Expand Up @@ -50,18 +51,9 @@ const incrementVersion = (version, level) => {
return incrementPatch(major, minor, patch);
};

const execUpdateToNewVersion = (version) => {
exec(
`npm version ${version} -m "Update version to ${version}"`,
// eslint-disable-next-line no-shadow
(err, stdout, stderr) => {
console.log(stdout);
if (err) {
console.log(stderr);
}
},
);
};
const execUpdateToNewVersion = async version => exec(
`npm version ${version} -m "Update version to ${version}"`,
);

module.exports = {
execUpdateToNewVersion,
Expand Down
135 changes: 55 additions & 80 deletions .github/actions/bumpVersion/index.js
Original file line number Diff line number Diff line change
@@ -1,93 +1,77 @@
/**
* NOTE: This is a compiled file. DO NOT directly edit this file.
*/
module.exports =
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({

/***/ 1326:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __nccwpck_require__) => {

const {exec} = __nccwpck_require__(3129);

// const fs = require('fs');
const core = __nccwpck_require__(9189);
const github = __nccwpck_require__(8349);
const functions = __nccwpck_require__(2812);

// Use Github Actions' default environment variables to get repo information
// https://docs.github.com/en/free-pro-team@latest/actions/reference/environment-variables#default-environment-variables
// const [repoOwner, repoName] = process.env.GITHUB_REPOSITORY.split('/');

const MAX_RETRIES = 10;
let errCount = 0;
let shouldRetry;

do {
shouldRetry = false;
// eslint-disable-next-line no-loop-func
exec('npm version prerelease -m "Update version to %s"', (err, stdout, stderr) => {
console.log(stdout);
if (err) {
console.log(stderr);

// It's possible that two PRs were merged in rapid succession.
// In this case, both PRs will attempt to update to the same npm version.
// This will cause the deploy to fail with an exit code 128
// saying the git tag for that version already exists.
if (errCount < MAX_RETRIES) {
console.log(
'Err: npm version conflict, attempting to automatically resolve',
`retryCount: ${++errCount}`,
);
shouldRetry = true;

// const { version } = JSON.parse(fs.readFileSync('./package.json'));

// const currentPatchVersion = `v${version.slice(0, -4)}`;
// console.log('Current patch version:', currentPatchVersion);

console.log('Fetching tags from github...');
const octokit = github.getOctokit(core.getInput('GITHUB_TOKEN', {required: true}));
octokit.repos.listTags({
owner: github.context.repo.owner,
repo: github.context.repo.repo,
})
.then((response) => {
const tags = response.data.map(tag => tag.name);

// tags come from latest to oldest
const highestVersion = tags[0];
console.log(`Highest version found: ${highestVersion}.`);

let semanticVersionLevel = core.getInput('SEMVER_LEVEL', {require: true});

// SEMVER_LEVEL defaults to BUILD
// it actually would fall to build anyway, but I think it is better to make it explicity
if (!semanticVersionLevel || !Object.values(functions.semanticVersionLevels)
.find(v => v === semanticVersionLevel)) {
// eslint-disable-next-line max-len, semi
console.log(`Invalid input for 'SEMVER_LEVEL': ${semanticVersionLevel},defaulting to: ${functions.semanticVersionLevels.build}`)
semanticVersionLevel = functions.semanticVersionLevels.build;
}
const newVersion = functions.incrementVersion(highestVersion, semanticVersionLevel);

core.setOutput('VERSION', newVersion);
const octokit = github.getOctokit(core.getInput('GITHUB_TOKEN', {required: true}));
let semanticVersionLevel = core.getInput('SEMVER_LEVEL', {require: true});

functions.execUpdateToNewVersion(newVersion);
})
.catch(exception => core.setFailed(exception));
} else {
core.setFailed(err);
}
}
// SEMVER_LEVEL defaults to BUILD
// it actually would fall to build anyway, but I think it is better to make it explicitly
if (!semanticVersionLevel || !Object.values(functions.semanticVersionLevels).find(v => v === semanticVersionLevel)) {
// eslint-disable-next-line max-len, semi
console.log(`Invalid input for 'SEMVER_LEVEL': ${semanticVersionLevel}, defaulting to: ${functions.semanticVersionLevels.build}`)
semanticVersionLevel = functions.semanticVersionLevels.build;
}

// eslint-disable-next-line no-shadow
const bumpVersion = async (core, github, semanticVersionLevel) => {
console.log('Fetching tags from github...');
const response = await octokit.repos.listTags({
owner: github.context.repo.owner,
repo: github.context.repo.repo,
});
} while (shouldRetry);
const tags = response.data.map(tag => tag.name);

// tags come from latest to oldest
const highestVersion = tags[0];
console.log(`Highest version found: ${highestVersion}.`);

const newVersion = functions.incrementVersion(highestVersion, semanticVersionLevel);

core.setOutput('VERSION', newVersion);

const {stdout} = await functions.execUpdateToNewVersion(newVersion);
console.log(stdout);
};


// It's possible that two PRs were merged in rapid succession.
// In this case, both PRs will attempt to update to the same npm version.
// This will cause the deploy to fail with an exit code 128
// saying the git tag for that version already exists.
for (let retry = 0; retry < MAX_RETRIES; retry++) {
try {
bumpVersion(core, github, semanticVersionLevel);
break;
} catch (error) {
console.log(
'Err: npm version conflict, attempting to automatically resolve',
`retryCount: ${retry}`,
);
console.log(error);
}
}


/***/ }),

/***/ 2812:
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {

const {exec} = __nccwpck_require__(3129);
const utils = __nccwpck_require__(1669);
const exec = utils.promisify(__nccwpck_require__(3129).exec);

const semanticVersionLevels = {
major: 'MAJOR',
Expand Down Expand Up @@ -139,18 +123,9 @@ const incrementVersion = (version, level) => {
return incrementPatch(major, minor, patch);
};

const execUpdateToNewVersion = (version) => {
exec(
`npm version ${version} -m "Update version to ${version}"`,
// eslint-disable-next-line no-shadow
(err, stdout, stderr) => {
console.log(stdout);
if (err) {
console.log(stderr);
}
},
);
};
const execUpdateToNewVersion = async version => exec(
`npm version ${version} -m "Update version to ${version}"`,
);

module.exports = {
execUpdateToNewVersion,
Expand Down

0 comments on commit ce7ff95

Please sign in to comment.