Skip to content

Commit

Permalink
🔥 Mergins head and abse metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
polRk committed Oct 24, 2024
1 parent f4d1e73 commit 0ca51ce
Show file tree
Hide file tree
Showing 8 changed files with 3,909 additions and 120 deletions.
24 changes: 12 additions & 12 deletions init/main.js

Large diffs are not rendered by default.

3,811 changes: 3,780 additions & 31 deletions init/post.js

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions init/src/jobs/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as fs from 'node:fs'
import * as path from 'node:path'
import { debug, getInput, saveState } from '@actions/core'
import { debug, getInput, info, saveState } from '@actions/core'
import { exec } from '@actions/exec'
import { generateComposeFile, prometheusConfig, ydbConfig } from '../configs'
import { context } from '@actions/github'
Expand All @@ -16,40 +16,40 @@ import { getPullRequestNumber } from '../help/pulls'
fs.mkdirSync(cwd, { recursive: true })

{
debug('Aquire pull request number...')
info('Aquire pull request number...')
let prNumber = await getPullRequestNumber() || -1
debug(`Pull request number: ${prNumber}`)
info(`Pull request number: ${prNumber}`)
saveState("issue", prNumber)
}

{
debug("Creating ydb config...")
info("Creating ydb config...")
let configPath = path.join(cwd, "ydb.yaml")
let configContent = ydbConfig
fs.writeFileSync(configPath, configContent, { encoding: "utf-8" })
debug(`Created config for ydb: ${configPath}`)
info(`Created config for ydb: ${configPath}`)
}

{
debug("Creating prometheus config...")
info("Creating prometheus config...")
let configPath = path.join(cwd, "prometheus.yml")
let configContent = prometheusConfig
fs.writeFileSync(configPath, configContent, { encoding: "utf-8" })
debug(`Created config for prometheus: ${configPath}`)
info(`Created config for prometheus: ${configPath}`)
}

{
debug("Creating compose config...")
info("Creating compose config...")
let composePath = path.join(cwd, "compose.yaml")
let composeContent = generateComposeFile(parseInt(getInput("YDB_DATABASE_NODE_COUNT", { required: true })))
fs.writeFileSync(composePath, composeContent, { encoding: "utf-8" })
debug(`Created compose.yaml: ${composePath}`)
info(`Created compose.yaml: ${composePath}`)
}

debug("Starting YDB...")
info("Starting YDB...")
await exec(`docker`, [`compose`, `-f`, `compose.yaml`, `up`, `--quiet-pull`, `-d`], { cwd })

let start = new Date()
debug(`YDB started at ${start}`)
info(`YDB started at ${start}`)
saveState("start", start.toISOString())
})()
130 changes: 84 additions & 46 deletions init/src/jobs/post.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import * as fs from 'node:fs'
import * as path from 'node:path'
import { exec } from "@actions/exec"
import { debug, getInput, getState, saveState } from "@actions/core"
import { debug, getInput, getState, info, saveState, warning } from "@actions/core"
import { DefaultArtifactClient } from '@actions/artifact'
import { collectPrometheus } from '../metrics/prometheus'
import { defaultMetrics } from '../metrics/default'
import { renderReport } from '../report/default'
import { context, getOctokit } from '@actions/github'
import { getCurrentWorkflowRuns } from '../workflow/workflow'
import type { Series } from '../report/chart'

