Comprehensive logging system with multiple severity levels and GitHub Actions annotation support for creating contextual feedback in pull requests and workflow runs. This system provides structured output formatting and integration with GitHub's workflow UI.
Writes debug messages that are only visible when debug logging is enabled via RUNNER_DEBUG=1.
/**
* Writes debug message to user log
* @param message - Debug message to log
*/
function debug(message: string): void;
/**
* Gets whether Actions Step Debug is enabled
* @returns True if debug logging is enabled
*/
function isDebug(): boolean;Usage Examples:
import { debug, isDebug } from '@actions/core';
// Basic debug logging
debug('Starting application initialization');
debug('Loading configuration from environment');
// Conditional debug logging
if (isDebug()) {
debug('Verbose debugging information');
debug(`Current working directory: ${process.cwd()}`);
debug(`Environment variables: ${JSON.stringify(process.env, null, 2)}`);
}
// Debug with structured data
const config = { apiUrl: 'https://api.example.com', timeout: 5000 };
debug(`Configuration loaded: ${JSON.stringify(config)}`);Controls whether commands are echoed to stdout during action execution. Command echoing shows the internal commands being executed by the Actions runner.
/**
* Enables or disables the echoing of commands into stdout for the rest of the step
* @param enabled - True to enable command echoing, false to disable
* @remarks
* Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.
* When enabled, internal runner commands will be visible in workflow logs.
*/
function setCommandEcho(enabled: boolean): void;Usage Examples:
import { setCommandEcho, debug } from '@actions/core';
// Enable command echoing for debugging
setCommandEcho(true);
debug('Commands will now be visible in logs');
// Perform operations with visible commands
// (internal runner commands will be shown)
// Disable command echoing for security
setCommandEcho(false);
debug('Commands are now hidden from logs');
// Conditional command echoing based on debug mode
import { isDebug } from '@actions/core';
if (isDebug()) {
setCommandEcho(true);
debug('Debug mode: enabling command echo');
} else {
setCommandEcho(false);
debug('Production mode: disabling command echo');
}Writes informational messages to the workflow log that are always visible.
/**
* Writes info to log with console.log
* @param message - Info message to log
*/
function info(message: string): void;Usage Examples:
import { info } from '@actions/core';
// Basic info logging
info('Application started successfully');
info('Processing 150 files');
// Progress updates
for (let i = 0; i < files.length; i++) {
if (i % 10 === 0) {
info(`Processed ${i}/${files.length} files`);
}
}
// Status updates
info('Connecting to database...');
info('Database connection established');
info('Running migrations...');
info('All migrations completed successfully');Creates warning annotations that appear in the workflow UI and can be linked to specific files and line numbers.
/**
* Adds a warning issue
* @param message - Warning issue message. Errors will be converted to string via toString()
* @param properties - Optional properties to add to the annotation
*/
function warning(message: string | Error, properties?: AnnotationProperties): void;
interface AnnotationProperties {
/** A title for the annotation */
title?: string;
/** The path of the file for which the annotation should be created */
file?: string;
/** The start line for the annotation */
startLine?: number;
/** The end line for the annotation. Defaults to startLine when startLine is provided */
endLine?: number;
/** The start column for the annotation. Cannot be sent when startLine and endLine are different values */
startColumn?: number;
/** The end column for the annotation. Cannot be sent when startLine and endLine are different values */
endColumn?: number;
}Usage Examples:
import { warning } from '@actions/core';
// Basic warning
warning('Configuration file not found, using defaults');
// Warning with title
warning('Deprecated API usage detected', {
title: 'Deprecation Warning'
});
// File-specific warning
warning('Missing semicolon', {
title: 'Linting Issue',
file: 'src/app.js',
startLine: 42,
startColumn: 25
});
// Multi-line warning
warning('Code block has potential issues', {
title: 'Code Quality',
file: 'src/utils.js',
startLine: 10,
endLine: 15
});
// Warning from Error object
try {
riskyOperation();
} catch (error) {
warning(error, {
title: 'Operation Failed',
file: 'src/operations.js'
});
}Creates error annotations that appear in the workflow UI. Unlike setFailed, these don't automatically fail the action.
/**
* Adds an error issue
* @param message - Error issue message. Errors will be converted to string via toString()
* @param properties - Optional properties to add to the annotation
*/
function error(message: string | Error, properties?: AnnotationProperties): void;Usage Examples:
import { error } from '@actions/core';
// Basic error annotation
error('Failed to parse configuration file');
// Error with file location
error('Syntax error in JavaScript code', {
title: 'Parse Error',
file: 'src/main.js',
startLine: 25,
startColumn: 10
});
// Error from exception
try {
await processFile('invalid-file.json');
} catch (err) {
error(err, {
title: 'File Processing Error',
file: 'invalid-file.json'
});
}
// Multiple errors with context
const errors = validateConfig(config);
errors.forEach((err, index) => {
error(`Validation error ${index + 1}: ${err.message}`, {
title: 'Configuration Validation',
file: 'config.json',
startLine: err.line
});
});Creates informational annotations that appear in the workflow UI for important information that's not an error.
/**
* Adds a notice issue
* @param message - Notice issue message. Errors will be converted to string via toString()
* @param properties - Optional properties to add to the annotation
*/
function notice(message: string | Error, properties?: AnnotationProperties): void;Usage Examples:
import { notice } from '@actions/core';
// Basic notice
notice('Deployment completed successfully to production environment');
// Notice with title
notice('Performance optimization applied', {
title: 'Optimization'
});
// File-specific notice
notice('New dependency added', {
title: 'Dependency Update',
file: 'package.json',
startLine: 15
});
// Success notice with details
notice('All tests passed with 95% code coverage', {
title: 'Test Results',
file: 'coverage/report.txt'
});Sets the action as failed with an error message and exits with code 1.
/**
* Sets the action status to failed
When the action exits it will be with an exit code of 1
* @param message - Error message for the failure
*/
function setFailed(message: string | Error): void;Usage Examples:
import { setFailed, error } from '@actions/core';
// Basic failure
try {
await criticalOperation();
} catch (err) {
setFailed(`Critical operation failed: ${err.message}`);
}
// Conditional failure
const results = await runTests();
if (results.failures > 0) {
setFailed(`Tests failed: ${results.failures} out of ${results.total} tests failed`);
}
// Failure with detailed error logging
try {
await deployApplication();
} catch (deployError) {
// Log detailed error information
error(deployError, {
title: 'Deployment Error',
file: 'deployment.yaml'
});
// Fail the action
setFailed('Deployment failed. See error annotations for details.');
}
// Validation failure
const validationErrors = await validateInputs();
if (validationErrors.length > 0) {
validationErrors.forEach(err => {
error(err.message, {
title: 'Input Validation Error',
file: err.file,
startLine: err.line
});
});
setFailed(`Input validation failed with ${validationErrors.length} errors`);
}import { info, debug, warning, error, setFailed } from '@actions/core';
async function processFiles(files: string[]) {
info(`Starting to process ${files.length} files`);
let processed = 0;
let warnings = 0;
let errors = 0;
for (const file of files) {
try {
debug(`Processing file: ${file}`);
await processFile(file);
processed++;
if (processed % 10 === 0) {
info(`Progress: ${processed}/${files.length} files processed`);
}
} catch (err) {
if (err.severity === 'warning') {
warning(err.message, {
title: 'Processing Warning',
file: file
});
warnings++;
} else {
error(err.message, {
title: 'Processing Error',
file: file
});
errors++;
}
}
}
info(`Processing complete: ${processed} processed, ${warnings} warnings, ${errors} errors`);
if (errors > 0) {
setFailed(`Processing failed with ${errors} errors`);
}
}import { error, warning, notice, setFailed } from '@actions/core';
interface ValidationResult {
isValid: boolean;
errors: Array<{
message: string;
file?: string;
line?: number;
column?: number;
severity: 'error' | 'warning' | 'info';
}>;
}
function reportValidationResults(result: ValidationResult) {
result.errors.forEach(issue => {
const annotation = {
title: `${issue.severity.toUpperCase()}: Validation Issue`,
file: issue.file,
startLine: issue.line,
startColumn: issue.column
};
switch (issue.severity) {
case 'error':
error(issue.message, annotation);
break;
case 'warning':
warning(issue.message, annotation);
break;
case 'info':
notice(issue.message, annotation);
break;
}
});
if (!result.isValid) {
const errorCount = result.errors.filter(e => e.severity === 'error').length;
setFailed(`Validation failed with ${errorCount} errors`);
}
}import { debug, isDebug, info } from '@actions/core';
function performComplexOperation(data: any) {
if (isDebug()) {
debug('=== Complex Operation Debug Info ===');
debug(`Input data: ${JSON.stringify(data, null, 2)}`);
debug(`Memory usage: ${process.memoryUsage().heapUsed / 1024 / 1024} MB`);
debug(`Current time: ${new Date().toISOString()}`);
}
info('Starting complex operation');
// ... perform operation ...
if (isDebug()) {
debug(`Operation completed in ${Date.now() - startTime}ms`);
debug(`Final memory usage: ${process.memoryUsage().heapUsed / 1024 / 1024} MB`);
}
info('Complex operation completed successfully');
}Annotations appear in multiple places:
Annotations with file and line information provide clickable links that navigate directly to the specified location in the code.