-
Notifications
You must be signed in to change notification settings - Fork 1
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 wallets version updates. #3
base: master
Are you sure you want to change the base?
Changes from all commits
89246be
ea1daca
bbf7f81
f00e9e5
89c3764
3d5a9e9
801de02
d47b6c2
e1072eb
aa3a8f4
2158dcc
76ecc8a
e2749f8
db5ec48
9ba5a48
103d923
2c79e32
02c2d10
5af4cf6
3867cdd
f8cef0a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
//registry.npmjs.org/:_authToken=${NPM_TOKEN} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,233 @@ | ||
require("dotenv").config(); | ||
const util = require("util"); | ||
const exec = util.promisify(require("child_process").exec); | ||
const versionNumberRegexp = /([vV])?([0-9]{1,2})\.([0-9]{1,2})(?:\.([0-9]{1,2}))?(?:\.([0-9]{1,2}))?[\n|\s]?/g; | ||
const wallets = require("./wallets"); | ||
const writeFile = util.promisify(require("fs").writeFile); | ||
const manifest = require("./package"); | ||
|
||
class Version { | ||
constructor(versionRegexpResult) { | ||
this.prefix = versionRegexpResult[1] || ""; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a prettier in this project, all your code should be prettified. The command: |
||
this.major = parseInt(versionRegexpResult[2]); | ||
this.minor = parseInt(versionRegexpResult[3]); | ||
this.patch = versionRegexpResult[4] ? parseInt(versionRegexpResult[4]) : null; | ||
this.fourth = versionRegexpResult[5] ? parseInt(versionRegexpResult[5]) : null; | ||
} | ||
|
||
static fromVersionString(versionString) { | ||
if (typeof versionString === "string") { | ||
versionNumberRegexp.lastIndex = 0; | ||
let regexpResult = versionNumberRegexp.exec(versionString); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could be const |
||
if (regexpResult) { | ||
return new Version(regexpResult); | ||
} | ||
} | ||
|
||
throw new Error("Can't parse version string : syntax error"); | ||
} | ||
|
||
toString() { | ||
let string = this.prefix + this.major + "." + this.minor; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. prefer template litterals for concatenation |
||
string += this.patch !== null ? "." + this.patch : ""; | ||
string += this.fourth !== null ? "." + this.fourth : ""; | ||
return string; | ||
} | ||
} | ||
|
||
class Update { | ||
constructor(walletIdentifier, from, to) { | ||
this.walletIdentifier = walletIdentifier; | ||
this.from = from; | ||
this.to = to; | ||
} | ||
|
||
toString() { | ||
return "updated " + this.walletIdentifier + " from " + this.from.toString() + " to " + this.to.toString(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For logging purpose you should look into https://github.com/pinojs/pino There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. again template litterals |
||
} | ||
} | ||
|
||
(async function() { | ||
try { | ||
console.log("--- Wallet updater launched at " + new Date() + "--"); | ||
let updates = await checkAllForUpdates(); | ||
|
||
if (updates.filter(o => { return o !== null; }).length > 0) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can use shorthand notation: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also updates.filter is immutable, it returns the filtered version of updates, but inside your conditions updates still contains all elements |
||
await updateFile(updates); | ||
await updatePatchNumber(); | ||
|
||
const commitMessage = buildCommitMessage(updates); | ||
|
||
await addDeployKey(); | ||
await addChanges(); | ||
await commit(commitMessage); | ||
await tag(commitMessage); | ||
await push(); | ||
await publish(); | ||
} else { | ||
console.log("Wallets are up to date."); | ||
} | ||
|
||
console.log("--- Wallet updater ended at " + new Date() + "--"); | ||
} catch (e) { | ||
console.error(e); | ||
} | ||
})(); | ||
|
||
|
||
async function addDeployKey() { | ||
if (!process.env.deploy_key) { | ||
throw new Error("Environment variable deploy_key is not set - cannot send modifications to server."); | ||
} | ||
const { stdout, stderr } = await exec("eval \"$(ssh-agent -s)\" && echo $deploy_key | ssh-add -"); | ||
console.log(stdout); | ||
console.log(stderr); | ||
} | ||
|
||
async function addChanges() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could create a helper to create these methods, and plz use spawn instead of exec, but be careful of the different synthax. |
||
const { stdout } = await exec("git add wallets.json package.json"); | ||
console.log(stdout); | ||
} | ||
|
||
async function commit(message) { | ||
const { stdout } = await exec("git commit -m \"" + message + "\""); | ||
console.log(stdout); | ||
} | ||
|
||
async function tag(message) { | ||
const { stdout } = await exec("git tag " + manifest.version + " -m \" " + message + "\""); | ||
console.log(stdout); | ||
} | ||
|
||
async function push() { | ||
const { stderr } = await exec("git push --follow-tags origin HEAD"); | ||
console.log(stderr); | ||
console.log("Updated wallet.json successfully"); | ||
} | ||
|
||
function buildCommitMessage(updates) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use |
||
let commitMessage = "Update wallet.json\n\n"; | ||
updates.forEach(update => { | ||
if (update) { | ||
commitMessage += update.toString() + "\n"; | ||
} | ||
}); | ||
return commitMessage; | ||
} | ||
|
||
async function updateFile(updates) { | ||
updates.forEach(update => { | ||
if (update) { | ||
wallets[update.walletIdentifier].tag = update.to.toString(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should not mutate wallets variable. |
||
} | ||
}); | ||
return writeFile("./wallets.json", JSON.stringify(wallets, null, " ")); | ||
} | ||
|
||
async function checkAllForUpdates() { | ||
const pendingUpdates = []; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems convoluted, even If I know we use to do things this way....
|
||
for (let property in wallets) { | ||
if (wallets.hasOwnProperty(property)) { | ||
pendingUpdates.push(checkForUpdates(wallets[property], property)); | ||
} | ||
} | ||
return Promise.all(pendingUpdates); | ||
} | ||
|
||
async function checkForUpdates(wallet, identifier) { | ||
const tags = await listRemoteTags(wallet.repository); | ||
let versions = parseVersionsTags(tags); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could chain |
||
const currentVersion = findCurrentVersion(wallet, identifier); | ||
if (currentVersion) { | ||
versions = versions.filter(superiorVersionsFilter(currentVersion)); | ||
versions = versions.sort(versionsSorter); | ||
|
||
if (versions.length > 0) { | ||
const targetVersion = versions[versions.length - 1]; | ||
return new Update(identifier, currentVersion, targetVersion); | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
function findCurrentVersion(wallet, identifier) { | ||
try { | ||
return Version.fromVersionString(wallet.tag); | ||
}catch (e) { | ||
console.warn("Can't determined current version for wallet : " + identifier + " missing tag"); | ||
return null; | ||
} | ||
} | ||
|
||
async function publish() { | ||
if (!process.env.NPM_TOKEN) { | ||
throw new Error("Environment variable NPM_TOKEN is not set - cannot publish package."); | ||
} | ||
try { | ||
await exec("npm whoami"); | ||
} catch (e) { | ||
throw new Error("Something went wrong authenticating you on npm - Check your NPM_TOKEN validity"); | ||
} | ||
|
||
const { stdout } = await exec("npm publish"); | ||
console.log(stdout); | ||
return stdout; | ||
} | ||
|
||
async function updatePatchNumber() { | ||
const currentVersion = Version.fromVersionString(manifest.version); | ||
currentVersion.patch += 1; | ||
|
||
manifest.version = currentVersion.toString(); | ||
return writeFile("./package.json", JSON.stringify(manifest, null, " ")); | ||
} | ||
|
||
|
||
function superiorVersionsFilter(currentVersion) { | ||
return version => { | ||
if (version.major === currentVersion.major) { | ||
if (version.minor > currentVersion.minor) { | ||
return 1; | ||
} else if (version.minor === currentVersion.minor) { | ||
if (version.patch > currentVersion.patch) { | ||
return 1; | ||
} else if (version.patch === currentVersion.patch) { | ||
if (version.fourth > currentVersion.fourth) { | ||
return 1; | ||
} | ||
} | ||
} | ||
} | ||
return 0; | ||
}; | ||
} | ||
|
||
function versionsSorter(a, b) { | ||
if ( | ||
a.major > b.major || | ||
(a.major >= b.major && a.minor > b.minor) || | ||
(a.major >= b.major && a.minor >= b.minor && a.patch > b.patch) || | ||
(a.major >= b.major && a.minor >= b.minor && a.patch >= b.patch && a.fourth > b.fourth) | ||
) { | ||
return 1; | ||
} else { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. else not needed |
||
return -1; | ||
} | ||
} | ||
|
||
function parseVersionsTags(tagLists) { | ||
const versions = []; | ||
let version = {}; | ||
versionNumberRegexp.lastIndex = 0; | ||
while ((version = versionNumberRegexp.exec(tagLists))) { | ||
versions.push(new Version(version)); | ||
} | ||
return versions; | ||
} | ||
|
||
async function listRemoteTags(remote) { | ||
const { stdout } = await exec("git ls-remote --tags " + remote); | ||
return stdout; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wallets.json package should come with 0 dependencies when integrated with other projects.
At first I thought about the wallets update automation as a separate project.
But maybe it could live inside this very project, but all dependencies should be considered as dev then