Skip to content

Commit

Permalink
Add validate-new-release command to check the diff of a plugins.xml file
Browse files Browse the repository at this point in the history
checks the diff of plugins.xml (in a PR for example), extracts the data of the new plugins, downloading their package file and validating the checksum
  • Loading branch information
kabaros committed Apr 17, 2020
1 parent f4cf0f9 commit 5ece08f
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 9 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ A set of tools by the [Public Knowledge Project](https://docs.pkp.sfu.ca/) to he

### pkp-plugin validate-releases --input ./plugins.xml

(internal tool) used by the CI job for plugins registry to extract the releases from `plugins.xml` and validate their MD5 hashes
(used internally by CI) extracts all the releases from `plugins.xml` and validate their MD5 hashes

### pkp-plugin validate-new-release

(used internally by CI) validates the new releases added to a plugin.xml file (used internally by the CI tool)

### pkp-plugin version

Expand Down
14 changes: 6 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const minimist = require('minimist')
const help = require('./src/help')
const version = require('./src/version')
const validateAllReleases = require('./src/validate-all-releases')
const validateNewRelease = require('./src/validate-new-release')

const start = async args => {
const params = minimist(args)
Expand All @@ -17,17 +18,14 @@ const start = async args => {
}

switch (cmd) {
case 'validate-new-release':
return validateNewRelease(params)
case 'validate-releases':
case 'validatereleases':
case 'validateReleases':
validateAllReleases(params)
break
return validateAllReleases(params)
case 'version':
version(params)
break
return version(params)
case 'help':
help(params)
break
return help(params)
default:
console.error(`"${cmd}" is not a valid command!`)
break
Expand Down
21 changes: 21 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"license": "ISC",
"dependencies": {
"chalk": "^4.0.0",
"follow-redirects": "^1.11.0",
"minimist": "^1.2.5",
"shelljs": "^0.8.3",
"xml2js": "^0.4.23"
Expand Down
6 changes: 6 additions & 0 deletions src/help.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,10 @@ module.exports = args => {
' extracts all releases for all plugins from a plugins.xml file and validates their MD5 checksum (used internally by the CI tool)'
)
)
console.log(
chalk.white(
chalk.green('validate-new-release'),
' validates the new releases added to a plugin.xml file (used internally by the CI tool)'
)
)
}
14 changes: 14 additions & 0 deletions src/validate-new-release/checkSumFile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const crypto = require('crypto')
const fs = require('fs')
/**
* Calculates the md5 check sum of a file
*/
module.exports = function checksumFile (path, hashName = 'md5') {
return new Promise((resolve, reject) => {
const hash = crypto.createHash(hashName)
const stream = fs.createReadStream(path)
stream.on('error', err => reject(err))
stream.on('data', chunk => hash.update(chunk))
stream.on('end', () => resolve(hash.digest('hex')))
})
}
19 changes: 19 additions & 0 deletions src/validate-new-release/download-package.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const https = require('follow-redirects').https
const fs = require('fs')

/**
* Downloads a file from the internet following the redirect (which is needed for Github links)
*/
module.exports = (package, fileName) => {
return new Promise((resolve, reject) => {
const file = fs.createWriteStream(fileName)
const req = https.get(package, function (response) {
response.pipe(file)
response.on('end', resolve)
})
req.on('error', function (err) {
console.log('Request error: ' + err.message)
reject(err)
})
})
}
20 changes: 20 additions & 0 deletions src/validate-new-release/extract-release-data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* scraps a fragment of xml to get the package url, MD5 etc..
* @param {string} lines the diffed lines showing what changed in a plugins.xml file
*/
const extractReleaseData = lines => {
const {
groups: { package }
} = /<package>(?<package>[^ $]*)<\/package>/g.exec(lines)

const {
groups: { md5 }
} = /md5=\"(?<md5>[^ $]*)\"/g.exec(lines)

return {
md5,
package
}
}

module.exports = extractReleaseData
50 changes: 50 additions & 0 deletions src/validate-new-release/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const shell = require('shelljs')
const chalk = require('chalk')
const downloadPackage = require('./download-package')
const extractReleaseData = require('./extract-release-data')
const checksumFile = require('./checkSumFile')

module.exports = async args => {
console.log(chalk.blueBright(`Checking new release`))
const diffFile = __dirname + '/diff.temp'
const command = shell.exec(`git diff origin/master | grep ^+[^+]`)
const changedLines = command.stdout

// Extract release, md5 data from diff
const { package: packageUrl, md5: expectedMD5 } = extractReleaseData(
changedLines
)
console.log(chalk.blueBright(`Package url: ${packageUrl}`))
console.log(chalk.blueBright(`MD5: ${expectedMD5}`))

// Downlaod package
const downloadedFileName = __dirname + '/downloaded_package.tar.gz'
await downloadPackage(packageUrl, downloadedFileName)

// Calculate MD5 of downloaded file
const md5 = await checksumFile(downloadedFileName)

if (md5 === expectedMD5) {
console.log(chalk.greenBright(`The MD5 of the downloaded file is correct`))
} else {
console.log(
chalk.redBright(
`The MD5 of the downloaded is incorrect. Expected ${expectedMD5}, Actual ${md5}`
)
)
shell.rm(downloadedFileName)
shell.exit(1)
}

console.log(chalk.blueBright(`MD5 of downloaded package: ${md5}`))

// check contents of tar file
shell.exec(`tar -tf ${downloadedFileName}`) // ToDO .. check contents of the tar file

shell.rm(downloadedFileName)

if (command.code !== 0) {
shell.echo('Error: checking new release failed')
shell.exit(1)
}
}

0 comments on commit 5ece08f

Please sign in to comment.