or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cli-commands.mddangerfile-api.mdgit-utilities.mdgithub-integration.mdindex.mdplatform-integrations.md
tile.json

dangerfile-api.mddocs/

Dangerfile API

The core API available in Dangerfiles for creating custom rules and automations. Dangerfiles have access to global functions and objects that are injected into the runtime.

Capabilities

Global Messaging Functions

Functions for reporting issues and providing feedback in pull requests.

fail

Reports critical issues that should fail the CI build.

/**
 * Highlights critical issues. Message is shown inside a HTML table.
 * @param message - The markdown string to output
 * @param file - Optional file path to attach the message to
 * @param line - Optional line number to attach the message to
 */
declare function fail(message: MarkdownString, file?: string, line?: number): void;

Usage Examples:

// Basic failure
fail("Missing unit tests for new functionality");

// File-specific failure
fail("This file contains a security vulnerability", "src/auth.ts");

// Line-specific failure
fail("Hardcoded password found", "src/config.ts", 42);

warn

Reports warnings that don't fail the build but should be addressed.

/**
 * Highlights low-priority issues. Message is shown inside a HTML table.
 * @param message - The markdown string to output
 * @param file - Optional file path to attach the message to
 * @param line - Optional line number to attach the message to
 */
declare function warn(message: MarkdownString, file?: string, line?: number): void;

Usage Examples:

// Basic warning
warn("This PR is quite large, consider breaking it up");

// File-specific warning
warn("Consider adding JSDoc comments", "src/utils.ts");

message

Reports informational messages and general feedback.

/**
 * Adds a message to the Danger table with custom icon support.
 * @param message - The markdown string to output
 * @param file - Optional file path to attach the message to
 * @param line - Optional line number to attach the message to
 */
declare function message(message: MarkdownString, file?: string, line?: number): void;

/**
 * Adds a message with custom options including icon.
 * @param message - The markdown string to output
 * @param opts - Options object with file, line, and icon
 */
declare function message(message: MarkdownString, opts?: {
  file?: string;
  line?: number;
  icon?: MarkdownString;
}): void;

Usage Examples:

// Basic message
message("Great job on the comprehensive tests!");

// With custom icon
message("Performance looks good! πŸš€", { icon: "⚑" });

// File-specific with icon
message("Nice refactoring!", {
  file: "src/components/Button.tsx",
  icon: "✨"
});

markdown

Adds raw markdown content below the Danger table.

/**
 * Adds raw markdown into the Danger comment, under the table.
 * @param message - The markdown string to output
 * @param file - Optional file path to attach the message to
 * @param line - Optional line number to attach the message to
 */
declare function markdown(message: MarkdownString, file?: string, line?: number): void;

Usage Examples:

// Add formatted table
markdown(`
## Test Coverage Report
| File | Coverage |
|------|----------|
| auth.ts | 95% |
| utils.ts | 87% |
`);

// Add charts or complex formatting
markdown(`
### Build Size Analysis
![Bundle Size Chart](https://example.com/chart.png)
`);

Async Execution

schedule

Schedules asynchronous operations to run after the main Dangerfile execution.

/**
 * Schedules a function to run asynchronously after Dangerfile evaluation.
 * @param asyncFunction - Promise or callback function to execute
 */
declare function schedule(asyncFunction: Scheduleable): void;

type Scheduleable = Promise<any> | Promise<void> | CallbackableFn;
type CallbackableFn = (callback: (done: any) => void) => void;

Usage Examples:

// Schedule async API calls
schedule(async () => {
  const coverage = await fetchCoverageReport();
  if (coverage < 80) {
    warn(`Code coverage is ${coverage}%, target is 80%`);
  }
});

// Schedule with callback style
schedule((callback) => {
  performLongRunningTask((result) => {
    if (result.hasIssues) {
      fail("Long running task found issues");
    }
    callback("done");
  });
});

// Multiple scheduled operations
schedule(async () => {
  const [lint, test, security] = await Promise.all([
    runLintCheck(),
    runTestSuite(),
    runSecurityScan()
  ]);
  
  if (lint.errors > 0) fail(`${lint.errors} lint errors found`);
  if (test.failed > 0) fail(`${test.failed} tests failed`);
  if (security.vulnerabilities > 0) warn(`${security.vulnerabilities} security issues`);
});

Global Objects

danger

The main DSL object containing all metadata and platform-specific information.

/**
 * The root Danger object containing all metadata for introspection
 */
declare const danger: DangerDSLType;

interface DangerDSLType {
  readonly git: GitDSL;
  readonly github: GitHubDSL;
  readonly gitlab: GitLabDSL;
  readonly bitbucket_server: BitBucketServerDSL;
  readonly bitbucket_cloud: BitBucketCloudDSL;
  readonly utils: DangerUtilsDSL;
}

results

Access to current Danger run results for introspection.

/**
 * The current results of a Danger run for introspection
 */
declare const results: DangerRuntimeContainer;

interface DangerRuntimeContainer extends DangerResults {
  scheduled?: any[];
}

interface DangerResults {
  fails: Violation[];
  warnings: Violation[];
  messages: Violation[];
  markdowns: Violation[];
  github?: {
    stepSummary?: string;
  };
  meta?: {
    runtimeName: string;
    runtimeHref: string;
  };
}

