290 lines
9.5 KiB
JavaScript
290 lines
9.5 KiB
JavaScript
const github = require('@actions/github')
|
|
const core = require('@actions/core')
|
|
const orderBy = require('lodash/orderBy')
|
|
const find = require('lodash/find')
|
|
const round = require('lodash/round')
|
|
const fs = require('fs/promises')
|
|
const { DateTime } = require('luxon')
|
|
// const isPlainObject = require('lodash/isPlainObject')
|
|
|
|
const dec = new TextDecoder()
|
|
|
|
async function main () {
|
|
const token = core.getInput('token')
|
|
// const tokenCommon = core.getInput('tokenCommon')
|
|
const inputCovPath = core.getInput('coverageResultsPath') // 'data/coverage-raw.json'
|
|
const outputCovPath = core.getInput('coverageResultsPath') // 'data/coverage.json'
|
|
const outputHistPath = core.getInput('histCoveragePath') // 'data/historical-coverage.json'
|
|
const relVersionRaw = core.getInput('version') // 'v7.47.0'
|
|
const relVersion = relVersionRaw.indexOf('v') === 0 ? relVersionRaw.substring(1) : relVersionRaw
|
|
const gh = github.getOctokit(token)
|
|
// const ghCommon = github.getOctokit(tokenCommon)
|
|
const owner = github.context.repo.owner // 'ietf-tools'
|
|
const repo = github.context.repo.repo // 'datatracker'
|
|
const sender = github.context.payload.sender.login // 'rjsparks'
|
|
const repoCommon = core.getInput('repoCommon') // 'common'
|
|
const summary = core.getInput('summary') // ''
|
|
const changelog = core.getInput('changelog') // ''
|
|
|
|
// -> Parse coverage results
|
|
console.info('Parsing coverage.json file...')
|
|
const covLatest = JSON.parse(await fs.readFile(inputCovPath, 'utf8'))
|
|
const covLatestStats = {
|
|
code: covLatest.latest.code.coverage,
|
|
template: covLatest.latest.template.coverage,
|
|
url: covLatest.latest.url.coverage
|
|
}
|
|
|
|
// -> Fix coverage results versioning
|
|
console.info(`Writing ${relVersion} normalized coverage.json file...`)
|
|
fs.writeFile(outputCovPath, JSON.stringify({
|
|
[relVersion]: covLatest.latest,
|
|
version: relVersion
|
|
}, null, 2), 'utf8')
|
|
|
|
// -> Fetch existing releases
|
|
const releases = []
|
|
let hasMoreReleases = false
|
|
let releasesCurPage = 0
|
|
do {
|
|
hasMoreReleases = false
|
|
releasesCurPage++
|
|
const resp = await gh.request('GET /repos/{owner}/{repo}/releases', {
|
|
owner,
|
|
repo,
|
|
page: releasesCurPage,
|
|
per_page: 100
|
|
})
|
|
if (resp?.data?.length > 0) {
|
|
console.info(`Fetching existing releases... ${(releasesCurPage - 1) * 100}`)
|
|
hasMoreReleases = true
|
|
releases.push(...resp.data)
|
|
}
|
|
} while (hasMoreReleases)
|
|
console.info(`Found ${releases.length} existing releases.`)
|
|
|
|
// -> Fetch latest historical coverage
|
|
let covData = null
|
|
for (const rel of orderBy(releases, ['created_at'], ['desc'])) {
|
|
if (rel.draft) { continue }
|
|
|
|
const covAsset = find(rel.assets, ['name', 'historical-coverage.json'])
|
|
if (covAsset) {
|
|
console.info(`Fetching latest historical-coverage.json from release ${rel.name}...`)
|
|
const covRaw = await gh.request('GET /repos/{owner}/{repo}/releases/assets/{asset_id}', {
|
|
owner,
|
|
repo,
|
|
asset_id: covAsset.id,
|
|
headers: {
|
|
Accept: 'application/octet-stream'
|
|
}
|
|
})
|
|
covData = JSON.parse(dec.decode(covRaw.data))
|
|
break
|
|
}
|
|
}
|
|
|
|
// -> Update historical coverage
|
|
if (!covData) {
|
|
console.warn('Could not find historical coverage data... Skipping...')
|
|
} else {
|
|
console.info('Writing updated historical-coverage.json file...')
|
|
covData = {
|
|
[relVersion]: covLatestStats,
|
|
...covData
|
|
}
|
|
await fs.writeFile(outputHistPath, JSON.stringify(covData, null, 2), 'utf8')
|
|
}
|
|
|
|
// -> Find matching release version
|
|
const newRelease = find(releases, ['name', relVersionRaw])
|
|
if (!newRelease) {
|
|
console.warn(`Could not find a release matching ${relVersionRaw}... Skipping coverage chart generation...`)
|
|
return
|
|
}
|
|
|
|
// -> Fetch list of existing chart files in common repo
|
|
console.info('Fetching list of existing chart files from common repo...')
|
|
const chartsDirListing = []
|
|
const respDir = await gh.request('GET /repos/{owner}/{repo}/contents/{path}', {
|
|
owner,
|
|
repo: repoCommon,
|
|
path: 'assets/graphs/datatracker'
|
|
})
|
|
if (respDir?.data?.length > 0) {
|
|
chartsDirListing.push(...respDir.data)
|
|
}
|
|
|
|
// -> Coverage Chart
|
|
// if (chartsDirListing.some(c => c.name === `${newRelease.id}.svg`)) {
|
|
// console.info(`Chart SVG already exists for ${newRelease.name}, skipping...`)
|
|
// } else {
|
|
// console.info(`Generating chart SVG for ${newRelease.name}...`)
|
|
|
|
// const { ChartJSNodeCanvas } = require('chartjs-node-canvas')
|
|
// const chartJSNodeCanvas = new ChartJSNodeCanvas({ type: 'svg', width: 850, height: 300, backgroundColour: '#FFFFFF' })
|
|
|
|
// // -> Reorder versions
|
|
// const versions = []
|
|
// for (const [key, value] of Object.entries(covData)) {
|
|
// if (isPlainObject(value)) {
|
|
// const vRel = find(releases, r => r.tag_name === key || r.tag_name === `v${key}`)
|
|
// if (!vRel) {
|
|
// continue
|
|
// }
|
|
// versions.push({
|
|
// tag: key,
|
|
// time: vRel.created_at,
|
|
// stats: {
|
|
// code: round(value.code * 100, 2),
|
|
// template: round(value.template * 100, 2),
|
|
// url: round(value.url * 100, 2)
|
|
// }
|
|
// })
|
|
// }
|
|
// }
|
|
// const roVersions = orderBy(versions, ['time', 'tag'], ['asc', 'asc'])
|
|
|
|
// // -> Fill axis + data points
|
|
// const labels = []
|
|
// const datasetCode = []
|
|
// const datasetTemplate = []
|
|
// const datasetUrl = []
|
|
|
|
// for (const ver of roVersions) {
|
|
// labels.push(ver.tag)
|
|
// datasetCode.push(ver.stats.code)
|
|
// datasetTemplate.push(ver.stats.template)
|
|
// datasetUrl.push(ver.stats.url)
|
|
// }
|
|
|
|
// // -> Generate chart SVG
|
|
// const outputStream = chartJSNodeCanvas.renderToBufferSync({
|
|
// type: 'line',
|
|
// options: {
|
|
// borderColor: '#CCC',
|
|
// layout: {
|
|
// padding: 20
|
|
// },
|
|
// plugins: {
|
|
// legend: {
|
|
// position: 'bottom',
|
|
// labels: {
|
|
// font: {
|
|
// size: 11
|
|
// }
|
|
// }
|
|
// }
|
|
// },
|
|
// scales: {
|
|
// x: {
|
|
// ticks: {
|
|
// font: {
|
|
// size: 10
|
|
// }
|
|
// }
|
|
// },
|
|
// y: {
|
|
// ticks: {
|
|
// callback: (value) => {
|
|
// return `${value}%`
|
|
// },
|
|
// font: {
|
|
// size: 10
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// },
|
|
// data: {
|
|
// labels,
|
|
// datasets: [
|
|
// {
|
|
// label: 'Code',
|
|
// data: datasetCode,
|
|
// borderWidth: 2,
|
|
// borderColor: '#E53935',
|
|
// backgroundColor: '#C6282833',
|
|
// fill: false,
|
|
// cubicInterpolationMode: 'monotone',
|
|
// tension: 0.4,
|
|
// pointRadius: 0
|
|
// },
|
|
// {
|
|
// label: 'Templates',
|
|
// data: datasetTemplate,
|
|
// borderWidth: 2,
|
|
// borderColor: '#039BE5',
|
|
// backgroundColor: '#0277BD33',
|
|
// fill: false,
|
|
// cubicInterpolationMode: 'monotone',
|
|
// tension: 0.4,
|
|
// pointRadius: 0
|
|
// },
|
|
// {
|
|
// label: 'URLs',
|
|
// data: datasetUrl,
|
|
// borderWidth: 2,
|
|
// borderColor: '#7CB342',
|
|
// backgroundColor: '#558B2F33',
|
|
// fill: false,
|
|
// cubicInterpolationMode: 'monotone',
|
|
// tension: 0.4,
|
|
// pointRadius: 0
|
|
// }
|
|
// ]
|
|
// }
|
|
// }, 'image/svg+xml')
|
|
// const svg = Buffer.from(outputStream).toString('base64')
|
|
|
|
// // -> Upload to common repo
|
|
// console.info(`Uploading chart SVG for ${newRelease.name}...`)
|
|
// await ghCommon.rest.repos.createOrUpdateFileContents({
|
|
// owner,
|
|
// repo: repoCommon,
|
|
// path: `assets/graphs/datatracker/${newRelease.id}.svg`,
|
|
// message: `chore: update datatracker release chart for release ${newRelease.name}`,
|
|
// content: svg
|
|
// })
|
|
// }
|
|
|
|
// -> Add to changelog body
|
|
let formattedBody = ''
|
|
const covInfo = {
|
|
code: round(covLatestStats.code * 100, 2),
|
|
template: round(covLatestStats.template * 100, 2),
|
|
url: round(covLatestStats.url * 100, 2)
|
|
}
|
|
|
|
formattedBody = summary ? `**Summary:** ${summary}\n` : ''
|
|
formattedBody += `**Release Date**: ${DateTime.now().setZone('utc').toFormat('ccc, LLLL d, y \'at\' h:mm a ZZZZ')}\n`
|
|
formattedBody += `**Release Author**: @${sender}\n`
|
|
formattedBody += '\n---\n\n'
|
|
formattedBody += changelog
|
|
formattedBody += '\n\n---\n\n**Coverage**\n\n'
|
|
formattedBody += `}?style=flat-square)`
|
|
formattedBody += `}?style=flat-square)`
|
|
formattedBody += `}?style=flat-square)\n\n`
|
|
// formattedBody += ``
|
|
|
|
core.setOutput('changelog', formattedBody)
|
|
}
|
|
|
|
main()
|
|
|
|
function getCoverageColor (val) {
|
|
if (val >= 95) {
|
|
return 'brightgreen'
|
|
} else if (val >= 90) {
|
|
return 'green'
|
|
} else if (val >= 80) {
|
|
return 'yellowgreen'
|
|
} else if (val >= 60) {
|
|
return 'yellow'
|
|
} else if (val >= 50) {
|
|
return 'orange'
|
|
} else {
|
|
return 'red'
|
|
}
|
|
}
|