mirror of
https://github.com/ROCm/composable_kernel.git
synced 2026-05-14 02:02:46 +00:00
Automated Perfetto UI Notifications (#3255)
* Testing visualization generation
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Adding dummy test data
* Update Jenkinsfile
* Update Jenkinsfile
* Adding notifications
* Testing
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Image compression
* Update Jenkinsfile
* Moving capture logic to main Jenkins file
* Testing generation
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Fixing curl request
* Update Jenkinsfile
* Clean up
* Fix
* Fixing notification
* Testing message creation
* Adjusting message payload
* Testing notification generation
* Updating main jenkinsfile
* Fixing cleanup call
* Removing test pipeline code
* Comment clean up
* Testing pipeline
* Update Jenkinsfile
* Update Jenkinsfile
* Update Jenkinsfile
* Moving archive
Moving trace archive to safe location before source checkout
* Removing test pipeline
* Testing pipeline with unique file names
* Update Jenkinsfile
* Removing test files
Updated main pipeline
[ROCm/composable_kernel commit: 40d7217ac7]
This commit is contained in:
132
Jenkinsfile
vendored
132
Jenkinsfile
vendored
@@ -72,6 +72,129 @@ def sendFailureNotifications() {
|
||||
}
|
||||
}
|
||||
|
||||
def generateAndArchiveBuildTraceVisualization() {
|
||||
try {
|
||||
def buildTraceFileName = "ck_build_trace.json";
|
||||
|
||||
// Attempt to download the build trace file to check if it exists
|
||||
def traceFileExists = false
|
||||
try {
|
||||
copyArtifacts(
|
||||
projectName: env.JOB_NAME,
|
||||
selector: specific(env.BUILD_NUMBER),
|
||||
filter: buildTraceFileName
|
||||
)
|
||||
traceFileExists = fileExists(buildTraceFileName)
|
||||
} catch (Exception e) {
|
||||
echo "Could not copy artifacts: ${e.getMessage()}"
|
||||
traceFileExists = false
|
||||
}
|
||||
|
||||
sh """
|
||||
echo "post download:"
|
||||
ls -la
|
||||
"""
|
||||
|
||||
if (traceFileExists) {
|
||||
// Move the build trace file to a temporary location to preserve it during checkout
|
||||
sh """
|
||||
mkdir -p /tmp/jenkins_artifacts
|
||||
cp ${buildTraceFileName} /tmp/jenkins_artifacts/${buildTraceFileName}
|
||||
ls -la /tmp/jenkins_artifacts/
|
||||
"""
|
||||
} else {
|
||||
echo "Build trace archive not found"
|
||||
return
|
||||
}
|
||||
|
||||
// Checkout source code to get required files
|
||||
checkout scm
|
||||
|
||||
// Restore the build trace file after checkout
|
||||
sh """
|
||||
ls -la
|
||||
cp /tmp/jenkins_artifacts/${buildTraceFileName} ${buildTraceFileName}
|
||||
ls -la ${buildTraceFileName}
|
||||
"""
|
||||
|
||||
// Pull image
|
||||
def image = "ghcr.io/puppeteer/puppeteer:24.30.0"
|
||||
echo "Pulling image: ${image}"
|
||||
def retimage = docker.image("${image}")
|
||||
retimage.pull()
|
||||
|
||||
// Create a temporary workspace
|
||||
sh """#!/bin/bash
|
||||
ls -la
|
||||
mkdir -p workspace
|
||||
cp ./script/infra_helper/capture_build_trace.js ./workspace
|
||||
cp ${buildTraceFileName} ./workspace/${buildTraceFileName}
|
||||
chmod 777 ./workspace
|
||||
ls -la ./workspace
|
||||
"""
|
||||
|
||||
// Run container to get snapshot
|
||||
def dockerOpts = "--cap-add=SYS_ADMIN -v \"\$(pwd)/workspace:/workspace\" -e NODE_PATH=/home/pptruser/node_modules"
|
||||
// Create unique image name by sanitizing job name
|
||||
def sanitizedJobName = env.JOB_NAME.replaceAll(/[\/\\:*?"<>| ]/, '_')
|
||||
def imageName = "perfetto_snapshot_${sanitizedJobName}_build_${env.BUILD_NUMBER}.png"
|
||||
sh """
|
||||
docker run --rm ${dockerOpts} ${image} node /workspace/capture_build_trace.js
|
||||
mv ./workspace/perfetto_snapshot_build.png ./workspace/${imageName}
|
||||
"""
|
||||
|
||||
// Archive the snapshot
|
||||
sh """
|
||||
mv ./workspace/${imageName} ${imageName}
|
||||
"""
|
||||
archiveArtifacts "${imageName}"
|
||||
|
||||
// Notify the channel
|
||||
withCredentials([string(credentialsId: 'ck_ci_build_perf_webhook_url', variable: 'WEBHOOK_URL')]) {
|
||||
sh '''
|
||||
# Create build trace filename with build number based on the original filename
|
||||
BUILD_TRACE_WITH_NUMBER=$(echo "''' + buildTraceFileName + '''" | sed 's/.json/_''' + sanitizedJobName + '''_''' + env.BUILD_NUMBER + '''.json/')
|
||||
|
||||
# Convert image to base64
|
||||
echo "Converting image to base64..."
|
||||
IMAGE_BASE64=$(base64 -w 0 ''' + imageName + ''')
|
||||
echo "Image base64 length: ${#IMAGE_BASE64}"
|
||||
|
||||
# Convert build trace to base64
|
||||
echo "Converting build trace to base64..."
|
||||
BUILD_TRACE_BASE64=$(base64 -w 0 ''' + buildTraceFileName + ''')
|
||||
echo "Build trace base64 length: ${#BUILD_TRACE_BASE64}"
|
||||
|
||||
# Create JSON payload with base64 data
|
||||
echo "Creating JSON payload..."
|
||||
{
|
||||
printf '{\n'
|
||||
printf ' "jobName": "%s",\n' "''' + env.JOB_NAME + '''"
|
||||
printf ' "buildNumber": "%s",\n' "''' + env.BUILD_NUMBER + '''"
|
||||
printf ' "jobUrl": "%s",\n' "''' + env.RUN_DISPLAY_URL + '''"
|
||||
printf ' "imageName": "%s",\n' "''' + imageName + '''"
|
||||
printf ' "imageData": "%s",\n' "$IMAGE_BASE64"
|
||||
printf ' "buildTraceName": "%s",\n' "$BUILD_TRACE_WITH_NUMBER"
|
||||
printf ' "buildTraceData": "%s"\n' "$BUILD_TRACE_BASE64"
|
||||
printf '}\n'
|
||||
} > webhook_payload.json
|
||||
|
||||
echo "JSON payload created, size: $(wc -c < webhook_payload.json) bytes"
|
||||
|
||||
curl -X POST "${WEBHOOK_URL}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d @webhook_payload.json
|
||||
|
||||
# Clean up temporary file
|
||||
rm -f webhook_payload.json
|
||||
'''
|
||||
}
|
||||
} catch (Exception e) {
|
||||
echo "Throwing error exception while generating build trace visualization"
|
||||
echo 'Exception occurred: ' + e.toString()
|
||||
}
|
||||
}
|
||||
|
||||
class Version {
|
||||
int major, minor, patch
|
||||
@Override
|
||||
@@ -1750,6 +1873,15 @@ pipeline {
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
node(rocmnode("nogpu")) {
|
||||
script {
|
||||
// Simulate capture
|
||||
generateAndArchiveBuildTraceVisualization()
|
||||
}
|
||||
cleanWs()
|
||||
}
|
||||
}
|
||||
success {
|
||||
script {
|
||||
// Report the parent stage build ck and run tests status
|
||||
|
||||
53
script/infra_helper/capture_build_trace.js
Normal file
53
script/infra_helper/capture_build_trace.js
Normal file
@@ -0,0 +1,53 @@
|
||||
const puppeteer = require('puppeteer');
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
// Launch the browser
|
||||
const browser = await puppeteer.launch({
|
||||
args: [
|
||||
'--no-sandbox',
|
||||
'--headless',
|
||||
'--disable-gpu',
|
||||
'--window-size=1920x1080'
|
||||
]});
|
||||
const page = await browser.newPage();
|
||||
await page.setViewport({ width: 1920, height: 1080 });
|
||||
await page.goto('https://ui.perfetto.dev');
|
||||
// Wait for the home page to be visible
|
||||
console.log('Waiting for page to load...');
|
||||
await page.waitForSelector('.pf-home-page', { visible: true, timeout: 30000 });
|
||||
// Locate and click the Open trace button
|
||||
const elements = await page.$$('li');
|
||||
let element = null;
|
||||
for (const el of elements) {
|
||||
const text = await el.evaluate(node => node.textContent);
|
||||
if (text && text.includes('Open trace file')) {
|
||||
element = el;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (element) {
|
||||
const [fileChooser] = await Promise.all([
|
||||
page.waitForFileChooser(),
|
||||
element.click()
|
||||
]);
|
||||
await fileChooser.accept(['/workspace/ck_build_trace.json']);
|
||||
} else {
|
||||
throw new Error('Element not found');
|
||||
}
|
||||
console.log('Waiting for data to load...');
|
||||
// Wait for the timeline element to be visible
|
||||
await page.waitForSelector('.pf-track', { timeout: 30000 });
|
||||
// Wait for the data to finish loading
|
||||
await page.waitForFunction(() => {
|
||||
return !document.body.textContent.includes('Loading...');
|
||||
}, { timeout: 30000 });
|
||||
console.log('Capturing screenshot...');
|
||||
await page.screenshot({path: '/workspace/perfetto_snapshot_build.png'});
|
||||
console.log('Done capturing screenshot...');
|
||||
await browser.close();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user