or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

environment-state.mdindex.mdinput-output.mdjob-summaries.mdlogging-annotations.mdoidc-tokens.mdoutput-grouping.mdpath-utilities.mdplatform-detection.md
tile.json

logging-annotations.mddocs/

Logging and Annotations

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.

Capabilities

Debug Logging

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)}`);

Command Echo Control

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');
}

Info Logging

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');

Warning Annotations

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'
  });
}

Error Annotations

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
  });
});

Notice Annotations

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'
});

Set Failed

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`);
}

Common Patterns

Progressive Logging

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`);
  }
}

Structured Error Reporting

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`);
  }
}

Debug Context Logging

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');
}

Annotation Display

Annotations appear in multiple places:

  • Workflow run summary: All annotations are listed with their severity
  • Pull request checks: Annotations appear as line comments on relevant files
  • Actions tab: Annotations are shown in the workflow execution details
  • Email notifications: Error annotations may be included in failure notifications

Annotations with file and line information provide clickable links that navigate directly to the specified location in the code.