Core functions for cli filesystem scenarios including copy, move, remove, mkdir, and executable discovery operations.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Actions IO provides essential filesystem operations for CLI scenarios and GitHub Actions workflows. It offers TypeScript implementations of common Unix commands with cross-platform compatibility, proper error handling, and async/await support.
npm install @actions/ioimport { cp, mv, rmRF, mkdirP, which, findInPath } from "@actions/io";
import type { CopyOptions, MoveOptions } from "@actions/io";For CommonJS:
const { cp, mv, rmRF, mkdirP, which, findInPath } = require("@actions/io");import { cp, mv, rmRF, mkdirP, which } from "@actions/io";
// Create directories recursively
await mkdirP("path/to/nested/directory");
// Copy files or directories
await cp("source/file.txt", "dest/file.txt");
await cp("source/directory", "dest/directory", { recursive: true });
// Move files or directories
await mv("old/path", "new/path");
// Remove files or directories recursively
await rmRF("path/to/remove");
// Find executables in PATH
const pythonPath = await which("python", true);
console.log(`Python found at: ${pythonPath}`);Actions IO is built around cross-platform filesystem operations:
cp, mv, rm -rf, mkdir -p, and which functionalityCopy files or directories with configurable options for recursion, force overwrite, and source directory handling.
/**
* Copies a file or folder with configurable options
* @param source - Source path to copy from
* @param dest - Destination path to copy to
* @param options - Optional copy configuration
*/
function cp(
source: string,
dest: string,
options: CopyOptions = {}
): Promise<void>;
interface CopyOptions {
/** Whether to recursively copy all subdirectories. Defaults to false */
recursive?: boolean;
/** Whether to overwrite existing files in the destination. Defaults to true */
force?: boolean;
/** Whether to copy the source directory along with all the files. Only takes effect when recursive=true and copying a directory. Default is true */
copySourceDirectory?: boolean;
}Usage Examples:
import { cp } from "@actions/io";
// Copy a single file
await cp("source.txt", "destination.txt");
// Copy a file without overwriting if destination exists
await cp("source.txt", "dest.txt", { force: false });
// Copy directory recursively
await cp("src/", "build/", { recursive: true });
// Copy directory contents without creating source directory at destination
await cp("src/", "build/", {
recursive: true,
copySourceDirectory: false
});Move files or directories to new locations with optional force overwrite.
/**
* Moves a path (file or directory) to a new location
* @param source - Source path to move from
* @param dest - Destination path to move to
* @param options - Optional move configuration
*/
function mv(
source: string,
dest: string,
options: MoveOptions = {}
): Promise<void>;
interface MoveOptions {
/** Whether to overwrite existing files in the destination. Defaults to true */
force?: boolean;
}Usage Examples:
import { mv } from "@actions/io";
// Move a file
await mv("old-name.txt", "new-name.txt");
// Move without overwriting existing destination
await mv("source.txt", "existing-dest.txt", { force: false });
// Move directory
await mv("old-directory/", "new-directory/");Remove files or directories recursively with force, equivalent to rm -rf command.
/**
* Remove a path recursively with force (equivalent to rm -rf)
* @param inputPath - Path to remove
*/
function rmRF(inputPath: string): Promise<void>;Usage Examples:
import { rmRF } from "@actions/io";
// Remove a file
await rmRF("unwanted-file.txt");
// Remove directory and all contents
await rmRF("temp-directory/");
// Remove with special characters (safe on all platforms)
await rmRF("path/with spaces/file.txt");Create directories recursively, equivalent to mkdir -p command.
/**
* Make a directory recursively. Creates the full path with folders in between
* @param fsPath - Path to create
*/
function mkdirP(fsPath: string): Promise<void>;Usage Examples:
import { mkdirP } from "@actions/io";
// Create nested directories
await mkdirP("deeply/nested/directory/structure");
// Create directory (no-op if already exists)
await mkdirP("existing-directory");Find executable files in the system PATH, equivalent to which command.
/**
* Returns path of a tool had the tool actually been invoked. Resolves via paths.
* @param tool - Name of the tool to find
* @param check - Whether to check if tool exists and throw if not found
* @returns Path to tool, or empty string if not found (when check=false)
*/
function which(tool: string, check?: boolean): Promise<string>;Usage Examples:
import { which } from "@actions/io";
// Find tool without throwing if not found
const nodePath = await which("node");
if (nodePath) {
console.log(`Node.js found at: ${nodePath}`);
}
// Find tool and throw error if not found
try {
const pythonPath = await which("python", true);
console.log(`Python found at: ${pythonPath}`);
} catch (error) {
console.error("Python not found in PATH");
}Find all occurrences of an executable in the system PATH.
/**
* Returns a list of all occurrences of the given tool on the system path
* @param tool - Name of the tool to find
* @returns Array of paths where the tool is found
*/
function findInPath(tool: string): Promise<string[]>;Usage Examples:
import { findInPath } from "@actions/io";
// Find all instances of a tool
const pythonPaths = await findInPath("python");
console.log("Python installations found:", pythonPaths);
// Check if tool exists anywhere in PATH
const gccPaths = await findInPath("gcc");
if (gccPaths.length > 0) {
console.log("GCC is available");
}All functions throw descriptive errors for common failure scenarios:
cp and mv throw when source doesn't existcp throws when trying to copy directory without recursive: true*, ", <, >, |which with check: true throws detailed platform-specific error messagesActions IO handles cross-platform differences automatically:
/ and \ appropriately.exe, .cmd, .bat extensions