add getting metrics data for n commits

This commit is contained in:
jpaul 2023-11-27 14:46:52 +01:00
parent 47c5a10370
commit e9bf44a5db
6 changed files with 503 additions and 59 deletions

View File

@ -43,6 +43,14 @@ inputs:
required: false
description: 'Post a comment containing a Native Image build report on pull requests.'
default: 'false'
native-image-metric-history:
required: false
description: 'Post a diagramm showing the image details history for last builds.'
default: 'false'
build-counts-for-metric-history:
required: false
description: 'Set how many builds are considered for metric history.'
default: '10'
native-image-pr-comparison:
required: false
description: 'Post a comment containing a comparison between the Native Image of the pr-branch and the pr-base-branch on pull.'

165
dist/cleanup/index.js generated vendored
View File

@ -74057,7 +74057,7 @@ else {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.OCTOKIT_BASIC_HEADER = exports.OCTOKIT_ROUTE_BLOB = exports.OCTOKIT_ROUTE_TREE = exports.OCTOKIT_ROUTE_REF_METRICS = exports.OCTOKIT_ROUTE_REF = exports.OCTOKIT_ROUTE_CREATE_TREE = exports.OCTOKIT_ROUTE_CREATE_REF = exports.OCTOKIT_REF_BRANCHE_PREFIX = exports.METRIC_PATH = exports.ERROR_HINT = exports.EVENT_NAME_PULL_REQUEST = exports.ENV_GITHUB_EVENT_NAME = exports.GDS_GRAALVM_PRODUCT_ID = exports.GDS_BASE = exports.MANDREL_NAMESPACE = exports.GRAALVM_RELEASES_REPO = exports.GRAALVM_PLATFORM = exports.GRAALVM_GH_USER = exports.GRAALVM_FILE_EXTENSION = exports.GRAALVM_ARCH = exports.JDK_HOME_SUFFIX = exports.JDK_PLATFORM = exports.JDK_ARCH = exports.VERSION_LATEST = exports.VERSION_DEV = exports.DISTRIBUTION_MANDREL = exports.DISTRIBUTION_GRAALVM_COMMUNITY = exports.DISTRIBUTION_GRAALVM = exports.IS_WINDOWS = exports.IS_MACOS = exports.IS_LINUX = exports.INPUT_NI_MUSL = exports.INPUT_CHECK_FOR_UPDATES = exports.INPUT_CACHE = exports.INPUT_SET_JAVA_HOME = exports.INPUT_GITHUB_TOKEN = exports.INPUT_COMPONENTS = exports.INPUT_DISTRIBUTION = exports.INPUT_JAVA_VERSION = exports.INPUT_GDS_TOKEN = exports.INPUT_VERSION = void 0;
exports.OCTOKIT_BASIC_HEADER = exports.OCTOKIT_ROUTE_GET_EVENTS = exports.OCTOKIT_ROUTE_GET_BLOB = exports.OCTOKIT_ROUTE_GET_TREE = exports.OCTOKIT_ROUTE_GET_REF_METRICS = exports.OCTOKIT_ROUTE_GET_REF = exports.OCTOKIT_ROUTE_CREATE_TREE = exports.OCTOKIT_ROUTE_CREATE_REF = exports.OCTOKIT_REF_BRANCHE_PREFIX = exports.METRIC_PATH = exports.ERROR_HINT = exports.EVENT_NAME_PULL_REQUEST = exports.ENV_GITHUB_EVENT_NAME = exports.GDS_GRAALVM_PRODUCT_ID = exports.GDS_BASE = exports.MANDREL_NAMESPACE = exports.GRAALVM_RELEASES_REPO = exports.GRAALVM_PLATFORM = exports.GRAALVM_GH_USER = exports.GRAALVM_FILE_EXTENSION = exports.GRAALVM_ARCH = exports.JDK_HOME_SUFFIX = exports.JDK_PLATFORM = exports.JDK_ARCH = exports.VERSION_LATEST = exports.VERSION_DEV = exports.DISTRIBUTION_MANDREL = exports.DISTRIBUTION_GRAALVM_COMMUNITY = exports.DISTRIBUTION_GRAALVM = exports.IS_WINDOWS = exports.IS_MACOS = exports.IS_LINUX = exports.INPUT_NI_MUSL = exports.INPUT_CHECK_FOR_UPDATES = exports.INPUT_CACHE = exports.INPUT_SET_JAVA_HOME = exports.INPUT_GITHUB_TOKEN = exports.INPUT_COMPONENTS = exports.INPUT_DISTRIBUTION = exports.INPUT_JAVA_VERSION = exports.INPUT_GDS_TOKEN = exports.INPUT_VERSION = void 0;
exports.INPUT_VERSION = 'version';
exports.INPUT_GDS_TOKEN = 'gds-token';
exports.INPUT_JAVA_VERSION = 'java-version';
@ -74094,10 +74094,11 @@ exports.METRIC_PATH = 'graalvm-metrics';
exports.OCTOKIT_REF_BRANCHE_PREFIX = 'heads';
exports.OCTOKIT_ROUTE_CREATE_REF = 'POST /repos/{owner}/{repo}/git/refs';
exports.OCTOKIT_ROUTE_CREATE_TREE = 'POST /repos/{owner}/{repo}/git/trees';
exports.OCTOKIT_ROUTE_REF = 'GET /repos/{owner}/{repo}/git/ref/';
exports.OCTOKIT_ROUTE_REF_METRICS = `GET /repos/{owner}/{repo}/git/ref/${exports.METRIC_PATH}/`;
exports.OCTOKIT_ROUTE_TREE = 'GET /repos/{owner}/{repo}/git/trees/';
exports.OCTOKIT_ROUTE_BLOB = 'GET /repos/{owner}/{repo}/git/blobs/';
exports.OCTOKIT_ROUTE_GET_REF = 'GET /repos/{owner}/{repo}/git/ref/';
exports.OCTOKIT_ROUTE_GET_REF_METRICS = `GET /repos/{owner}/{repo}/git/ref/${exports.METRIC_PATH}/`;
exports.OCTOKIT_ROUTE_GET_TREE = 'GET /repos/{owner}/{repo}/git/trees/';
exports.OCTOKIT_ROUTE_GET_BLOB = 'GET /repos/{owner}/{repo}/git/blobs/';
exports.OCTOKIT_ROUTE_GET_EVENTS = 'GET /networks/{owner}/{repo}/events';
exports.OCTOKIT_BASIC_HEADER = { 'X-GitHub-Api-Version': '2022-11-28' };
function determineJDKArchitecture() {
switch (process.arch) {
@ -74427,6 +74428,8 @@ const BYTES_TO_GiB = 1024 * 1024 * 1024;
const DOCS_BASE = 'https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/BuildOutput.md';
const INPUT_NI_JOB_REPORTS = 'native-image-job-reports';
const INPUT_NI_PR_REPORTS = 'native-image-pr-reports';
const INPUT_NI_JOB_METRIC_HISTORY = 'native-image-metric-history';
const INPUT_NI_HISTORY_BUILD_COUNT = 'build-counts-for-metric-history';
const INPUT_NI_PR_COMPARISON = 'native-image-pr-comparison';
const NATIVE_IMAGE_CONFIG_FILE = (0, path_1.join)((0, os_1.tmpdir)(), 'native-image-options.properties');
const NATIVE_IMAGE_CONFIG_FILE_ENV = 'NATIVE_IMAGE_CONFIG_FILE';
@ -74469,10 +74472,25 @@ function generateReports() {
}
const treeSha = yield (0, utils_1.createTree)(JSON.stringify(buildOutput));
yield (0, utils_1.createRef)(treeSha);
if (areMetricHistoriesEnabled()) {
const pushEvents = yield (0, utils_1.getPushEvents)(getBuildCountsForMetricHistory());
// Prepare data
const timestamps = [];
const shas = [];
for (const pushEvent in pushEvents) {
timestamps.push(JSON.parse(pushEvent).created_at);
shas.push(JSON.parse(pushEvent).payload.commits[0].sha);
}
// Extract data for plotting
const commitDates = (0, utils_1.formatTimestamps)(timestamps);
const imageData = (0, utils_1.getImageData)(shas);
core.info(String(commitDates));
core.info(String(shas));
core.info(String(imageData));
}
if (arePRBaseComparisonEnabled()) {
const prMetrics = JSON.parse(yield (0, utils_1.getPrBaseBranchMetrics)());
yield (0, utils_1.createPRComment)(createPRComparison(buildOutput, prMetrics));
core.info(createPRComparison(buildOutput, prMetrics));
}
}
});
@ -74484,9 +74502,15 @@ function areJobReportsEnabled() {
function arePRReportsEnabled() {
return (0, utils_1.isPREvent)() && core.getInput(INPUT_NI_PR_REPORTS) === 'true';
}
function areMetricHistoriesEnabled() {
return core.getInput(INPUT_NI_JOB_METRIC_HISTORY) === 'true';
}
function arePRBaseComparisonEnabled() {
return (0, utils_1.isPREvent)() && core.getInput(INPUT_NI_PR_COMPARISON) === 'true';
}
function getBuildCountsForMetricHistory() {
return Number(core.getInput(INPUT_NI_HISTORY_BUILD_COUNT));
}
function getNativeImageOptionsFile() {
let optionsFile = process.env[NATIVE_IMAGE_CONFIG_FILE_ENV];
if (optionsFile === undefined) {
@ -74528,7 +74552,7 @@ gantt
title Native Image Size Details
todayMarker off
dateFormat X
axisFormat %s
axisFormat %
section Code area
${recentBranch} (${bytesToHuman(detailsRecent.code_area.bytes)}): active, 0, ${detailsRecent.code_area.bytes}
@ -74819,7 +74843,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getPrBaseBranchMetrics = exports.createTree = exports.createRef = exports.createPRComment = exports.isPREvent = exports.toSemVer = exports.calculateSHA256 = exports.downloadExtractAndCacheJDK = exports.downloadAndExtractJDK = exports.getMatchingTags = exports.getTaggedRelease = exports.getLatestRelease = exports.exec = void 0;
exports.getImageData = exports.formatTimestamps = exports.getPushEvents = exports.getPrBaseBranchMetrics = exports.createTree = exports.createRef = exports.createPRComment = exports.isPREvent = exports.toSemVer = exports.calculateSHA256 = exports.downloadExtractAndCacheJDK = exports.downloadAndExtractJDK = exports.getMatchingTags = exports.getTaggedRelease = exports.getLatestRelease = exports.exec = void 0;
const c = __importStar(__nccwpck_require__(2764));
const core = __importStar(__nccwpck_require__(2258));
const github = __importStar(__nccwpck_require__(7168));
@ -74834,6 +74858,7 @@ const rest_1 = __nccwpck_require__(6175);
const node_fetch_1 = __importDefault(__nccwpck_require__(831));
// Set up Octokit for github.com only and in the same way as @actions/github (see https://git.io/Jy9YP)
const baseUrl = 'https://api.github.com';
const { DateTime } = __nccwpck_require__(1278);
const GitHubDotCom = rest_1.Octokit.defaults({
baseUrl,
request: {
@ -75058,28 +75083,136 @@ exports.getPrBaseBranchMetrics = getPrBaseBranchMetrics;
function getBaseBranchCommitSha(octokit, context) {
return __awaiter(this, void 0, void 0, function* () {
const prBaseBranchName = getPrBaseBranchSha();
const { data } = yield octokit.request(c.OCTOKIT_ROUTE_REF + c.OCTOKIT_REF_BRANCHE_PREFIX + '/' + prBaseBranchName, Object.assign(Object.assign({}, context.repo), { ref: c.OCTOKIT_REF_BRANCHE_PREFIX + '/' + prBaseBranchName, headers: c.OCTOKIT_BASIC_HEADER }));
const { data } = yield octokit.request(c.OCTOKIT_ROUTE_GET_REF + c.OCTOKIT_REF_BRANCHE_PREFIX + '/' + prBaseBranchName, Object.assign(Object.assign({}, context.repo), { ref: c.OCTOKIT_REF_BRANCHE_PREFIX + '/' + prBaseBranchName, headers: c.OCTOKIT_BASIC_HEADER }));
return data.object.sha;
});
}
function getBlobTreeSha(octokit, context, baseCommitSha) {
return __awaiter(this, void 0, void 0, function* () {
const { data } = yield octokit.request(c.OCTOKIT_ROUTE_REF_METRICS + baseCommitSha, Object.assign(Object.assign({}, context.repo), { headers: c.OCTOKIT_BASIC_HEADER }));
const { data } = yield octokit.request(c.OCTOKIT_ROUTE_GET_REF_METRICS + baseCommitSha, Object.assign(Object.assign({}, context.repo), { headers: c.OCTOKIT_BASIC_HEADER }));
return data.object.sha;
});
}
function getBlobSha(octokit, context, blobTreeSha) {
return __awaiter(this, void 0, void 0, function* () {
const { data } = yield octokit.request(c.OCTOKIT_ROUTE_TREE + blobTreeSha, Object.assign(Object.assign({}, context.repo), { tree_sha: blobTreeSha, headers: c.OCTOKIT_BASIC_HEADER }));
const { data } = yield octokit.request(c.OCTOKIT_ROUTE_GET_TREE + blobTreeSha, Object.assign(Object.assign({}, context.repo), { tree_sha: blobTreeSha, headers: c.OCTOKIT_BASIC_HEADER }));
return data.tree[0].sha;
});
}
function getBlobContent(octokit, context, blobSha) {
return __awaiter(this, void 0, void 0, function* () {
const { data } = yield octokit.request(c.OCTOKIT_ROUTE_BLOB + blobSha, Object.assign(Object.assign({}, context.repo), { file_sha: blobSha, headers: c.OCTOKIT_BASIC_HEADER }));
const { data } = yield octokit.request(c.OCTOKIT_ROUTE_GET_BLOB + blobSha, Object.assign(Object.assign({}, context.repo), { file_sha: blobSha, headers: c.OCTOKIT_BASIC_HEADER }));
return js_base64_1.Base64.decode(data.content);
});
}
function getPushEvents(numberOfBuilds) {
return __awaiter(this, void 0, void 0, function* () {
try {
const octokit = new rest_1.Octokit({
auth: getGitHubToken(),
request: {
fetch: node_fetch_1.default,
},
});
const context = github.context;
const eventResponse = yield octokit.request(c.OCTOKIT_ROUTE_GET_EVENTS, Object.assign(Object.assign({}, context.repo), { headers: c.OCTOKIT_BASIC_HEADER }));
let linkHeader = eventResponse.headers.link;
const eventData = eventResponse.data;
const pushEvents = [];
/* for (const gitEvent in eventData ) {
if (numberOfBuilds <= 0) {
break
}
if (gitEvent["type"] === 'pushEvent' && gitEvent["payload"].ref === process.env.GITHUB_REF) {
pushEvents.push(gitEvent)
numberOfBuilds = numberOfBuilds - 1
}
const linkHeader = eventResponse.headers.link
const regex = /<([^>]+)>;\s*rel/;
const nextPageMatch = linkHeader?.search(/<([^>]+)>;\s*rel="next"/)
}*/
for (let event of eventData) {
if (numberOfBuilds <= 0) {
break;
}
if (event.type === "PushEvent" &&
event.payload.ref === process.env.GITHUB_REF) {
pushEvents.push(event);
numberOfBuilds--;
}
}
let nextPageMatch = /<([^>]+)>;\s*rel="next"/;
while (linkHeader &&
linkHeader.includes('rel="next"') &&
numberOfBuilds > 0) {
let nextPageUrl = nextPageMatch === null || nextPageMatch === void 0 ? void 0 : nextPageMatch.exec(linkHeader)[1];
// Make the request for the next page
// Assuming you use fetch API or similar for making HTTP requests
(0, node_fetch_1.default)(nextPageUrl, {
headers: {
Authorization: "Bearer " + getGitHubToken(),
},
})
.then((response) => response.json())
.then((nextPageResponse) => {
for (let event of nextPageResponse) {
if (numberOfBuilds <= 0) {
break;
}
if (event.type === "PushEvent" &&
event.payload.ref === process.env.GITHUB_REF) {
pushEvents.push(event);
numberOfBuilds--;
}
}
// Update the link_header for the next iteration
linkHeader = eventResponse.headers.link;
})
.catch((error) => {
console.error("Error fetching next page:", error);
});
}
return pushEvents;
}
catch (err) {
return [];
console.info("An error occurred during getting metrics data.");
}
});
}
exports.getPushEvents = getPushEvents;
function formatTimestamps(timestamps) {
const formattedTimestamps = [];
for (const date in timestamps) {
let commitTime = DateTime.fromISO(date);
let commitTimeUtc = commitTime.setZone('UTC');
let commitTimeLocal = commitTimeUtc.setZone('Europe/Berlin');
let formatter = 'dd.MM.\'HH:mm';
formattedTimestamps.push(commitTimeLocal.toFormat(formatter));
}
return (formattedTimestamps);
}
exports.formatTimestamps = formatTimestamps;
function getImageData(shas) {
return __awaiter(this, void 0, void 0, function* () {
const context = github.context;
const octokit = new rest_1.Octokit({
auth: getGitHubToken(),
request: {
fetch: node_fetch_1.default,
},
});
const imageData = [];
for (const sha in shas) {
const blobTreeSha = yield getBlobTreeSha(octokit, context, sha);
const blobSha = yield getBlobSha(octokit, context, blobTreeSha);
imageData.push(yield getBlobContent(octokit, context, blobSha));
}
return imageData;
});
}
exports.getImageData = getImageData;
/***/ }),
@ -75090,6 +75223,14 @@ function getBlobContent(octokit, context, blobSha) {
module.exports = eval("require")("encoding");
/***/ }),
/***/ 1278:
/***/ ((module) => {
module.exports = eval("require")("luxon");
/***/ }),
/***/ 9491:

165
dist/main/index.js generated vendored
View File

@ -73942,7 +73942,7 @@ function wrappy (fn, cb) {
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.OCTOKIT_BASIC_HEADER = exports.OCTOKIT_ROUTE_BLOB = exports.OCTOKIT_ROUTE_TREE = exports.OCTOKIT_ROUTE_REF_METRICS = exports.OCTOKIT_ROUTE_REF = exports.OCTOKIT_ROUTE_CREATE_TREE = exports.OCTOKIT_ROUTE_CREATE_REF = exports.OCTOKIT_REF_BRANCHE_PREFIX = exports.METRIC_PATH = exports.ERROR_HINT = exports.EVENT_NAME_PULL_REQUEST = exports.ENV_GITHUB_EVENT_NAME = exports.GDS_GRAALVM_PRODUCT_ID = exports.GDS_BASE = exports.MANDREL_NAMESPACE = exports.GRAALVM_RELEASES_REPO = exports.GRAALVM_PLATFORM = exports.GRAALVM_GH_USER = exports.GRAALVM_FILE_EXTENSION = exports.GRAALVM_ARCH = exports.JDK_HOME_SUFFIX = exports.JDK_PLATFORM = exports.JDK_ARCH = exports.VERSION_LATEST = exports.VERSION_DEV = exports.DISTRIBUTION_MANDREL = exports.DISTRIBUTION_GRAALVM_COMMUNITY = exports.DISTRIBUTION_GRAALVM = exports.IS_WINDOWS = exports.IS_MACOS = exports.IS_LINUX = exports.INPUT_NI_MUSL = exports.INPUT_CHECK_FOR_UPDATES = exports.INPUT_CACHE = exports.INPUT_SET_JAVA_HOME = exports.INPUT_GITHUB_TOKEN = exports.INPUT_COMPONENTS = exports.INPUT_DISTRIBUTION = exports.INPUT_JAVA_VERSION = exports.INPUT_GDS_TOKEN = exports.INPUT_VERSION = void 0;
exports.OCTOKIT_BASIC_HEADER = exports.OCTOKIT_ROUTE_GET_EVENTS = exports.OCTOKIT_ROUTE_GET_BLOB = exports.OCTOKIT_ROUTE_GET_TREE = exports.OCTOKIT_ROUTE_GET_REF_METRICS = exports.OCTOKIT_ROUTE_GET_REF = exports.OCTOKIT_ROUTE_CREATE_TREE = exports.OCTOKIT_ROUTE_CREATE_REF = exports.OCTOKIT_REF_BRANCHE_PREFIX = exports.METRIC_PATH = exports.ERROR_HINT = exports.EVENT_NAME_PULL_REQUEST = exports.ENV_GITHUB_EVENT_NAME = exports.GDS_GRAALVM_PRODUCT_ID = exports.GDS_BASE = exports.MANDREL_NAMESPACE = exports.GRAALVM_RELEASES_REPO = exports.GRAALVM_PLATFORM = exports.GRAALVM_GH_USER = exports.GRAALVM_FILE_EXTENSION = exports.GRAALVM_ARCH = exports.JDK_HOME_SUFFIX = exports.JDK_PLATFORM = exports.JDK_ARCH = exports.VERSION_LATEST = exports.VERSION_DEV = exports.DISTRIBUTION_MANDREL = exports.DISTRIBUTION_GRAALVM_COMMUNITY = exports.DISTRIBUTION_GRAALVM = exports.IS_WINDOWS = exports.IS_MACOS = exports.IS_LINUX = exports.INPUT_NI_MUSL = exports.INPUT_CHECK_FOR_UPDATES = exports.INPUT_CACHE = exports.INPUT_SET_JAVA_HOME = exports.INPUT_GITHUB_TOKEN = exports.INPUT_COMPONENTS = exports.INPUT_DISTRIBUTION = exports.INPUT_JAVA_VERSION = exports.INPUT_GDS_TOKEN = exports.INPUT_VERSION = void 0;
exports.INPUT_VERSION = 'version';
exports.INPUT_GDS_TOKEN = 'gds-token';
exports.INPUT_JAVA_VERSION = 'java-version';
@ -73979,10 +73979,11 @@ exports.METRIC_PATH = 'graalvm-metrics';
exports.OCTOKIT_REF_BRANCHE_PREFIX = 'heads';
exports.OCTOKIT_ROUTE_CREATE_REF = 'POST /repos/{owner}/{repo}/git/refs';
exports.OCTOKIT_ROUTE_CREATE_TREE = 'POST /repos/{owner}/{repo}/git/trees';
exports.OCTOKIT_ROUTE_REF = 'GET /repos/{owner}/{repo}/git/ref/';
exports.OCTOKIT_ROUTE_REF_METRICS = `GET /repos/{owner}/{repo}/git/ref/${exports.METRIC_PATH}/`;
exports.OCTOKIT_ROUTE_TREE = 'GET /repos/{owner}/{repo}/git/trees/';
exports.OCTOKIT_ROUTE_BLOB = 'GET /repos/{owner}/{repo}/git/blobs/';
exports.OCTOKIT_ROUTE_GET_REF = 'GET /repos/{owner}/{repo}/git/ref/';
exports.OCTOKIT_ROUTE_GET_REF_METRICS = `GET /repos/{owner}/{repo}/git/ref/${exports.METRIC_PATH}/`;
exports.OCTOKIT_ROUTE_GET_TREE = 'GET /repos/{owner}/{repo}/git/trees/';
exports.OCTOKIT_ROUTE_GET_BLOB = 'GET /repos/{owner}/{repo}/git/blobs/';
exports.OCTOKIT_ROUTE_GET_EVENTS = 'GET /networks/{owner}/{repo}/events';
exports.OCTOKIT_BASIC_HEADER = { 'X-GitHub-Api-Version': '2022-11-28' };
function determineJDKArchitecture() {
switch (process.arch) {
@ -74526,6 +74527,8 @@ const BYTES_TO_GiB = 1024 * 1024 * 1024;
const DOCS_BASE = 'https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/BuildOutput.md';
const INPUT_NI_JOB_REPORTS = 'native-image-job-reports';
const INPUT_NI_PR_REPORTS = 'native-image-pr-reports';
const INPUT_NI_JOB_METRIC_HISTORY = 'native-image-metric-history';
const INPUT_NI_HISTORY_BUILD_COUNT = 'build-counts-for-metric-history';
const INPUT_NI_PR_COMPARISON = 'native-image-pr-comparison';
const NATIVE_IMAGE_CONFIG_FILE = (0, path_1.join)((0, os_1.tmpdir)(), 'native-image-options.properties');
const NATIVE_IMAGE_CONFIG_FILE_ENV = 'NATIVE_IMAGE_CONFIG_FILE';
@ -74568,10 +74571,25 @@ function generateReports() {
}
const treeSha = yield (0, utils_1.createTree)(JSON.stringify(buildOutput));
yield (0, utils_1.createRef)(treeSha);
if (areMetricHistoriesEnabled()) {
const pushEvents = yield (0, utils_1.getPushEvents)(getBuildCountsForMetricHistory());
// Prepare data
const timestamps = [];
const shas = [];
for (const pushEvent in pushEvents) {
timestamps.push(JSON.parse(pushEvent).created_at);
shas.push(JSON.parse(pushEvent).payload.commits[0].sha);
}
// Extract data for plotting
const commitDates = (0, utils_1.formatTimestamps)(timestamps);
const imageData = (0, utils_1.getImageData)(shas);
core.info(String(commitDates));
core.info(String(shas));
core.info(String(imageData));
}
if (arePRBaseComparisonEnabled()) {
const prMetrics = JSON.parse(yield (0, utils_1.getPrBaseBranchMetrics)());
yield (0, utils_1.createPRComment)(createPRComparison(buildOutput, prMetrics));
core.info(createPRComparison(buildOutput, prMetrics));
}
}
});
@ -74583,9 +74601,15 @@ function areJobReportsEnabled() {
function arePRReportsEnabled() {
return (0, utils_1.isPREvent)() && core.getInput(INPUT_NI_PR_REPORTS) === 'true';
}
function areMetricHistoriesEnabled() {
return core.getInput(INPUT_NI_JOB_METRIC_HISTORY) === 'true';
}
function arePRBaseComparisonEnabled() {
return (0, utils_1.isPREvent)() && core.getInput(INPUT_NI_PR_COMPARISON) === 'true';
}
function getBuildCountsForMetricHistory() {
return Number(core.getInput(INPUT_NI_HISTORY_BUILD_COUNT));
}
function getNativeImageOptionsFile() {
let optionsFile = process.env[NATIVE_IMAGE_CONFIG_FILE_ENV];
if (optionsFile === undefined) {
@ -74627,7 +74651,7 @@ gantt
title Native Image Size Details
todayMarker off
dateFormat X
axisFormat %s
axisFormat %
section Code area
${recentBranch} (${bytesToHuman(detailsRecent.code_area.bytes)}): active, 0, ${detailsRecent.code_area.bytes}
@ -75895,7 +75919,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getPrBaseBranchMetrics = exports.createTree = exports.createRef = exports.createPRComment = exports.isPREvent = exports.toSemVer = exports.calculateSHA256 = exports.downloadExtractAndCacheJDK = exports.downloadAndExtractJDK = exports.getMatchingTags = exports.getTaggedRelease = exports.getLatestRelease = exports.exec = void 0;
exports.getImageData = exports.formatTimestamps = exports.getPushEvents = exports.getPrBaseBranchMetrics = exports.createTree = exports.createRef = exports.createPRComment = exports.isPREvent = exports.toSemVer = exports.calculateSHA256 = exports.downloadExtractAndCacheJDK = exports.downloadAndExtractJDK = exports.getMatchingTags = exports.getTaggedRelease = exports.getLatestRelease = exports.exec = void 0;
const c = __importStar(__nccwpck_require__(2764));
const core = __importStar(__nccwpck_require__(2258));
const github = __importStar(__nccwpck_require__(7168));
@ -75910,6 +75934,7 @@ const rest_1 = __nccwpck_require__(6175);
const node_fetch_1 = __importDefault(__nccwpck_require__(831));
// Set up Octokit for github.com only and in the same way as @actions/github (see https://git.io/Jy9YP)
const baseUrl = 'https://api.github.com';
const { DateTime } = __nccwpck_require__(1278);
const GitHubDotCom = rest_1.Octokit.defaults({
baseUrl,
request: {
@ -76134,28 +76159,136 @@ exports.getPrBaseBranchMetrics = getPrBaseBranchMetrics;
function getBaseBranchCommitSha(octokit, context) {
return __awaiter(this, void 0, void 0, function* () {
const prBaseBranchName = getPrBaseBranchSha();
const { data } = yield octokit.request(c.OCTOKIT_ROUTE_REF + c.OCTOKIT_REF_BRANCHE_PREFIX + '/' + prBaseBranchName, Object.assign(Object.assign({}, context.repo), { ref: c.OCTOKIT_REF_BRANCHE_PREFIX + '/' + prBaseBranchName, headers: c.OCTOKIT_BASIC_HEADER }));
const { data } = yield octokit.request(c.OCTOKIT_ROUTE_GET_REF + c.OCTOKIT_REF_BRANCHE_PREFIX + '/' + prBaseBranchName, Object.assign(Object.assign({}, context.repo), { ref: c.OCTOKIT_REF_BRANCHE_PREFIX + '/' + prBaseBranchName, headers: c.OCTOKIT_BASIC_HEADER }));
return data.object.sha;
});
}
function getBlobTreeSha(octokit, context, baseCommitSha) {
return __awaiter(this, void 0, void 0, function* () {
const { data } = yield octokit.request(c.OCTOKIT_ROUTE_REF_METRICS + baseCommitSha, Object.assign(Object.assign({}, context.repo), { headers: c.OCTOKIT_BASIC_HEADER }));
const { data } = yield octokit.request(c.OCTOKIT_ROUTE_GET_REF_METRICS + baseCommitSha, Object.assign(Object.assign({}, context.repo), { headers: c.OCTOKIT_BASIC_HEADER }));
return data.object.sha;
});
}
function getBlobSha(octokit, context, blobTreeSha) {
return __awaiter(this, void 0, void 0, function* () {
const { data } = yield octokit.request(c.OCTOKIT_ROUTE_TREE + blobTreeSha, Object.assign(Object.assign({}, context.repo), { tree_sha: blobTreeSha, headers: c.OCTOKIT_BASIC_HEADER }));
const { data } = yield octokit.request(c.OCTOKIT_ROUTE_GET_TREE + blobTreeSha, Object.assign(Object.assign({}, context.repo), { tree_sha: blobTreeSha, headers: c.OCTOKIT_BASIC_HEADER }));
return data.tree[0].sha;
});
}
function getBlobContent(octokit, context, blobSha) {
return __awaiter(this, void 0, void 0, function* () {
const { data } = yield octokit.request(c.OCTOKIT_ROUTE_BLOB + blobSha, Object.assign(Object.assign({}, context.repo), { file_sha: blobSha, headers: c.OCTOKIT_BASIC_HEADER }));
const { data } = yield octokit.request(c.OCTOKIT_ROUTE_GET_BLOB + blobSha, Object.assign(Object.assign({}, context.repo), { file_sha: blobSha, headers: c.OCTOKIT_BASIC_HEADER }));
return js_base64_1.Base64.decode(data.content);
});
}
function getPushEvents(numberOfBuilds) {
return __awaiter(this, void 0, void 0, function* () {
try {
const octokit = new rest_1.Octokit({
auth: getGitHubToken(),
request: {
fetch: node_fetch_1.default,
},
});
const context = github.context;
const eventResponse = yield octokit.request(c.OCTOKIT_ROUTE_GET_EVENTS, Object.assign(Object.assign({}, context.repo), { headers: c.OCTOKIT_BASIC_HEADER }));
let linkHeader = eventResponse.headers.link;
const eventData = eventResponse.data;
const pushEvents = [];
/* for (const gitEvent in eventData ) {
if (numberOfBuilds <= 0) {
break
}
if (gitEvent["type"] === 'pushEvent' && gitEvent["payload"].ref === process.env.GITHUB_REF) {
pushEvents.push(gitEvent)
numberOfBuilds = numberOfBuilds - 1
}
const linkHeader = eventResponse.headers.link
const regex = /<([^>]+)>;\s*rel/;
const nextPageMatch = linkHeader?.search(/<([^>]+)>;\s*rel="next"/)
}*/
for (let event of eventData) {
if (numberOfBuilds <= 0) {
break;
}
if (event.type === "PushEvent" &&
event.payload.ref === process.env.GITHUB_REF) {
pushEvents.push(event);
numberOfBuilds--;
}
}
let nextPageMatch = /<([^>]+)>;\s*rel="next"/;
while (linkHeader &&
linkHeader.includes('rel="next"') &&
numberOfBuilds > 0) {
let nextPageUrl = nextPageMatch === null || nextPageMatch === void 0 ? void 0 : nextPageMatch.exec(linkHeader)[1];
// Make the request for the next page
// Assuming you use fetch API or similar for making HTTP requests
(0, node_fetch_1.default)(nextPageUrl, {
headers: {
Authorization: "Bearer " + getGitHubToken(),
},
})
.then((response) => response.json())
.then((nextPageResponse) => {
for (let event of nextPageResponse) {
if (numberOfBuilds <= 0) {
break;
}
if (event.type === "PushEvent" &&
event.payload.ref === process.env.GITHUB_REF) {
pushEvents.push(event);
numberOfBuilds--;
}
}
// Update the link_header for the next iteration
linkHeader = eventResponse.headers.link;
})
.catch((error) => {
console.error("Error fetching next page:", error);
});
}
return pushEvents;
}
catch (err) {
return [];
console.info("An error occurred during getting metrics data.");
}
});
}
exports.getPushEvents = getPushEvents;
function formatTimestamps(timestamps) {
const formattedTimestamps = [];
for (const date in timestamps) {
let commitTime = DateTime.fromISO(date);
let commitTimeUtc = commitTime.setZone('UTC');
let commitTimeLocal = commitTimeUtc.setZone('Europe/Berlin');
let formatter = 'dd.MM.\'HH:mm';
formattedTimestamps.push(commitTimeLocal.toFormat(formatter));
}
return (formattedTimestamps);
}
exports.formatTimestamps = formatTimestamps;
function getImageData(shas) {
return __awaiter(this, void 0, void 0, function* () {
const context = github.context;
const octokit = new rest_1.Octokit({
auth: getGitHubToken(),
request: {
fetch: node_fetch_1.default,
},
});
const imageData = [];
for (const sha in shas) {
const blobTreeSha = yield getBlobTreeSha(octokit, context, sha);
const blobSha = yield getBlobSha(octokit, context, blobTreeSha);
imageData.push(yield getBlobContent(octokit, context, blobSha));
}
return imageData;
});
}
exports.getImageData = getImageData;
/***/ }),
@ -76166,6 +76299,14 @@ function getBlobContent(octokit, context, blobSha) {
module.exports = eval("require")("encoding");
/***/ }),
/***/ 1278:
/***/ ((module) => {
module.exports = eval("require")("luxon");
/***/ }),
/***/ 9491:

View File

@ -1,5 +1,6 @@
import * as otypes from '@octokit/types'
import {context} from "@actions/github";
import exp from "constants";
export const INPUT_VERSION = 'version'
export const INPUT_GDS_TOKEN = 'gds-token'
@ -49,10 +50,11 @@ export const OCTOKIT_REF_BRANCHE_PREFIX = 'heads'
export const OCTOKIT_ROUTE_CREATE_REF = 'POST /repos/{owner}/{repo}/git/refs'
export const OCTOKIT_ROUTE_CREATE_TREE = 'POST /repos/{owner}/{repo}/git/trees'
export const OCTOKIT_ROUTE_REF = 'GET /repos/{owner}/{repo}/git/ref/'
export const OCTOKIT_ROUTE_REF_METRICS = `GET /repos/{owner}/{repo}/git/ref/${METRIC_PATH}/`
export const OCTOKIT_ROUTE_TREE = 'GET /repos/{owner}/{repo}/git/trees/'
export const OCTOKIT_ROUTE_BLOB = 'GET /repos/{owner}/{repo}/git/blobs/'
export const OCTOKIT_ROUTE_GET_REF = 'GET /repos/{owner}/{repo}/git/ref/'
export const OCTOKIT_ROUTE_GET_REF_METRICS = `GET /repos/{owner}/{repo}/git/ref/${METRIC_PATH}/`
export const OCTOKIT_ROUTE_GET_TREE = 'GET /repos/{owner}/{repo}/git/trees/'
export const OCTOKIT_ROUTE_GET_BLOB = 'GET /repos/{owner}/{repo}/git/blobs/'
export const OCTOKIT_ROUTE_GET_EVENTS = 'GET /networks/{owner}/{repo}/events'
export const OCTOKIT_BASIC_HEADER = {'X-GitHub-Api-Version': '2022-11-28'}

View File

@ -4,7 +4,14 @@ import * as fs from 'fs'
import * as github from '@actions/github'
import {join} from 'path'
import {tmpdir} from 'os'
import {createPRComment, createRef, createTree, getPrBaseBranchMetrics, isPREvent, toSemVer} from '../utils'
import {
createPRComment,
createRef,
createTree, formatTimestamps, getImageData,
getPrBaseBranchMetrics, getPushEvents,
isPREvent,
toSemVer
} from '../utils'
import {gte} from 'semver'
const BUILD_OUTPUT_JSON_PATH = join(tmpdir(), 'native-image-build-output.json')
@ -15,6 +22,8 @@ const DOCS_BASE =
'https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/BuildOutput.md'
const INPUT_NI_JOB_REPORTS = 'native-image-job-reports'
const INPUT_NI_PR_REPORTS = 'native-image-pr-reports'
const INPUT_NI_JOB_METRIC_HISTORY = 'native-image-metric-history'
const INPUT_NI_HISTORY_BUILD_COUNT = 'build-counts-for-metric-history'
const INPUT_NI_PR_COMPARISON = 'native-image-pr-comparison'
const NATIVE_IMAGE_CONFIG_FILE = join(
tmpdir(),
@ -137,14 +146,33 @@ export async function generateReports(): Promise<void> {
if (arePRReportsEnabled()) {
await createPRComment(report)
}
const treeSha = await createTree(JSON.stringify(buildOutput))
await createRef(treeSha)
if (areMetricHistoriesEnabled()) {
const pushEvents = await getPushEvents(getBuildCountsForMetricHistory())
// Prepare data
const timestamps = []
const shas = []
for (const pushEvent in pushEvents) {
timestamps.push(JSON.parse(pushEvent).created_at)
shas.push(JSON.parse(pushEvent).payload.commits[0].sha)
}
// Extract data for plotting
const commitDates = formatTimestamps(timestamps)
const imageData = getImageData(shas)
core.info(String(commitDates))
core.info(String(shas))
core.info(String(imageData))
}
if (arePRBaseComparisonEnabled()) {
const prMetrics: BuildOutput = JSON.parse(
await getPrBaseBranchMetrics()
)
await createPRComment(createPRComparison(buildOutput, prMetrics))
core.info(createPRComparison(buildOutput, prMetrics))
}
}
}
@ -157,10 +185,18 @@ function arePRReportsEnabled(): boolean {
return isPREvent() && core.getInput(INPUT_NI_PR_REPORTS) === 'true'
}
function areMetricHistoriesEnabled(): boolean {
return core.getInput(INPUT_NI_JOB_METRIC_HISTORY) === 'true'
}
function arePRBaseComparisonEnabled(): boolean {
return isPREvent() && core.getInput(INPUT_NI_PR_COMPARISON) === 'true'
}
function getBuildCountsForMetricHistory(): number {
return Number(core.getInput(INPUT_NI_HISTORY_BUILD_COUNT))
}
function getNativeImageOptionsFile(): string {
let optionsFile = process.env[NATIVE_IMAGE_CONFIG_FILE_ENV]
if (optionsFile === undefined) {
@ -208,7 +244,7 @@ gantt
title Native Image Size Details
todayMarker off
dateFormat X
axisFormat %s
axisFormat %
section Code area
${recentBranch} (${bytesToHuman(detailsRecent.code_area.bytes)}): active, 0, ${detailsRecent.code_area.bytes}

View File

@ -14,6 +14,7 @@ import {Context} from "@actions/github/lib/context";
// Set up Octokit for github.com only and in the same way as @actions/github (see https://git.io/Jy9YP)
const baseUrl = 'https://api.github.com'
const { DateTime } = require('luxon');
const GitHubDotCom = Octokit.defaults({
baseUrl,
request: {
@ -212,7 +213,6 @@ export async function createRef(sha: string) {
export async function createTree(metadataJson: string): Promise<string> {
try {
const octokit = new Octokit({
auth: getGitHubToken(),
request: {
@ -268,7 +268,7 @@ export async function getPrBaseBranchMetrics(): Promise<string> {
async function getBaseBranchCommitSha(octokit: Octokit, context: Context): Promise<string> {
const prBaseBranchName = getPrBaseBranchSha()
const { data } = await octokit.request(c.OCTOKIT_ROUTE_REF + c.OCTOKIT_REF_BRANCHE_PREFIX + '/' + prBaseBranchName, {
const { data } = await octokit.request(c.OCTOKIT_ROUTE_GET_REF + c.OCTOKIT_REF_BRANCHE_PREFIX + '/' + prBaseBranchName, {
...context.repo,
ref: c.OCTOKIT_REF_BRANCHE_PREFIX + '/' + prBaseBranchName,
headers: c.OCTOKIT_BASIC_HEADER
@ -277,7 +277,7 @@ async function getBaseBranchCommitSha(octokit: Octokit, context: Context): Promi
}
async function getBlobTreeSha(octokit: Octokit, context: Context, baseCommitSha: string): Promise<string> {
const { data } = await octokit.request(c.OCTOKIT_ROUTE_REF_METRICS + baseCommitSha, {
const { data } = await octokit.request(c.OCTOKIT_ROUTE_GET_REF_METRICS + baseCommitSha, {
...context.repo,
headers: c.OCTOKIT_BASIC_HEADER
})
@ -285,7 +285,7 @@ async function getBlobTreeSha(octokit: Octokit, context: Context, baseCommitSha:
}
async function getBlobSha(octokit: Octokit, context: Context, blobTreeSha: string) {
const { data } = await octokit.request(c.OCTOKIT_ROUTE_TREE + blobTreeSha, {
const { data } = await octokit.request(c.OCTOKIT_ROUTE_GET_TREE + blobTreeSha, {
...context.repo,
tree_sha: blobTreeSha,
headers: c.OCTOKIT_BASIC_HEADER
@ -294,10 +294,126 @@ async function getBlobSha(octokit: Octokit, context: Context, blobTreeSha: strin
}
async function getBlobContent(octokit: Octokit, context: Context, blobSha: string) {
const { data } = await octokit.request(c.OCTOKIT_ROUTE_BLOB + blobSha, {
const { data } = await octokit.request(c.OCTOKIT_ROUTE_GET_BLOB + blobSha, {
...context.repo,
file_sha: blobSha,
headers: c.OCTOKIT_BASIC_HEADER
})
return Base64.decode(data.content)
}
export async function getPushEvents(numberOfBuilds: number): Promise<any[]> {
try {
const octokit = new Octokit({
auth: getGitHubToken(),
request: {
fetch: fetch,
},
});
const context = github.context
const eventResponse = await octokit.request(c.OCTOKIT_ROUTE_GET_EVENTS, {
...context.repo,
headers: c.OCTOKIT_BASIC_HEADER
})
let linkHeader = eventResponse.headers.link
const eventData: any = eventResponse.data
const pushEvents = []
/* for (const gitEvent in eventData ) {
if (numberOfBuilds <= 0) {
break
}
if (gitEvent["type"] === 'pushEvent' && gitEvent["payload"].ref === process.env.GITHUB_REF) {
pushEvents.push(gitEvent)
numberOfBuilds = numberOfBuilds - 1
}
const linkHeader = eventResponse.headers.link
const regex = /<([^>]+)>;\s*rel/;
const nextPageMatch = linkHeader?.search(/<([^>]+)>;\s*rel="next"/)
}*/
for (let event of eventData) {
if (numberOfBuilds <= 0) {
break;
}
if (
event.type === "PushEvent" &&
event.payload!.ref! === process.env.GITHUB_REF
) {
pushEvents.push(event);
numberOfBuilds--;
}
}
let nextPageMatch = /<([^>]+)>;\s*rel="next"/;
while (
linkHeader &&
linkHeader.includes('rel="next"') &&
numberOfBuilds > 0
) {
let nextPageUrl = nextPageMatch?.exec(linkHeader)![1];
// Make the request for the next page
// Assuming you use fetch API or similar for making HTTP requests
fetch(nextPageUrl, {
headers: {
Authorization: "Bearer " + getGitHubToken(),
},
})
.then((response) => response.json())
.then((nextPageResponse) => {
for (let event of nextPageResponse) {
if (numberOfBuilds <= 0) {
break;
}
if (
event.type === "PushEvent" &&
event.payload.ref === process.env.GITHUB_REF
) {
pushEvents.push(event);
numberOfBuilds--;
}
}
// Update the link_header for the next iteration
linkHeader = eventResponse.headers.link;
})
.catch((error) => {
console.error("Error fetching next page:", error);
});
}
return pushEvents
} catch (err) {
return []
console.info("An error occurred during getting metrics data.")
}
}
export function formatTimestamps(timestamps: string[]) {
const formattedTimestamps = []
for (const date in timestamps) {
let commitTime = DateTime.fromISO(date);
let commitTimeUtc = commitTime.setZone('UTC');
let commitTimeLocal = commitTimeUtc.setZone('Europe/Berlin');
let formatter = 'dd.MM.\'HH:mm';
formattedTimestamps.push(commitTimeLocal.toFormat(formatter));
}
return(formattedTimestamps)
}
export async function getImageData(shas: string[]) {
const context = github.context
const octokit = new Octokit({
auth: getGitHubToken(),
request: {
fetch: fetch,
},
});
const imageData = []
for (const sha in shas) {
const blobTreeSha = await getBlobTreeSha(octokit, context, sha)
const blobSha = await getBlobSha(octokit, context, blobTreeSha)
imageData.push(await getBlobContent(octokit, context, blobSha))
}
return imageData
}