@grnsft/if-eco-ci-plugin
Version:
EcoCI plugin for Impact Framework.
125 lines • 17.2 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EcoCI = void 0;
const zod_1 = require("zod");
const moment_timezone_1 = __importDefault(require("moment-timezone"));
const interfaces_1 = require("@grnsft/if-core/interfaces");
const utils_1 = require("@grnsft/if-core/utils");
const api_1 = require("./api");
const { ConfigError } = utils_1.ERRORS;
exports.EcoCI = (0, interfaces_1.PluginFactory)({
metadata: {
inputs: {},
outputs: {
carbon: {
description: 'the used carbon in running the workflow',
unit: 'gCO2eq',
'aggregation-method': { time: 'sum', component: 'sum' },
},
energy: {
description: 'the used energy in running the workflow',
unit: 'kWh',
'aggregation-method': { time: 'sum', component: 'sum' },
},
},
},
implementation: async (inputs, config) => {
const result = await getRepoMetrics(config, inputs);
return inputs.map(input => {
const { energy, carbon } = calculateMetrics(result, { input, config });
return {
...input,
energy,
carbon,
};
});
},
configValidation: (config) => {
if (!config || !Object.keys(config)?.length) {
throw new ConfigError('Config is not provided.');
}
const schema = zod_1.z.object({
repo: zod_1.z.string().regex(/^[a-zA-Z0-9_-]+\/[a-zA-Z0-9_-]+$/),
branch: zod_1.z.string(),
workflow: zod_1.z.number(),
'start-date': zod_1.z.string().or(zod_1.z.date()).optional(),
'end-date': zod_1.z.string().or(zod_1.z.date()).optional(),
});
return (0, utils_1.validate)(schema, config);
},
inputValidation: (input, _config, index) => {
const schema = zod_1.z.object({
timestamp: zod_1.z.string().or(zod_1.z.date()),
duration: zod_1.z.number().or(zod_1.z.string()),
});
return (0, utils_1.validate)(schema, input, index);
},
});
/**
* Gets metrics for the specified repository.
*/
const getRepoMetrics = async (config, inputs) => {
const { repo, branch, workflow, 'start-date': start, 'end-date': end } = config;
const firstTimestamp = start || inputs[0].timestamp;
const endTimestamp = start && !end ? start : end || inputs[inputs.length - 1].timestamp;
const evaledDuration = eval(inputs[inputs.length - 1]?.duration);
const { startDate, endDate } = getOnlyDates(firstTimestamp, endTimestamp, evaledDuration);
const params = {
repo,
branch,
workflow,
start_date: startDate || firstTimestamp,
end_date: endDate,
};
return await (0, api_1.EcoCiAPI)().getRepoMetrics(params);
};
/**
* Calculates the energy and carbon metrics.
* Converts energy from `mJ` to `kWh`.
*/
const calculateMetrics = (metrics, { input, config }) => {
const kWhForJ = 2.78e-8;
const { 'start-date': startDate, 'end-date': endDate } = config;
const data = metrics.reduce((acc, item) => {
const dateInMilliseconds = moment_timezone_1.default
.tz(item[2].toString(), 'UTC')
.toDate()
.getTime();
const startRange = moment_timezone_1.default.utc(startDate || input.timestamp).valueOf();
const endRange = endDate
? moment_timezone_1.default.utc(endDate).valueOf()
: startRange + eval(input.duration) * 1000;
if (dateInMilliseconds >= startRange && dateInMilliseconds < endRange) {
acc.energy += item[0];
acc.carbon += parseFloat(item[item.length - 1]?.toString());
return acc;
}
return { energy: acc.energy, carbon: acc.carbon };
}, { energy: 0, carbon: 0 });
// Convert MJ to Joules (1 MJ = 1,000,000 J) and then
// convert Joules to kWh (1 kWh = 3,600,000 J)
data.energy = (data.energy / 1000000) * kWhForJ;
// Convert micro-grams to grams to get gCO2eq unit
data.carbon = data.carbon * 1e-6;
return data;
};
/**
* Drops time part and returns only dates.
*/
const getOnlyDates = (startDate, endDate, duration) => {
const startTimestampSeconds = new Date(startDate).getTime() / 1000;
const endTimestampSeconds = new Date(endDate).getTime() / 1000;
const range = endTimestampSeconds - startTimestampSeconds;
if (range === 0) {
const endDateInMilliseconds = (duration + endTimestampSeconds) * 1000;
endDate = new Date(endDateInMilliseconds - new Date().getTimezoneOffset() * 60000).toISOString();
}
return {
startDate,
endDate,
};
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLDZCQUFzQjtBQUN0QixzRUFBcUM7QUFHckMsMkRBQXlEO0FBQ3pELGlEQUF1RDtBQUV2RCwrQkFBK0I7QUFHL0IsTUFBTSxFQUFDLFdBQVcsRUFBQyxHQUFHLGNBQU0sQ0FBQztBQUVoQixRQUFBLEtBQUssR0FBRyxJQUFBLDBCQUFhLEVBQUM7SUFDakMsUUFBUSxFQUFFO1FBQ1IsTUFBTSxFQUFFLEVBQUU7UUFDVixPQUFPLEVBQUU7WUFDUCxNQUFNLEVBQUU7Z0JBQ04sV0FBVyxFQUFFLHlDQUF5QztnQkFDdEQsSUFBSSxFQUFFLFFBQVE7Z0JBQ2Qsb0JBQW9CLEVBQUUsRUFBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUM7YUFDdEQ7WUFDRCxNQUFNLEVBQUU7Z0JBQ04sV0FBVyxFQUFFLHlDQUF5QztnQkFDdEQsSUFBSSxFQUFFLEtBQUs7Z0JBQ1gsb0JBQW9CLEVBQUUsRUFBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUM7YUFDdEQ7U0FDRjtLQUNGO0lBQ0QsY0FBYyxFQUFFLEtBQUssRUFBRSxNQUFzQixFQUFFLE1BQW9CLEVBQUUsRUFBRTtRQUNyRSxNQUFNLE1BQU0sR0FBRyxNQUFNLGNBQWMsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFcEQsT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ3hCLE1BQU0sRUFBQyxNQUFNLEVBQUUsTUFBTSxFQUFDLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLE1BQU0sRUFBQyxDQUFDLENBQUM7WUFFbkUsT0FBTztnQkFDTCxHQUFHLEtBQUs7Z0JBQ1IsTUFBTTtnQkFDTixNQUFNO2FBQ1AsQ0FBQztRQUNKLENBQUMs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RCxDQUFDLEVBQ0QsRUFBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUMsQ0FDdkIsQ0FBQztJQUVGLHFEQUFxRDtJQUNyRCw4Q0FBOEM7SUFDOUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLEdBQUcsT0FBTyxDQUFDO0lBRWhELGtEQUFrRDtJQUNsRCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO0lBRWpDLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQyxDQUFDO0FBRUY7O0dBRUc7QUFDSCxNQUFNLFlBQVksR0FBRyxDQUFDLFNBQWlCLEVBQUUsT0FBZSxFQUFFLFFBQWdCLEVBQUUsRUFBRTtJQUM1RSxNQUFNLHFCQUFxQixHQUFHLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxHQUFHLElBQUksQ0FBQztJQUNuRSxNQUFNLG1CQUFtQixHQUFHLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxHQUFHLElBQUksQ0FBQztJQUMvRCxNQUFNLEtBQUssR0FBRyxtQkFBbUIsR0FBRyxxQkFBcUIsQ0FBQztJQUUxRCxJQUFJLEtBQUssS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUNoQixNQUFNLHFCQUFxQixHQUFHLENBQUMsUUFBUSxHQUFHLG1CQUFtQixDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQ3RFLE9BQU8sR0FBRyxJQUFJLElBQUksQ0FDaEIscUJBQXFCLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxHQUFHLEtBQUssQ0FDL0QsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNsQixDQUFDO0lBRUQsT0FBTztRQUNMLFNBQVM7UUFDVCxPQUFPO0tBQ1IsQ0FBQztBQUNKLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7en0gZnJvbSAnem9kJztcbmltcG9ydCBtb21lbnQgZnJvbSAnbW9tZW50LXRpbWV6b25lJztcblxuaW1wb3J0IHtQbHVnaW5QYXJhbXMsIENvbmZpZ1BhcmFtc30gZnJvbSAnQGdybnNmdC9pZi1jb3JlL3R5cGVzJztcbmltcG9ydCB7UGx1Z2luRmFjdG9yeX0gZnJvbSAnQGdybnNmdC9pZi1jb3JlL2ludGVyZmFjZXMnO1xuaW1wb3J0IHtFUlJPUlMsIHZhbGlkYXRlfSBmcm9tICdAZ3Juc2Z0L2lmLWNvcmUvdXRpbHMnO1xuXG5pbXBvcnQge0Vjb0NpQVBJfSBmcm9tICcuL2FwaSc7XG5pbXBvcnQge0Vjb0NpUGFyYW1zfSBmcm9tICcuL3R5cGVzJztcblxuY29uc3Qge0NvbmZpZ0Vycm9yfSA9IEVSUk9SUztcblxuZXhwb3J0IGNvbnN0IEVjb0NJID0gUGx1Z2luRmFjdG9yeSh7XG4gIG1ldGFkYXRhOiB7XG4gICAgaW5wdXRzOiB7fSxcbiAgICBvdXRwdXRzOiB7XG4gICAgICBjYXJib246IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICd0aGUgdXNlZCBjYXJib24gaW4gcnVubmluZyB0aGUgd29ya2Zsb3cnLFxuICAgICAgICB1bml0OiAnZ0NPMmVxJyxcbiAgICAgICAgJ2FnZ3JlZ2F0aW9uLW1ldGhvZCc6IHt0aW1lOiAnc3VtJywgY29tcG9uZW50OiAnc3VtJ30sXG4gICAgICB9LFxuICAgICAgZW5lcmd5OiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAndGhlIHVzZWQgZW5lcmd5IGluIHJ1bm5pbmcgdGhlIHdvcmtmbG93JyxcbiAgICAgICAgdW5pdDogJ2tXaCcsXG4gICAgICAgICdhZ2dyZWdhdGlvbi1tZXRob2QnOiB7dGltZTogJ3N1bScsIGNvbXBvbmVudDogJ3N1bSd9LFxuICAgICAgfSxcbiAgICB9LFxuICB9LFxuICBpbXBsZW1lbnRhdGlvbjogYXN5bmMgKGlucHV0czogUGx1Z2luUGFyYW1zW10sIGNvbmZpZzogQ29uZmlnUGFyYW1zKSA9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZ2V0UmVwb01ldHJpY3MoY29uZmlnLCBpbnB1dHMpO1xuXG4gICAgcmV0dXJuIGlucHV0cy5tYXAoaW5wdXQgPT4ge1xuICAgICAgY29uc3Qge2VuZXJneSwgY2FyYm9ufSA9IGNhbGN1bGF0ZU1ldHJpY3MocmVzdWx0LCB7aW5wdXQsIGNvbmZpZ30pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5pbnB1dCxcbiAgICAgICAgZW5lcmd5LFxuICAgICAgICBjYXJib24sXG4gICAgICB9O1xuICAgIH0pO1xuICB9LFxuICBjb25maWdWYWxpZGF0aW9uOiAoY29uZmlnOiBDb25maWdQYXJhbXMpID0+IHtcbiAgICBpZiAoIWNvbmZpZyB8fCAhT2JqZWN0LmtleXMoY29uZmlnKT8ubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgQ29uZmlnRXJyb3IoJ0NvbmZpZyBpcyBub3QgcHJvdmlkZWQuJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2NoZW1hID0gei5vYmplY3Qoe1xuICAgICAgcmVwbzogei5zdHJpbmcoKS5yZWdleCgvXlthLXpBLVowLTlfLV0rXFwvW2EtekEtWjAtOV8tXSskLyksXG4gICAgICBicmFuY2g6IHouc3RyaW5nKCksXG4gICAgICB3b3JrZmxvdzogei5udW1iZXIoKSxcbiAgICAgICdzdGFydC1kYXRlJzogei5zdHJpbmcoKS5vcih6LmRhdGUoKSkub3B0aW9uYWwoKSxcbiAgICAgICdlbmQtZGF0ZSc6IHouc3RyaW5nKCkub3Ioei5kYXRlKCkpLm9wdGlvbmFsKCksXG4gICAgfSk7XG5cbiAgICByZXR1cm4gdmFsaWRhdGU8ei5pbmZlcjx0eXBlb2Ygc2NoZW1hPj4oc2NoZW1hLCBjb25maWcpO1xuICB9LFxuICBpbnB1dFZhbGlkYXRpb246IChcbiAgICBpbnB1dDogUGx1Z2luUGFyYW1zLFxuICAgIF9jb25maWc6IENvbmZpZ1BhcmFtcyxcbiAgICBpbmRleDogbnVtYmVyIHwgdW5kZWZpbmVkXG4gICkgPT4ge1xuICAgIGNvbnN0IHNjaGVtYSA9IHoub2JqZWN0KHtcbiAgICAgIHRpbWVzdGFtcDogei5zdHJpbmcoKS5vcih6LmRhdGUoKSksXG4gICAgICBkdXJhdGlvbjogei5udW1iZXIoKS5vcih6LnN0cmluZygpKSxcbiAgICB9KTtcblxuICAgIHJldHVybiB2YWxpZGF0ZTx6LmluZmVyPHR5cGVvZiBzY2hlbWE+PihzY2hlbWEsIGlucHV0LCBpbmRleCk7XG4gIH0sXG59KTtcblxuLyoqXG4gKiBHZXRzIG1ldHJpY3MgZm9yIHRoZSBzcGVjaWZpZWQgcmVwb3NpdG9yeS5cbiAqL1xuY29uc3QgZ2V0UmVwb01ldHJpY3MgPSBhc3luYyAoY29uZmlnOiBDb25maWdQYXJhbXMsIGlucHV0czogUGx1Z2luUGFyYW1zW10pID0+IHtcbiAgY29uc3Qge3JlcG8sIGJyYW5jaCwgd29ya2Zsb3csICdzdGFydC1kYXRlJzogc3RhcnQsICdlbmQtZGF0ZSc6IGVuZH0gPSBjb25maWc7XG5cbiAgY29uc3QgZmlyc3RUaW1lc3RhbXAgPSBzdGFydCB8fCBpbnB1dHNbMF0udGltZXN0YW1wO1xuICBjb25zdCBlbmRUaW1lc3RhbXAgPVxuICAgIHN0YXJ0ICYmICFlbmQgPyBzdGFydCA6IGVuZCB8fCBpbnB1dHNbaW5wdXRzLmxlbmd0aCAtIDFdLnRpbWVzdGFtcDtcbiAgY29uc3QgZXZhbGVkRHVyYXRpb24gPSBldmFsKGlucHV0c1tpbnB1dHMubGVuZ3RoIC0gMV0/LmR1cmF0aW9uKTtcblxuICBjb25zdCB7c3RhcnREYXRlLCBlbmREYXRlfSA9IGdldE9ubHlEYXRlcyhcbiAgICBmaXJzdFRpbWVzdGFtcCxcbiAgICBlbmRUaW1lc3RhbXAsXG4gICAgZXZhbGVkRHVyYXRpb25cbiAgKTtcbiAgY29uc3QgcGFyYW1zOiBFY29DaVBhcmFtcyA9IHtcbiAgICByZXBvLFxuICAgIGJyYW5jaCxcbiAgICB3b3JrZmxvdyxcbiAgICBzdGFydF9kYXRlOiBzdGFydERhdGUgfHwgZmlyc3RUaW1lc3RhbXAsXG4gICAgZW5kX2RhdGU6IGVuZERhdGUsXG4gIH07XG5cbiAgcmV0dXJuIGF3YWl0IEVjb0NpQVBJKCkuZ2V0UmVwb01ldHJpY3MocGFyYW1zKTtcbn07XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgZW5lcmd5IGFuZCBjYXJib24gbWV0cmljcy5cbiAqIENvbnZlcnRzIGVuZXJneSBmcm9tIGBtSmAgdG8gYGtXaGAuXG4gKi9cblxuY29uc3QgY2FsY3VsYXRlTWV0cmljcyA9IChcbiAgbWV0cmljczogW10sXG4gIHtpbnB1dCwgY29uZmlnfToge2lucHV0OiBQbHVnaW5QYXJhbXM7IGNvbmZpZzogQ29uZmlnUGFyYW1zfVxuKSA9PiB7XG4gIGNvbnN0IGtXaEZvckogPSAyLjc4ZS04O1xuICBjb25zdCB7J3N0YXJ0LWRhdGUnOiBzdGFydERhdGUsICdlbmQtZGF0ZSc6IGVuZERhdGV9ID0gY29uZmlnO1xuXG4gIGNvbnN0IGRhdGEgPSBtZXRyaWNzLnJlZHVjZShcbiAgICAoYWNjOiB7ZW5lcmd5OiBudW1iZXI7IGNhcmJvbjogbnVtYmVyfSwgaXRlbTogbnVtYmVyW10pID0+IHtcbiAgICAgIGNvbnN0IGRhdGVJbk1pbGxpc2Vjb25kcyA9IG1vbWVudFxuICAgICAgICAudHooaXRlbVsyXS50b1N0cmluZygpLCAnVVRDJylcbiAgICAgICAgLnRvRGF0ZSgpXG4gICAgICAgIC5nZXRUaW1lKCk7XG4gICAgICBjb25zdCBzdGFydFJhbmdlID0gbW9tZW50LnV0YyhzdGFydERhdGUgfHwgaW5wdXQudGltZXN0YW1wKS52YWx1ZU9mKCk7XG4gICAgICBjb25zdCBlbmRSYW5nZSA9IGVuZERhdGVcbiAgICAgICAgPyBtb21lbnQudXRjKGVuZERhdGUpLnZhbHVlT2YoKVxuICAgICAgICA6IHN0YXJ0UmFuZ2UgKyBldmFsKGlucHV0LmR1cmF0aW9uKSAqIDEwMDA7XG5cbiAgICAgIGlmIChkYXRlSW5NaWxsaXNlY29uZHMgPj0gc3RhcnRSYW5nZSAmJiBkYXRlSW5NaWxsaXNlY29uZHMgPCBlbmRSYW5nZSkge1xuICAgICAgICBhY2MuZW5lcmd5ICs9IGl0ZW1bMF07XG4gICAgICAgIGFjYy5jYXJib24gKz0gcGFyc2VGbG9hdChpdGVtW2l0ZW0ubGVuZ3RoIC0gMV0/LnRvU3RyaW5nKCkpO1xuXG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7ZW5lcmd5OiBhY2MuZW5lcmd5LCBjYXJib246IGFjYy5jYXJib259O1xuICAgIH0sXG4gICAge2VuZXJneTogMCwgY2FyYm9uOiAwfVxuICApO1xuXG4gIC8vIENvbnZlcnQgTUogdG8gSm91bGVzICgxIE1KID0gMSwwMDAsMDAwIEopIGFuZCB0aGVuXG4gIC8vIGNvbnZlcnQgSm91bGVzIHRvIGtXaCAoMSBrV2ggPSAzLDYwMCwwMDAgSilcbiAgZGF0YS5lbmVyZ3kgPSAoZGF0YS5lbmVyZ3kgLyAxMDAwMDAwKSAqIGtXaEZvcko7XG5cbiAgLy8gQ29udmVydCBtaWNyby1ncmFtcyB0byBncmFtcyB0byBnZXQgZ0NPMmVxIHVuaXRcbiAgZGF0YS5jYXJib24gPSBkYXRhLmNhcmJvbiAqIDFlLTY7XG5cbiAgcmV0dXJuIGRhdGE7XG59O1xuXG4vKipcbiAqIERyb3BzIHRpbWUgcGFydCBhbmQgcmV0dXJucyBvbmx5IGRhdGVzLlxuICovXG5jb25zdCBnZXRPbmx5RGF0ZXMgPSAoc3RhcnREYXRlOiBzdHJpbmcsIGVuZERhdGU6IHN0cmluZywgZHVyYXRpb246IG51bWJlcikgPT4ge1xuICBjb25zdCBzdGFydFRpbWVzdGFtcFNlY29uZHMgPSBuZXcgRGF0ZShzdGFydERhdGUpLmdldFRpbWUoKSAvIDEwMDA7XG4gIGNvbnN0IGVuZFRpbWVzdGFtcFNlY29uZHMgPSBuZXcgRGF0ZShlbmREYXRlKS5nZXRUaW1lKCkgLyAxMDAwO1xuICBjb25zdCByYW5nZSA9IGVuZFRpbWVzdGFtcFNlY29uZHMgLSBzdGFydFRpbWVzdGFtcFNlY29uZHM7XG5cbiAgaWYgKHJhbmdlID09PSAwKSB7XG4gICAgY29uc3QgZW5kRGF0ZUluTWlsbGlzZWNvbmRzID0gKGR1cmF0aW9uICsgZW5kVGltZXN0YW1wU2Vjb25kcykgKiAxMDAwO1xuICAgIGVuZERhdGUgPSBuZXcgRGF0ZShcbiAgICAgIGVuZERhdGVJbk1pbGxpc2Vjb25kcyAtIG5ldyBEYXRlKCkuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwMDAwXG4gICAgKS50b0lTT1N0cmluZygpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBzdGFydERhdGUsXG4gICAgZW5kRGF0ZSxcbiAgfTtcbn07XG4iXX0=