(async function post() {
let cwd = getState("cwd")
Expand All @@ -22,86 +23,123 @@ import { getCurrentWorkflowRuns } from '../workflow/workflow'

let artifactClient = new DefaultArtifactClient()

debug("Collecting metrics for head ref...")
info("Collecting metrics for head ref...")
let metrics = await collectPrometheus(start, end, defaultMetrics.metrics)
info(`Metrics collected for head ref: ${Object.keys(metrics)}`)
debug(`Head ref metrics: ${Object.keys(metrics)}`)

{
debug("Writing metrics...")
info("Writing metrics...")
let metricsPath = path.join(cwd, `${sdk}-metrics.json`)
fs.writeFileSync(metricsPath, JSON.stringify(metrics), { encoding: "utf-8" })
debug(`Metrics written to ${metricsPath}`)
info(`Metrics written to ${metricsPath}`)

debug("Upload metrics as an artifact...")
info("Upload metrics as an artifact...")
let { id } = await artifactClient.uploadArtifact(`${sdk}-metrics.json`, [metricsPath], cwd, { retentionDays: 1 })
debug(`Metrics uploaded as an artifact ${id}`)
info(`Metrics uploaded as an artifact ${id}`)
}

if (!isPullRequest) {
debug("Not a pull request.")
warning("Not a pull request.")
} else {
// debug(`Pull request number: ${pullNumber}`)

// debug("Fetching information about pull request...")
// let { data: pr } = await getOctokit(getInput("token", { required: true })).rest.pulls.get({
// owner: context.repo.owner,
// repo: context.repo.repo,
// pull_number: pullNumber,
// })

// debug(`Fetching information about previous runs for base branch...`)
// let runs = await getCurrentWorkflowRuns(pr.base.ref)
// debug(`Found ${runs.length} completed and successfull runs for default branch.`)

// debug(`Finding latest run...`)
// let latestRun = runs[0]
// debug(`Latest run: ${JSON.stringify(latestRun, null, 4)}`)

// debug(`Finding latest run artifacts...`)
// let { data: { artifacts } } = await getOctokit(getInput("token", { required: true })).rest.actions.listWorkflowRunArtifacts({
// owner: context.repo.owner,
// repo: context.repo.repo,
// run_id: latestRun.id,
// })

// debug(`Found ${artifacts.length} artifacts: ${JSON.stringify(artifacts, null, 4)}`)

// debug("Collecting metrics for base ref...")
debug(`Pull request number: ${pullNumber}`)

info("Fetching information about pull request...")
let { data: pr } = await getOctokit(getInput("github_token", { required: true })).rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pullNumber,
})
info(`Pull request information fetched: ${pr.html_url}`)
debug(`Pull request information: ${JSON.stringify(pr, null, 4)}`)

info(`Fetching information about previous runs for base branch...`)
let runs = await getCurrentWorkflowRuns(pr.base.ref)
info(`Found ${runs.length} completed and successfull runs for default branch.`)
debug(`Previous runs for base branch: ${JSON.stringify(runs.map(run => ({ id: run.id, upd: run.updated_at })), null, 4)}`)

info(`Finding latest run...`)
let latestRun = runs[0]
info(`Latest run: ${latestRun.url}`)
debug(`Latest run: ${JSON.stringify(latestRun, null, 4)}`)

info(`Finding latest run artifacts...`)
let { data: { artifacts } } = await getOctokit(getInput("github_token", { required: true })).rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: latestRun.id,
})
info(`Found ${artifacts.length} artifacts.`)
debug(`Latest run artifacts: ${JSON.stringify(artifacts, null, 4)}`)

let artifact = artifacts.find(artifact => artifact.name === `${sdk}-metrics.json`)
if (!artifact) {
warning("Metrics for base ref not found.")
} else {
debug(`Metrics artifact: ${JSON.stringify(artifact, null, 4)}`)

info(`Downloading artifact ${artifact.id}...`)
let { downloadPath } = await artifactClient.downloadArtifact(artifact.id, {
path: cwd,
findBy: {
token: getInput("github_token", { required: true }),
workflowRunId: latestRun.workflow_id,
repositoryOwner: context.repo.owner,
repositoryName: context.repo.repo,
}
});

info(`Downloaded artifact ${artifact.name} to ${downloadPath}`)

info(`Extracting metrics from artifact ${artifact.id}...`)
let baseMetrics = JSON.parse(fs.readFileSync(path.join(cwd, artifact.name), { encoding: "utf-8" })) as Record<string, Series[]>

info(`Metrics extracted from artifact ${artifact.id}: ${Object.keys(baseMetrics)}`)
debug(`Base metrics: ${JSON.stringify(baseMetrics, null, 4)}`)

info(`Merging metrics...`)
for (let [name, baseSeries] of Object.entries(baseMetrics)) {
if (!metrics[name]) continue

// base metrics always must be the second
metrics[name] = metrics[name].concat(baseSeries)
}
}
}

debug("Rendering report...")
info("Rendering report...")
let report = renderReport(sdk, metrics)
debug(`Report: ${report}`)

{
debug("Writing report...")
info("Writing report...")
let reportPath = path.join(cwd, `${sdk}-report.md`)
fs.writeFileSync(reportPath, report, { encoding: "utf-8" })
debug(`Report written to ${reportPath}`)
info(`Report written to ${reportPath}`)

debug("Upload report as an artifact...")
info("Upload report as an artifact...")
let { id } = await artifactClient.uploadArtifact(`${sdk}-report.md`, [reportPath], cwd, { retentionDays: 1 })
debug(`Report uploaded as an artifact ${id}`)
info(`Report uploaded as an artifact ${id}`)
}

