mirror of
				https://github.com/docker/build-push-action.git
				synced 2025-11-04 00:10:55 +00:00 
			
		
		
		
	Merge pull request #79 from useblacksmith/wire-metrics
*: report metrics to the VM agent
This commit is contained in:
		
				commit
				
					
						e836937c09
					
				
			
		
					 9 changed files with 1497 additions and 19 deletions
				
			
		
							
								
								
									
										6
									
								
								babel.config.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								babel.config.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					module.exports = {
 | 
				
			||||||
 | 
					  presets: [
 | 
				
			||||||
 | 
					    ['@babel/preset-env', { targets: { node: 'current' } }],
 | 
				
			||||||
 | 
					    '@babel/preset-typescript'
 | 
				
			||||||
 | 
					  ]
 | 
				
			||||||
 | 
					}; 
 | 
				
			||||||
							
								
								
									
										14
									
								
								dist/index.js
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								dist/index.js
									
										
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										2
									
								
								dist/index.js.map
									
										
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								dist/index.js.map
									
										
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| 
						 | 
					@ -6,8 +6,12 @@ const config: Config.InitialOptions = {
 | 
				
			||||||
  testEnvironment: 'node',
 | 
					  testEnvironment: 'node',
 | 
				
			||||||
  testMatch: ['**/*.test.ts'],
 | 
					  testMatch: ['**/*.test.ts'],
 | 
				
			||||||
  transform: {
 | 
					  transform: {
 | 
				
			||||||
    '^.+\\.ts$': 'ts-jest'
 | 
					    '^.+\\.ts$': 'ts-jest',
 | 
				
			||||||
 | 
					    '^.+\\.js$': 'babel-jest'
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  transformIgnorePatterns: [
 | 
				
			||||||
 | 
					    '/node_modules/(?!(@buf|@connectrpc)/)'
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
  verbose: true,
 | 
					  verbose: true,
 | 
				
			||||||
  collectCoverage: true,
 | 
					  collectCoverage: true,
 | 
				
			||||||
  collectCoverageFrom: [
 | 
					  collectCoverageFrom: [
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1435
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										1435
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -27,7 +27,7 @@
 | 
				
			||||||
  "packageManager": "yarn@3.6.3",
 | 
					  "packageManager": "yarn@3.6.3",
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "@actions/core": "^1.10.1",
 | 
					    "@actions/core": "^1.10.1",
 | 
				
			||||||
    "@buf/blacksmith_vm-agent.connectrpc_es": "^1.6.1-20241213043610-906584953dd9.2",
 | 
					    "@buf/blacksmith_vm-agent.connectrpc_es": "^1.6.1-20241220192643-e85a9caa965d.2",
 | 
				
			||||||
    "@connectrpc/connect": "^1.6.1",
 | 
					    "@connectrpc/connect": "^1.6.1",
 | 
				
			||||||
    "@connectrpc/connect-node": "^1.6.1",
 | 
					    "@connectrpc/connect-node": "^1.6.1",
 | 
				
			||||||
    "@docker/actions-toolkit": "0.37.1",
 | 
					    "@docker/actions-toolkit": "0.37.1",
 | 
				
			||||||
| 
						 | 
					@ -38,11 +38,15 @@
 | 
				
			||||||
    "portfinder": "^1.0.32"
 | 
					    "portfinder": "^1.0.32"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
 | 
					    "@babel/core": "^7.26.0",
 | 
				
			||||||
 | 
					    "@babel/preset-env": "^7.26.0",
 | 
				
			||||||
 | 
					    "@babel/preset-typescript": "^7.26.0",
 | 
				
			||||||
    "@types/jest": "^29.5.14",
 | 
					    "@types/jest": "^29.5.14",
 | 
				
			||||||
    "@types/node": "^20.12.12",
 | 
					    "@types/node": "^20.12.12",
 | 
				
			||||||
    "@typescript-eslint/eslint-plugin": "^7.9.0",
 | 
					    "@typescript-eslint/eslint-plugin": "^7.9.0",
 | 
				
			||||||
    "@typescript-eslint/parser": "^7.9.0",
 | 
					    "@typescript-eslint/parser": "^7.9.0",
 | 
				
			||||||
    "@vercel/ncc": "^0.38.1",
 | 
					    "@vercel/ncc": "^0.38.1",
 | 
				
			||||||
 | 
					    "babel-jest": "^29.7.0",
 | 
				
			||||||
    "eslint": "^8.57.0",
 | 
					    "eslint": "^8.57.0",
 | 
				
			||||||
    "eslint-config-prettier": "^9.1.0",
 | 
					    "eslint-config-prettier": "^9.1.0",
 | 
				
			||||||
    "eslint-plugin-jest": "^28.5.0",
 | 
					    "eslint-plugin-jest": "^28.5.0",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,6 +3,7 @@ import * as main from '../main';
 | 
				
			||||||
import * as reporter from '../reporter';
 | 
					import * as reporter from '../reporter';
 | 
				
			||||||
import {getDockerfilePath} from '../context';
 | 
					import {getDockerfilePath} from '../context';
 | 
				
			||||||
import * as setupBuilder from '../setup_builder';
 | 
					import * as setupBuilder from '../setup_builder';
 | 
				
			||||||
 | 
					import { Metric_MetricType } from "@buf/blacksmith_vm-agent.bufbuild_es/stickydisk/v1/stickydisk_pb";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
jest.mock('@actions/core', () => ({
 | 
					jest.mock('@actions/core', () => ({
 | 
				
			||||||
  debug: jest.fn(),
 | 
					  debug: jest.fn(),
 | 
				
			||||||
| 
						 | 
					@ -20,9 +21,14 @@ jest.mock('../context', () => ({
 | 
				
			||||||
  Inputs: jest.fn()
 | 
					  Inputs: jest.fn()
 | 
				
			||||||
}));
 | 
					}));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
jest.mock('../reporter', () => ({
 | 
					jest.mock('../reporter', () => {
 | 
				
			||||||
  reportBuildPushActionFailure: jest.fn().mockResolvedValue(undefined)
 | 
					  const actual = jest.requireActual('../reporter');
 | 
				
			||||||
}));
 | 
					  return {
 | 
				
			||||||
 | 
					    ...actual,
 | 
				
			||||||
 | 
					    reportBuildPushActionFailure: jest.fn().mockResolvedValue(undefined),
 | 
				
			||||||
 | 
					    reportMetric: jest.fn().mockImplementation((type: Metric_MetricType) => Promise.resolve())
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
jest.mock('../setup_builder', () => ({
 | 
					jest.mock('../setup_builder', () => ({
 | 
				
			||||||
  ...jest.requireActual('../setup_builder'),
 | 
					  ...jest.requireActual('../setup_builder'),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										12
									
								
								src/main.ts
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								src/main.ts
									
										
									
									
									
								
							| 
						 | 
					@ -21,6 +21,7 @@ import {promisify} from 'util';
 | 
				
			||||||
import {exec} from 'child_process';
 | 
					import {exec} from 'child_process';
 | 
				
			||||||
import * as reporter from './reporter';
 | 
					import * as reporter from './reporter';
 | 
				
			||||||
import {setupStickyDisk, startAndConfigureBuildkitd, getNumCPUs} from './setup_builder';
 | 
					import {setupStickyDisk, startAndConfigureBuildkitd, getNumCPUs} from './setup_builder';
 | 
				
			||||||
 | 
					import { Metric, Metric_MetricType } from "@buf/blacksmith_vm-agent.bufbuild_es/stickydisk/v1/stickydisk_pb";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const buildxVersion = 'v0.17.0';
 | 
					const buildxVersion = 'v0.17.0';
 | 
				
			||||||
const mountPoint = '/var/lib/buildkit';
 | 
					const mountPoint = '/var/lib/buildkit';
 | 
				
			||||||
| 
						 | 
					@ -73,9 +74,16 @@ export async function startBlacksmithBuilder(inputs: context.Inputs): Promise<{a
 | 
				
			||||||
    if (!dockerfilePath) {
 | 
					    if (!dockerfilePath) {
 | 
				
			||||||
      throw new Error('Failed to resolve dockerfile path');
 | 
					      throw new Error('Failed to resolve dockerfile path');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    const stickyDiskStartTime = Date.now();
 | 
				
			||||||
    const stickyDiskSetup = await setupStickyDisk(dockerfilePath);
 | 
					    const stickyDiskSetup = await setupStickyDisk(dockerfilePath);
 | 
				
			||||||
 | 
					    const stickyDiskDurationMs = Date.now() - stickyDiskStartTime;
 | 
				
			||||||
 | 
					    await reporter.reportMetric(Metric_MetricType.BPA_HOTLOAD_DURATION_MS, stickyDiskDurationMs);
 | 
				
			||||||
    const parallelism = await getNumCPUs();
 | 
					    const parallelism = await getNumCPUs();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const buildkitdStartTime = Date.now();
 | 
				
			||||||
    const buildkitdAddr = await startAndConfigureBuildkitd(parallelism, stickyDiskSetup.device);
 | 
					    const buildkitdAddr = await startAndConfigureBuildkitd(parallelism, stickyDiskSetup.device);
 | 
				
			||||||
 | 
					    const buildkitdDurationMs = Date.now() - buildkitdStartTime;
 | 
				
			||||||
 | 
					    await reporter.reportMetric(Metric_MetricType.BPA_BUILDKITD_READY_DURATION_MS, buildkitdDurationMs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return {addr: buildkitdAddr, buildId: stickyDiskSetup.buildId || null, exposeId: stickyDiskSetup.exposeId};
 | 
					    return {addr: buildkitdAddr, buildId: stickyDiskSetup.buildId || null, exposeId: stickyDiskSetup.exposeId};
 | 
				
			||||||
  } catch (error) {
 | 
					  } catch (error) {
 | 
				
			||||||
| 
						 | 
					@ -100,6 +108,7 @@ export async function startBlacksmithBuilder(inputs: context.Inputs): Promise<{a
 | 
				
			||||||
actionsToolkit.run(
 | 
					actionsToolkit.run(
 | 
				
			||||||
  // main
 | 
					  // main
 | 
				
			||||||
  async () => {
 | 
					  async () => {
 | 
				
			||||||
 | 
					    await reporter.reportMetric(Metric_MetricType.BPA_FEATURE_USAGE, 1);
 | 
				
			||||||
    const startedTime = new Date();
 | 
					    const startedTime = new Date();
 | 
				
			||||||
    const inputs: context.Inputs = await context.getInputs();
 | 
					    const inputs: context.Inputs = await context.getInputs();
 | 
				
			||||||
    stateHelper.setInputs(inputs);
 | 
					    stateHelper.setInputs(inputs);
 | 
				
			||||||
| 
						 | 
					@ -317,7 +326,10 @@ actionsToolkit.run(
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
          const {stdout} = await execAsync('pgrep buildkitd');
 | 
					          const {stdout} = await execAsync('pgrep buildkitd');
 | 
				
			||||||
          if (stdout.trim()) {
 | 
					          if (stdout.trim()) {
 | 
				
			||||||
 | 
					            const buildkitdShutdownStartTime = Date.now();
 | 
				
			||||||
            await shutdownBuildkitd();
 | 
					            await shutdownBuildkitd();
 | 
				
			||||||
 | 
					            const buildkitdShutdownDurationMs = Date.now() - buildkitdShutdownStartTime;
 | 
				
			||||||
 | 
					            await reporter.reportMetric(Metric_MetricType.BPA_BUILDKITD_SHUTDOWN_DURATION_MS, buildkitdShutdownDurationMs);
 | 
				
			||||||
            core.info('Shutdown buildkitd');
 | 
					            core.info('Shutdown buildkitd');
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        } catch (error) {
 | 
					        } catch (error) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,7 @@ import FormData from 'form-data';
 | 
				
			||||||
import { createClient } from "@connectrpc/connect";
 | 
					import { createClient } from "@connectrpc/connect";
 | 
				
			||||||
import { createGrpcTransport } from "@connectrpc/connect-node";
 | 
					import { createGrpcTransport } from "@connectrpc/connect-node";
 | 
				
			||||||
import { StickyDiskService } from "@buf/blacksmith_vm-agent.connectrpc_es/stickydisk/v1/stickydisk_connect";
 | 
					import { StickyDiskService } from "@buf/blacksmith_vm-agent.connectrpc_es/stickydisk/v1/stickydisk_connect";
 | 
				
			||||||
 | 
					import { Metric, Metric_MetricType } from "@buf/blacksmith_vm-agent.bufbuild_es/stickydisk/v1/stickydisk_pb";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Configure base axios instance for Blacksmith API.
 | 
					// Configure base axios instance for Blacksmith API.
 | 
				
			||||||
const createBlacksmithAPIClient = () => {
 | 
					const createBlacksmithAPIClient = () => {
 | 
				
			||||||
| 
						 | 
					@ -175,3 +176,25 @@ export async function post(client: AxiosInstance, url: string, formData: FormDat
 | 
				
			||||||
    signal: options?.signal
 | 
					    signal: options?.signal
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function reportMetric(
 | 
				
			||||||
 | 
					  metricType: Metric_MetricType,
 | 
				
			||||||
 | 
					  value: number
 | 
				
			||||||
 | 
					): Promise<void> {
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    const agentClient = createBlacksmithAgentClient();
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    const metric = new Metric({
 | 
				
			||||||
 | 
					      type: metricType,
 | 
				
			||||||
 | 
					      value: { case: "intValue", value: BigInt(value) }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await agentClient.reportMetric({
 | 
				
			||||||
 | 
					      repoName: process.env.GITHUB_REPO_NAME || '',
 | 
				
			||||||
 | 
					      region: process.env.BLACKSMITH_REGION || 'eu-central',
 | 
				
			||||||
 | 
					      metric: metric
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  } catch (error) {
 | 
				
			||||||
 | 
					    core.warning('Error reporting metric to BlacksmithAgent:', error);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue