WIP: refactor: port to JS
This should hopefully reduce the complexity of the action
This commit is contained in:
parent
a26909cb8c
commit
0be52794ad
20 changed files with 215059 additions and 109 deletions
145
src/main.js
Normal file
145
src/main.js
Normal file
|
@ -0,0 +1,145 @@
|
|||
import * as core from '@actions/core'
|
||||
import * as exec from '@actions/exec'
|
||||
import * as github from '@actions/github'
|
||||
import { DefaultArtifactClient } from '@actions/artifact'
|
||||
import * as fs from 'node:fs/promises'
|
||||
|
||||
/**
|
||||
* The main function for the action.
|
||||
*
|
||||
* @returns {Promise<void>} Resolves when the action is complete.
|
||||
*/
|
||||
export async function run() {
|
||||
try {
|
||||
const comment = core.getBooleanInput('comment-on-pr', { required: false })
|
||||
const upload = core.getBooleanInput('generate-artifact', {
|
||||
required: false
|
||||
})
|
||||
const artifactName = core.getInput('artifact-name', { required: false })
|
||||
const compare = core.getBooleanInput('do-comparison', { required: false })
|
||||
const jobName = core.getInput('job-name', { required: false })
|
||||
const baseBranch = core.getInput('base-branch', { required: false })
|
||||
const system = core.getInput('system', { required: true })
|
||||
|
||||
if (!comment && !upload) {
|
||||
core.error(
|
||||
'Both comment-on-pr and generate-artifact were set to false, nothing to do, consider disabling the action instead'
|
||||
)
|
||||
core.setFailed('Neither commenting nor uploading a report ... why?')
|
||||
return
|
||||
}
|
||||
|
||||
const flakeInfo = JSON.parse(
|
||||
await collectOutput('nix', ['flake', 'show', '--json'])
|
||||
)
|
||||
core.debug(`nix flake show --json: ${flakeInfo}`)
|
||||
|
||||
const report = await core.group('Generating size report', () =>
|
||||
generateReport(flakeInfo, system)
|
||||
)
|
||||
|
||||
if (upload) {
|
||||
const artifact = new DefaultArtifactClient()
|
||||
await fs.writeFile(artifactName, JSON.stringify(report))
|
||||
const { id, size } = artifact.uploadArtifact(artifactName, [artifactName])
|
||||
|
||||
core.info(`Uploaded report ${artifactName} (${size}B) with id ${id}`)
|
||||
}
|
||||
|
||||
// Done
|
||||
if (!comment) {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: compare reports and create comment
|
||||
} catch (error) {
|
||||
// Fail the workflow run if an error occurs
|
||||
if (error instanceof Error) core.setFailed(error.message)
|
||||
}
|
||||
}
|
||||
|
||||
async function generateReport(flakeInfo, system) {
|
||||
const packages = getPackages(flakeInfo, system)
|
||||
const hmConfigs = getKeys(flakeInfo, 'homeConfigurations')
|
||||
const nixosConfigs = getKeys(flakeInfo, 'nixosConfigurations')
|
||||
|
||||
core.info(`packages: ${packages}`)
|
||||
core.info(`homeConfigurations: ${hmConfigs}`)
|
||||
core.info(`nixosConfigurations: ${nixosConfigs}`)
|
||||
|
||||
const pkgSizes = await core.group('Calculating size of packages', () =>
|
||||
calculateSizeOf(packages, (pkg) => `.#${pkg}`)
|
||||
)
|
||||
|
||||
const hmConfigsSizes = await core.group(
|
||||
'Calculating size of Home-Manager Configurations',
|
||||
() =>
|
||||
calculateSizeOf(
|
||||
hmConfigs,
|
||||
(config) => `.#homeConfigurations.${config}.activationPackages`
|
||||
)
|
||||
)
|
||||
|
||||
const nixosConfigsSizes = await core.group(
|
||||
'Calculating size of NixOS Configurations',
|
||||
() =>
|
||||
calculateSizeOf(
|
||||
nixosConfigs,
|
||||
(config) =>
|
||||
`.#nixosConfigurations.${config}.config.system.build.toplevel`
|
||||
)
|
||||
)
|
||||
|
||||
return {
|
||||
packages: pkgSizes,
|
||||
nixosConfigurations: nixosConfigsSizes,
|
||||
homeConfigurations: hmConfigsSizes
|
||||
}
|
||||
}
|
||||
|
||||
async function calculateSizeOf(names, nameToInstallable) {
|
||||
let sizes = []
|
||||
for (const name of names) {
|
||||
sizes.push(await calculateSize(nameToInstallable(name)))
|
||||
}
|
||||
return sizes
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the packages from a `nix flake show --json` blob
|
||||
*
|
||||
* @returns {Array<String>} the packages in the current flake for the specific system
|
||||
*/
|
||||
function getPackages(flakeInfo, system) {
|
||||
return 'packages' in flakeInfo ? getKeys(flakeInfo.packages, system) : []
|
||||
}
|
||||
|
||||
function getKeys(flakeInfo, key) {
|
||||
return key in flakeInfo ? Object.keys(flakeInfo[key]) : []
|
||||
}
|
||||
|
||||
async function calculateSize(installable) {
|
||||
const path = await collectOutput('nix', [
|
||||
'build',
|
||||
'--print-out-paths',
|
||||
installable
|
||||
])
|
||||
const data = JSON.parse(
|
||||
await collectOutput('nix', ['path-info', '--closure-size', '--json', path])
|
||||
)
|
||||
data.path = path
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
async function collectOutput(cmd, args) {
|
||||
let output = ''
|
||||
await exec.exec(cmd, args, {
|
||||
listeners: {
|
||||
stdout: (data) => {
|
||||
output += data.toString()
|
||||
}
|
||||
}
|
||||
})
|
||||
return output
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue