Runtime environment detection and system information gathering for platform-specific logic. This module provides utilities to detect the operating system, architecture, and detailed system information, enabling actions to adapt their behavior based on the execution environment.
The platform detection utilities help you write actions that work correctly across GitHub's hosted runners (Windows, macOS, Linux) and self-hosted runners with different configurations. You can use these utilities to conditionally execute platform-specific code, select appropriate tools, or adjust behavior based on the runtime environment.
Basic platform detection constants that identify the current operating system.
/**
* Platform detection constants
*/
namespace platform {
/** Current platform string (equivalent to os.platform()) */
const platform: string;
/** Current architecture string (equivalent to os.arch()) */
const arch: string;
/** True if running on Windows platform */
const isWindows: boolean;
/** True if running on macOS platform */
const isMacOS: boolean;
/** True if running on Linux platform */
const isLinux: boolean;
}Usage Examples:
import { platform } from '@actions/core';
// Check current platform
console.log(`Running on: ${platform.platform}`); // 'win32', 'darwin', 'linux', etc.
console.log(`Architecture: ${platform.arch}`); // 'x64', 'arm64', etc.
// Platform-specific logic
if (platform.isWindows) {
console.log('Executing Windows-specific code');
await runWindowsCommand();
} else if (platform.isMacOS) {
console.log('Executing macOS-specific code');
await runMacCommand();
} else if (platform.isLinux) {
console.log('Executing Linux-specific code');
await runLinuxCommand();
}
// Architecture-specific logic
if (platform.arch === 'arm64') {
console.log('Running on ARM64 architecture');
await downloadArmBinary();
} else if (platform.arch === 'x64') {
console.log('Running on x64 architecture');
await downloadX64Binary();
}Get comprehensive system information including OS name, version, and all platform detection flags.
/**
* Get detailed platform information
* @returns Promise resolving to detailed platform information
*/
function getDetails(): Promise<PlatformDetails>;
interface PlatformDetails {
/** Human-readable OS name */
name: string;
/** Platform identifier */
platform: string;
/** System architecture */
arch: string;
/** OS version */
version: string;
/** True if running on Windows */
isWindows: boolean;
/** True if running on macOS */
isMacOS: boolean;
/** True if running on Linux */
isLinux: boolean;
}Usage Examples:
import { platform } from '@actions/core';
// Get detailed system information
const details = await platform.getDetails();
console.log(`OS Name: ${details.name}`);
console.log(`Platform: ${details.platform}`);
console.log(`Architecture: ${details.arch}`);
console.log(`Version: ${details.version}`);
// Example outputs:
// Windows: name="Microsoft Windows Server 2022", version="10.0.20348"
// macOS: name="macOS", version="12.6.1"
// Linux: name="Ubuntu", version="20.04"
// Use detailed info for compatibility checks
if (details.isWindows && parseFloat(details.version.split('.')[0]) >= 10) {
console.log('Windows 10+ detected, using modern APIs');
} else if (details.isMacOS && details.version >= '12.0') {
console.log('macOS Monterey+ detected');
} else if (details.isLinux && details.name.includes('Ubuntu')) {
console.log(`Ubuntu ${details.version} detected`);
}import { platform, info, exec } from '@actions/core';
async function installTools() {
const details = await platform.getDetails();
info(`Installing tools for ${details.name} ${details.version}`);
if (platform.isWindows) {
// Install tools via Chocolatey or direct download
await exec.exec('choco', ['install', 'nodejs', 'git', '-y']);
// Windows-specific configuration
await exec.exec('setx', ['PATH', '%PATH%;C:\\Tools\\bin']);
} else if (platform.isMacOS) {
// Install tools via Homebrew
await exec.exec('brew', ['install', 'node', 'git']);
// macOS-specific configuration
if (platform.arch === 'arm64') {
info('Configuring for Apple Silicon');
await exec.exec('arch', ['-arm64', 'brew', 'install', 'native-tools']);
}
} else if (platform.isLinux) {
// Install tools via package manager
if (details.name.includes('Ubuntu') || details.name.includes('Debian')) {
await exec.exec('sudo', ['apt-get', 'update']);
await exec.exec('sudo', ['apt-get', 'install', '-y', 'nodejs', 'git']);
} else if (details.name.includes('CentOS') || details.name.includes('Red Hat')) {
await exec.exec('sudo', ['yum', 'install', '-y', 'nodejs', 'git']);
}
}
info('Tool installation completed');
}import { platform, toPlatformPath, info } from '@actions/core';
import * as path from 'path';
async function setupPaths() {
const details = await platform.getDetails();
let configDir: string;
let dataDir: string;
let executableExt: string;
if (platform.isWindows) {
configDir = path.join(process.env.APPDATA || 'C:\\Users\\Default\\AppData\\Roaming', 'MyApp');
dataDir = path.join(process.env.LOCALAPPDATA || 'C:\\Users\\Default\\AppData\\Local', 'MyApp');
executableExt = '.exe';
// Windows-specific permissions
await exec.exec('icacls', [configDir, '/grant', 'Everyone:F']);
} else if (platform.isMacOS) {
const homeDir = process.env.HOME || '/Users/runner';
configDir = path.join(homeDir, 'Library', 'Preferences', 'MyApp');
dataDir = path.join(homeDir, 'Library', 'Application Support', 'MyApp');
executableExt = '';
// macOS-specific permissions
await exec.exec('chmod', ['755', configDir]);
} else if (platform.isLinux) {
const homeDir = process.env.HOME || '/home/runner';
configDir = path.join(homeDir, '.config', 'myapp');
dataDir = path.join(homeDir, '.local', 'share', 'myapp');
executableExt = '';
// Linux-specific permissions
await exec.exec('chmod', ['755', configDir]);
}
// Create directories
await fs.promises.mkdir(configDir, { recursive: true });
await fs.promises.mkdir(dataDir, { recursive: true });
info(`Configuration directory: ${configDir}`);
info(`Data directory: ${dataDir}`);
info(`Executable extension: ${executableExt || 'none'}`);
return { configDir, dataDir, executableExt };
}import { platform, info } from '@actions/core';
async function optimizeForPlatform() {
const details = await platform.getDetails();
let workerCount: number;
let memoryLimit: string;
let useNativeModules: boolean;
if (platform.isWindows) {
// Windows optimization
workerCount = Math.max(1, os.cpus().length - 1); // Leave one core free
memoryLimit = '4GB';
useNativeModules = details.version.includes('Server'); // Only on Server editions
info('Optimizing for Windows environment');
} else if (platform.isMacOS) {
// macOS optimization
workerCount = os.cpus().length; // macOS handles scheduling well
memoryLimit = platform.arch === 'arm64' ? '8GB' : '4GB'; // M1/M2 have more memory
useNativeModules = true; // Usually have development tools
info(`Optimizing for macOS ${platform.arch === 'arm64' ? 'Apple Silicon' : 'Intel'}`);
} else if (platform.isLinux) {
// Linux optimization
workerCount = Math.min(os.cpus().length, 4); // Conservative on Linux
memoryLimit = '2GB'; // GitHub runners have limited memory
useNativeModules = true; // Usually have build tools
info('Optimizing for Linux environment');
}
// Apply optimizations
process.env.UV_THREADPOOL_SIZE = workerCount.toString();
process.env.NODE_OPTIONS = `--max-old-space-size=${parseInt(memoryLimit) * 1024}`;
return { workerCount, memoryLimit, useNativeModules };
}import { platform, exec, info } from '@actions/core';
async function runCommand(command: string, args: string[] = []) {
const details = await platform.getDetails();
if (platform.isWindows) {
// Use PowerShell for complex commands on Windows
const psCommand = `${command} ${args.join(' ')}`;
await exec.exec('powershell', ['-Command', psCommand]);
} else {
// Direct execution on Unix-like systems
await exec.exec(command, args);
}
}
async function getSystemInfo() {
const details = await platform.getDetails();
const systemInfo: any = {};
if (platform.isWindows) {
// Windows system information
const { stdout: computerInfo } = await exec.getExecOutput(
'powershell',
['-Command', 'Get-ComputerInfo | ConvertTo-Json']
);
systemInfo.computer = JSON.parse(computerInfo);
const { stdout: diskInfo } = await exec.getExecOutput(
'powershell',
['-Command', 'Get-WmiObject -Class Win32_LogicalDisk | ConvertTo-Json']
);
systemInfo.disks = JSON.parse(diskInfo);
} else if (platform.isMacOS) {
// macOS system information
const { stdout: hwInfo } = await exec.getExecOutput('system_profiler', ['SPHardwareDataType', '-json']);
systemInfo.hardware = JSON.parse(hwInfo);
const { stdout: diskInfo } = await exec.getExecOutput('df', ['-h']);
systemInfo.disks = diskInfo;
} else if (platform.isLinux) {
// Linux system information
const { stdout: cpuInfo } = await exec.getExecOutput('lscpu', ['-J']);
systemInfo.cpu = JSON.parse(cpuInfo);
const { stdout: memInfo } = await exec.getExecOutput('cat', ['/proc/meminfo']);
systemInfo.memory = memInfo;
const { stdout: diskInfo } = await exec.getExecOutput('df', ['-h']);
systemInfo.disks = diskInfo;
}
return systemInfo;
}import { platform, info, getInput } from '@actions/core';
async function detectRunnerEnvironment() {
const details = await platform.getDetails();
const isGitHubHosted = process.env.GITHUB_ACTIONS === 'true' &&
process.env.RUNNER_ENVIRONMENT === 'github-hosted';
info(`Platform: ${details.platform}`);
info(`Architecture: ${details.arch}`);
info(`OS: ${details.name} ${details.version}`);
info(`Runner Type: ${isGitHubHosted ? 'GitHub-hosted' : 'Self-hosted'}`);
// GitHub-hosted runner specifics
if (isGitHubHosted) {
const runnerImageVersion = process.env.ImageVersion;
const runnerOS = process.env.ImageOS;
info(`Runner Image: ${runnerOS} ${runnerImageVersion}`);
// Optimize for GitHub-hosted runners
if (platform.isLinux) {
info('GitHub-hosted Linux runner detected');
// Use optimizations specific to GitHub's Linux environment
} else if (platform.isWindows) {
info('GitHub-hosted Windows runner detected');
// Use optimizations specific to GitHub's Windows environment
} else if (platform.isMacOS) {
info('GitHub-hosted macOS runner detected');
// Use optimizations specific to GitHub's macOS environment
}
} else {
info('Self-hosted runner detected - using conservative settings');
}
return {
platform: details.platform,
arch: details.arch,
osName: details.name,
osVersion: details.version,
isGitHubHosted,
runnerImage: process.env.ImageOS,
imageVersion: process.env.ImageVersion
};
}import { platform, warning, setFailed, info } from '@actions/core';
async function checkCompatibility() {
const details = await platform.getDetails();
const issues: string[] = [];
// Check minimum OS versions
if (platform.isWindows) {
const version = parseFloat(details.version.split('.')[0]);
if (version < 10) {
issues.push(`Windows ${version} is not supported. Minimum version: Windows 10`);
}
if (platform.arch !== 'x64') {
issues.push(`Windows ${platform.arch} architecture is not supported`);
}
} else if (platform.isMacOS) {
const majorVersion = parseInt(details.version.split('.')[0]);
if (majorVersion < 11) {
issues.push(`macOS ${details.version} is not supported. Minimum version: macOS 11`);
}
} else if (platform.isLinux) {
if (details.name.includes('Ubuntu')) {
const version = parseFloat(details.version);
if (version < 18.04) {
issues.push(`Ubuntu ${details.version} is not supported. Minimum version: Ubuntu 18.04`);
}
} else if (!details.name.includes('Ubuntu') && !details.name.includes('Debian')) {
warning(`Untested Linux distribution: ${details.name}. Results may vary.`);
}
}
// Check architecture support
if (!['x64', 'arm64'].includes(platform.arch)) {
issues.push(`Unsupported architecture: ${platform.arch}`);
}
// Report issues
if (issues.length > 0) {
for (const issue of issues) {
warning(issue);
}
setFailed(`Compatibility check failed: ${issues.length} issues found`);
} else {
info(`Compatibility check passed for ${details.name} ${details.version} ${platform.arch}`);
}
return issues.length === 0;
}import { platform, info, warning } from '@actions/core';
import * as os from 'os';
async function monitorResources() {
const details = await platform.getDetails();
// Memory monitoring
const totalMemory = os.totalmem();
const freeMemory = os.freemem();
const usedMemory = totalMemory - freeMemory;
const memoryUsagePercent = (usedMemory / totalMemory) * 100;
info(`Memory: ${Math.round(usedMemory / 1024 / 1024)}MB / ${Math.round(totalMemory / 1024 / 1024)}MB (${memoryUsagePercent.toFixed(1)}%)`);
if (memoryUsagePercent > 90) {
warning('High memory usage detected');
}
// CPU monitoring
const cpus = os.cpus();
info(`CPUs: ${cpus.length}x ${cpus[0].model}`);
// Platform-specific monitoring
if (platform.isLinux) {
try {
const { stdout } = await exec.getExecOutput('cat', ['/proc/loadavg']);
const loadAvg = stdout.trim().split(' ').slice(0, 3);
info(`Load Average: ${loadAvg.join(', ')}`);
if (parseFloat(loadAvg[0]) > cpus.length) {
warning('High system load detected');
}
} catch (error) {
// Load average not available
}
}
return {
platform: details.platform,
totalMemoryMB: Math.round(totalMemory / 1024 / 1024),
usedMemoryMB: Math.round(usedMemory / 1024 / 1024),
memoryUsagePercent: memoryUsagePercent,
cpuCount: cpus.length,
cpuModel: cpus[0].model
};
}x64 (Intel/AMD 64-bit): Most common architecturearm64 (ARM 64-bit): Apple Silicon Macs, some Linux systems