{
debug("Writing pull number...")
info("Writing pull number...")
let pullPath = path.join(cwd, `${sdk}-pull.txt`)
fs.writeFileSync(pullPath, pullNumber.toFixed(0), { encoding: "utf-8" })
debug(`Pull number written to ${pullPath}`)
info(`Pull number written to ${pullPath}`)

debug("Upload pull number as an artifact...")
info("Upload pull number as an artifact...")
let { id } = await artifactClient.uploadArtifact(`${sdk}-pull.txt`, [pullPath], cwd, { retentionDays: 1 })
debug(`Pull number uploaded as an artifact ${id}`)
info(`Pull number uploaded as an artifact ${id}`)
}

debug("Stopping YDB...")
info("Stopping YDB...")
await exec(`docker`, [`compose`, `-f`, `compose.yaml`, `down`], { cwd })

debug(`YDB stopped at ${end}`)
info(`YDB stopped at ${end}`)

let duration = end.getTime() - start.getTime()
debug(`YDB SLO Test duration: ${duration}ms.`)
info(`YDB SLO Test duration: ${duration}ms.`)

debug("Cleaning up temp directory...")
fs.rmSync(cwd, { recursive: true });
Expand Down
4 changes: 2 additions & 2 deletions init/src/report/colors.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Tableau 10
export const palette = [
"#2CA02C",
"#FF7F0E",
"#1F77B4",
"#D62728",
"#FF7F0E",
"#2CA02C",
"#9467BD",
"#8C564B",
"#E377C2",
Expand Down
4 changes: 2 additions & 2 deletions init/src/workflow/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { getInput } from "@actions/core"
import { context, getOctokit } from "@actions/github"

export async function getCurrentWorkflowRuns(branch: string) {
let { data: { workflows } } = await getOctokit(getInput("token", { required: true })).rest.actions.listRepoWorkflows({
let { data: { workflows } } = await getOctokit(getInput("github_token", { required: true })).rest.actions.listRepoWorkflows({
owner: context.repo.owner,
repo: context.repo.repo,
})
Expand All @@ -13,7 +13,7 @@ export async function getCurrentWorkflowRuns(branch: string) {
return []
}

let { data: { workflow_runs } } = await getOctokit(getInput("token", { required: true })).rest.actions.listWorkflowRuns({
let { data: { workflow_runs } } = await getOctokit(getInput("github_token", { required: true })).rest.actions.listWorkflowRuns({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: workflow.id,
Expand Down
19 changes: 10 additions & 9 deletions report/main.js

Large diffs are not rendered by default.

15 changes: 8 additions & 7 deletions report/src/jobs/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ import { context, getOctokit } from '@actions/github';
}
});

debug(`Found ${artifacts.length} artifacts: ${JSON.stringify(artifacts, null, 4)}`)
info(`Found ${artifacts.length} artifacts.`)
debug(`Artifacts: ${JSON.stringify(artifacts, null, 4)}`)

let reports: Record<string, string> = {}
let pulls: Record<string, string> = {}

for (let artifact of artifacts) {
debug(`Downloading artifact ${artifact.id}...`)
info(`Downloading artifact ${artifact.id}...`)
let { downloadPath } = await artifactClient.downloadArtifact(artifact.id, {
path: cwd,
findBy: {
Expand Down Expand Up @@ -59,7 +60,7 @@ import { context, getOctokit } from '@actions/github';
owner: context.repo.owner,
repo: context.repo.repo,
})
debug(`Got ${data.length} comments for ${pr}`)
info(`Got ${data.length} comments for ${pr}`)

comments[pr] = data.map(comment => ({
id: comment.id,
Expand All @@ -77,23 +78,23 @@ import { context, getOctokit } from '@actions/github';
})

if (existingComment) {
debug(`Updating report for ${sdk}...`)
info(`Updating report for ${sdk}...`)
let { data } = await getOctokit(getInput("token", { required: true })).rest.issues.updateComment({
comment_id: existingComment.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: report
})
debug(`Report for was ${sdk} updated: ${data.html_url}`)
info(`Report for was ${sdk} updated: ${data.html_url}`)
} else {
debug(`Creating report for ${sdk}...`)
info(`Creating report for ${sdk}...`)
let { data } = await getOctokit(getInput("token", { required: true })).rest.issues.createComment({
issue_number: parseInt(pr.trim()),
owner: context.repo.owner,
repo: context.repo.repo,
body: report
})
debug(`Report for ${sdk} created: ${data.html_url}`)
info(`Report for ${sdk} created: ${data.html_url}`)
}
}
})()

0 comments on commit 0ca51ce

Please sign in to comment.