Usage Examples:

// Check if build is already failing
if (results.fails.length > 0) {
  message("Build is already failing, skipping additional checks");
} else {
  // Run expensive checks only if no failures yet
  schedule(async () => {
    await runExpensiveAnalysis();
  });
}

// Add metadata to results
results.meta = {
  runtimeName: "Custom Danger Rules",
  runtimeHref: "https://github.com/company/danger-rules"
};

peril (Peril-specific)

Extended DSL available when running under Peril for scheduled tasks and environment access.

/**
 * Extended Peril interface for scheduled tasks and environment access
 */
declare const peril: PerilDSL;

interface PerilDSL {
  env: any;
  runTask: (taskName: string, time: string, data: any) => void;
  data?: any;
}

Usage Examples:

// Access Peril environment variables
const slackWebhook = peril.env.SLACK_WEBHOOK_URL;

// Schedule follow-up task
peril.runTask("reminder_pr_merge", "in 2 days", {
  prNumber: danger.github.pr.number,
  author: danger.github.pr.user.login
});

// Access task data
if (peril.data) {
  message(`Reminder: This PR has been open for ${peril.data.days} days`);
}

Universal Utilities

danger.utils

Utility functions available across all platforms.

interface DangerUtilsDSL {
  href: (href: string, text: string) => string | null;
  sentence: (array: string[]) => string;
  compliment: () => string;
}

href

Creates HTML links with null safety.

/**
 * Creates a link using HTML with null safety.
 * @param href - The HTML link's destination
 * @param text - The HTML link's text
 * @returns HTML <a> tag or null if inputs are invalid
 */
href(href: string, text: string): string | null;

Usage Examples:

// Create file links
const fileLink = danger.utils.href(
  "https://github.com/owner/repo/blob/main/src/file.ts",
  "src/file.ts"
);
message(`Changes needed in ${fileLink}`);

// Handle null safety
const link = danger.utils.href("", "empty href"); // returns null
if (link) {
  message(link);
}

sentence

Converts arrays to human-readable sentences.

/**
 * Converts an array of strings into a sentence.
 * @param array - The array of strings
 * @returns Formatted sentence string
 */
sentence(array: string[]): string;

Usage Examples:

const modifiedFiles = ["package.json", "yarn.lock", "README.md"];
const sentence = danger.utils.sentence(modifiedFiles);
message(`Modified files: ${sentence}`);
// Output: "Modified files: package.json, yarn.lock and README.md"

// Handle different array sizes
danger.utils.sentence(["one"]); // "one"
danger.utils.sentence(["one", "two"]); // "one and two"
danger.utils.sentence(["one", "two", "three"]); // "one, two and three"

compliment

Returns a random complimentary phrase for positive feedback.

/**
 * Returns a random compliment from a predefined list.
 * @returns A random complimentary string
 */
compliment(): string;

Usage Examples:

// Celebrate successful builds
if (results.fails.length === 0 && results.warnings.length === 0) {
  message(`${danger.utils.compliment()} All checks passed!`);
}

// Random positive feedback
const praise = danger.utils.compliment();
message(`${praise} Great work on this PR!`);
// Possible outputs: "Well done.", "Congrats.", "Woo!", "Yay.", etc.

Type Definitions

Core Types

type MarkdownString = string;

interface Violation {
  message: string;
  file?: string;
  line?: number;
  icon?: string; // Only valid for messages
}

Advanced Patterns

Conditional Logic Based on Platform

// Platform-specific logic
if (danger.github) {
  // GitHub-specific rules
  if (danger.github.pr.draft) {
    message("This is a draft PR");
  }
} else if (danger.gitlab) {
  // GitLab-specific rules
  if (danger.gitlab.mr.work_in_progress) {
    message("This is a work in progress MR");
  }
}

Combining Multiple Checks

const hasPackageChanges = danger.git.modified_files.includes("package.json");
const hasLockFileChanges = danger.git.modified_files.includes("yarn.lock");

if (hasPackageChanges && !hasLockFileChanges) {
  fail("package.json was modified but yarn.lock was not updated. Run `yarn install`.");
}

if (!hasPackageChanges && hasLockFileChanges) {
  warn("yarn.lock was modified but package.json was not. This might indicate a merge conflict.");
}

Async Rule Composition

// Compose multiple async checks
const runAllChecks = async () => {
  const [testResults, lintResults, coverageResults] = await Promise.all([
    runTests(),
    runLinter(),
    getCoverage()
  ]);

  // Report all results
  if (testResults.failed > 0) {
    fail(`❌ ${testResults.failed} tests failed`);
  }

  if (lintResults.errors > 0) {
    fail(`πŸ” ${lintResults.errors} lint errors found`);
  }

  if (coverageResults.percentage < 80) {
    warn(`πŸ“Š Coverage is ${coverageResults.percentage}%, target is 80%`);
  }

  // Success message if all checks pass
  if (testResults.failed === 0 && lintResults.errors === 0 && coverageResults.percentage >= 80) {
    message("βœ… All quality checks passed!");
  }
};

schedule(runAllChecks);