CDK for software projects - synthesizes configuration files from well-typed JavaScript/TypeScript definitions.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Unified task system for build processes, testing, and custom workflows. Projen's task system provides a consistent interface for defining and executing project tasks across different project types.
Individual task that can execute shell commands and spawn subtasks.
/**
* Represents a project task with shell commands and subtask execution
* Tasks are the building blocks of project automation
*/
class Task {
constructor(name: string, props?: TaskOptions);
/** Task identifier */
readonly name: string;
/** Working directory for task execution */
readonly cwd?: string;
/** Task description */
readonly description?: string;
/** Environment variables for task */
readonly env?: Record<string, string>;
/** Task steps to execute */
readonly steps: TaskStep[];
/** Add a shell command to execute */
exec(command: string, options?: TaskStepOptions): void;
/** Add a subtask to spawn */
spawn(subtask: string, options?: TaskStepOptions): void;
/** Add a built-in task step */
builtin(name: string): void;
/** Prevent further modifications to the task */
lock(): void;
}
interface TaskOptions {
/** Human-readable description of what the task does */
description?: string;
/** Initial shell command to execute */
exec?: string;
/** List of task steps to perform */
steps?: TaskStep[];
/** Environment variables for the task */
env?: Record<string, string>;
/** Working directory (relative to project root) */
cwd?: string;
/** Condition for task execution */
condition?: string;
}
interface TaskStep {
/** Shell command to execute */
exec?: string;
/** Subtask to spawn */
spawn?: string;
/** Built-in task to execute */
builtin?: string;
/** Environment variables for this step */
env?: Record<string, string>;
/** Working directory for this step */
cwd?: string;
/** Condition for step execution */
condition?: string;
}
interface TaskStepOptions {
/** Environment variables */
env?: Record<string, string>;
/** Working directory */
cwd?: string;
/** Execution condition */
condition?: string;
}Basic Task Usage:
import { Project } from "projen";
const project = new Project({ name: "task-example" });
// Simple task with single command
const buildTask = project.addTask("build", {
description: "Build the project",
exec: "tsc",
});
// Complex task with multiple steps
const testTask = project.addTask("test", {
description: "Run tests with coverage",
});
testTask.exec("npm run lint");
testTask.exec("jest --coverage", {
env: { NODE_ENV: "test" },
});
testTask.spawn("build"); // Run build task first
// Task with conditions
const deployTask = project.addTask("deploy", {
description: "Deploy to production",
condition: "$CI && $BRANCH == 'main'",
});
deployTask.exec("npm run build");
deployTask.exec("aws s3 sync ./dist s3://my-bucket");Central registry for managing all project tasks.
/**
* Task registry for a project - manages all tasks
* Provides methods for adding, removing, and finding tasks
*/
class Tasks extends Component {
constructor(project: Project);
/** All tasks in the project */
readonly all: Task[];
/** Add a new task to the project */
addTask(name: string, props?: TaskOptions): Task;
/** Remove a task from the project */
removeTask(name: string): Task | undefined;
/** Find a task by name */
tryFindTask(name: string): Task | undefined;
/** Check if a task exists */
hasTask(name: string): boolean;
}Tasks Registry Example:
import { Project } from "projen";
const project = new Project({ name: "registry-example" });
// Add multiple related tasks
project.tasks.addTask("clean", {
description: "Clean build artifacts",
exec: "rm -rf dist/",
});
project.tasks.addTask("compile", {
description: "Compile TypeScript",
exec: "tsc",
});
project.tasks.addTask("bundle", {
description: "Bundle application",
exec: "webpack --mode production",
});
// Create composite task
const buildTask = project.tasks.addTask("build", {
description: "Full build process",
});
buildTask.spawn("clean");
buildTask.spawn("compile");
buildTask.spawn("bundle");
// Check if task exists
if (project.tasks.hasTask("test")) {
const testTask = project.tasks.tryFindTask("test");
testTask?.exec("echo 'Running tests'");
}Common built-in tasks available across project types.
/**
* Built-in task steps that are commonly used
* These provide cross-platform functionality
*/
interface BuiltinTasks {
/** Remove files and directories */
"rm": { paths: string[] };
/** Copy files */
"cp": { source: string; target: string };
/** Create directories */
"mkdir": { path: string };
/** Echo text to console */
"echo": { message: string };
}Built-in Tasks Example:
import { Project } from "projen";
const project = new Project({ name: "builtin-example" });
const setupTask = project.addTask("setup", {
description: "Setup project directories",
});
// Use built-in tasks for cross-platform compatibility
setupTask.builtin("mkdir -p dist");
setupTask.builtin("mkdir -p temp");
setupTask.builtin("echo 'Setup complete'");
const cleanTask = project.addTask("clean", {
description: "Clean generated files",
});
cleanTask.builtin("rm -rf dist");
cleanTask.builtin("rm -rf temp");Task execution runtime and environment management.
/**
* Task execution runtime - handles task execution
* Manages environment, logging, and execution context
*/
class TaskRuntime {
constructor(workdir: string, options?: TaskRuntimeOptions);
/** Execute a task by name */
runTask(name: string, args?: string[]): Promise<void>;
/** List all available tasks */
listTasks(): Task[];
/** Get task by name */
tryFindTask(name: string): Task | undefined;
}
interface TaskRuntimeOptions {
/** Environment variables */
env?: Record<string, string>;
/** Logging options */
logging?: LoggerOptions;
/** Parallel task execution */
parallel?: boolean;
}Advanced task configuration and execution patterns.
/**
* Task model for complex task definitions
* Supports conditions, dependencies, and metadata
*/
class TaskModel {
constructor(name: string, definition: TaskDefinition);
readonly name: string;
readonly description?: string;
readonly condition?: string;
readonly dependencies?: string[];
readonly metadata?: Record<string, any>;
}
interface TaskDefinition {
description?: string;
steps: TaskStep[];
condition?: string;
dependencies?: string[];
metadata?: Record<string, any>;
}Advanced Task Example:
import { TypeScriptProject } from "projen";
const project = new TypeScriptProject({
name: "advanced-tasks",
});
// Task with dependencies and conditions
const deployTask = project.addTask("deploy", {
description: "Deploy application to production",
condition: "$CI == 'true' && $BRANCH == 'main'",
});
// Ensure build happens first
deployTask.spawn("build");
// Deploy steps with different conditions
deployTask.exec("echo 'Deploying to staging'", {
condition: "$ENVIRONMENT == 'staging'",
});
deployTask.exec("echo 'Deploying to production'", {
condition: "$ENVIRONMENT == 'production'",
});
// Post-deploy notifications
deployTask.exec("curl -X POST $SLACK_WEBHOOK -d 'Deployment complete'", {
condition: "$SLACK_WEBHOOK",
});
// Task with custom environment
const testTask = project.addTask("test:integration", {
description: "Run integration tests",
env: {
NODE_ENV: "test",
DATABASE_URL: "postgres://localhost:5432/test_db",
},
});
testTask.exec("jest --config jest.integration.config.js");Converting tasks to CI/CD workflows.
/**
* Convert projen tasks to GitHub Actions workflows
* Enables running tasks in CI/CD environments
*/
class TaskWorkflow extends Component {
constructor(github: GitHub, options: TaskWorkflowOptions);
}
interface TaskWorkflowOptions {
/** Task name to convert to workflow */
task: string;
/** Workflow trigger events */
triggers?: WorkflowTriggers;
/** Workflow name */
name?: string;
/** Job configuration */
jobSettings?: JobSettings;
}interface WorkflowTriggers {
/** Push triggers */
push?: {
branches?: string[];
paths?: string[];
};
/** Pull request triggers */
pullRequest?: {
branches?: string[];
paths?: string[];
};
/** Schedule triggers */
schedule?: Array<{
cron: string;
}>;
/** Manual workflow dispatch */
workflowDispatch?: boolean;
}
interface JobSettings {
/** Job runner (ubuntu-latest, windows-latest, etc.) */
runsOn?: string;
/** Job timeout in minutes */
timeoutMinutes?: number;
/** Environment variables */
env?: Record<string, string>;
/** Job permissions */
permissions?: Record<string, string>;
}