Spry LogoDocumentation
Contributing and Support

Contributing Guide

How to contribute to Spry and help improve the project

Contributing Guide

Welcome to Spry! We're excited that you want to contribute. This guide will help you get started with contributing code, documentation, or feedback.

Before You Start

Read the Development Setup

Familiarize yourself with the Development Setup guide to understand the project structure and tooling.

Check Existing Issues

Browse existing issues to see if your bug or feature has already been reported.

Review Recent Pull Requests

Look at recent pull requests to understand ongoing work and avoid duplication.

First Time Contributing?

Don't worry! We welcome contributions from developers of all experience levels. Start with issues labeled good first issue to get familiar with the codebase.

Types of Contributions

Bug Reports

Create a GitHub issue with the following information:

  • Clear title describing the problem
  • Steps to reproduce the issue
  • Expected behavior - what should happen
  • Actual behavior - what actually happens
  • Environment details (OS, Deno version)
  • Relevant error messages or logs
  • Code samples if applicable

Security Issues

If you discover a security vulnerability, please email the maintainers directly instead of creating a public issue.

Feature Requests

Open an issue or discussion with:

  • Clear description of the feature
  • Use case and motivation - why is this needed?
  • Proposed implementation (optional but helpful)
  • Examples of desired behavior
  • Alternatives considered (if any)

Code Contributions

We welcome contributions in these areas:

  • Bug fixes
  • New features
  • Performance improvements
  • Test coverage
  • Documentation improvements
  • Refactoring for code quality

Documentation

Help improve Spry's documentation by:

  • Fixing typos or grammar
  • Adding examples
  • Clarifying confusing sections
  • Writing new guides
  • Improving API documentation

Development Workflow

1. Fork and Clone

First, fork the repository on GitHub, then clone your fork:

# Clone your fork
git clone https://github.com/YOUR_USERNAME/spry.git
cd spry

# Add upstream remote
git remote add upstream https://github.com/programmablemd/spry.git

2. Create a Branch

Create a branch for your work using a descriptive name:

git checkout -b feature/my-feature
git checkout -b fix/issue-123
git checkout -b docs/improve-readme

3. Make Changes

When making changes:

  • Write tests for new functionality
  • Follow existing code style for consistency
  • Keep changes focused on a single issue or feature
  • Update documentation if needed

4. Test Your Changes

Run the full test suite to ensure your changes don't break existing functionality:

# Run all tests
deno test --parallel --allow-all

# Format check
deno fmt --check

# Lint
deno lint

Test Coverage

Aim for comprehensive test coverage including happy paths, edge cases, and error conditions. Tests should be clear and maintainable.

5. Commit Your Changes

Use semantic commit messages that follow our convention:

git commit -m "feat(axiom): add custom edge rule support #<ticket-number>"
git commit -m "fix(runbook): resolve dependency cycle detection #<ticket-number>"
git commit -m "docs: update contributing guide #<ticket-number>"
git commit -m "test(task): add execution plan tests #<ticket-number>"
git commit -m "refactor(shell): simplify command parsing #<ticket-number>"

6. Push and Create Pull Request

Push your changes and create a pull request:

git push origin feature/my-feature

Then navigate to GitHub and create a pull request from your branch.

Commit Message Format

We follow a structured commit message format for clarity and consistency:

<type>(<scope>): <description>

[optional body]

[optional footer]

Commit Types

TypeDescription
featNew feature
fixBug fix
docsDocumentation only changes
testAdding or updating tests
refactorCode refactoring without behavior changes
perfPerformance improvements
choreMaintenance tasks
ciCI/CD configuration changes

Commit Scopes

ScopeDescription
axiomGraph engine and core abstractions
runbookRunbook execution and orchestration
sqlpageSQLPage playbook integration
taskTask execution and planning
shellShell command execution
courierData movement and transformation

Commit Examples

feat(axiom): add support for custom edge rules

Add ability to register custom edge rules for graph building.
This enables extensibility for domain-specific relationships.

Closes #123
fix(runbook): handle missing task dependencies gracefully

Previously, missing dependencies caused a crash. Now they are
reported as warnings and skipped.

Fixes #456
feat(task)!: change task execution API signature

BREAKING CHANGE: The executeTask function now requires
an options object instead of individual parameters.

Migration guide available in docs/migration.md

Code Style Guidelines

TypeScript Best Practices

Follow these guidelines for consistent, maintainable code:

// Good: Explicit types, descriptive names
function processTask(task: ExecutableTask): TaskResult {
  const taskId = task.taskId();
  const dependencies = task.dependencies();
  
  return {
    id: taskId,
    status: 'completed',
    dependencies,
  };
}

// Avoid: Implicit types, unclear names
function proc(t: any) {
  const id = t.taskId();
  return { id, status: 'completed' };
}

Key principles:

  • Use TypeScript strict mode
  • Prefer const over let
  • Use explicit types for function parameters and return values
  • Use descriptive variable names
  • Avoid any type except when absolutely necessary

Code Formatting

Spry uses Deno's default formatting. Always run before committing:

deno fmt

Documentation Comments

Use JSDoc comments for public APIs:

/**
 * Build an execution plan from tasks.
 *
 * Uses Kahn's algorithm to determine topological order.
 *
 * @param tasks - Tasks in definition order
 * @returns Execution plan with layers and DAG order
 * @throws {Error} If circular dependencies are detected
 *
 * @example
 * ```typescript
 * const plan = executionPlan(tasks);
 * console.log(plan.layers);
 * ```
 */
export function executionPlan<T extends Task>(
  tasks: readonly T[]
): TaskExecutionPlan<T> {
  // Implementation
}

Comment guidelines:

  • Use JSDoc for public APIs
  • Comment complex logic and algorithms
  • Don't state the obvious
  • Explain why, not what

File Organization

Organize files consistently:

lib/axiom/projection/
├── flexible.ts          # Main implementation
├── flexible_test.ts     # Tests
├── playbook.ts
├── playbook_test.ts
└── fixture/             # Test fixtures
    ├── sample.md
    └── complex.md

Rules:

  • One main export per file when possible
  • Tests adjacent to source files (*_test.ts)
  • Fixtures in fixture/ subdirectories
  • Index files (mod.ts) for module exports

Testing Guidelines

Writing Tests

Write clear, focused tests using Deno's built-in test framework:

import { assertEquals, assertThrows } from "@std/assert";

Deno.test("executionPlan creates valid topological order", () => {
  // Arrange
  const tasks = createTestTasks();

  // Act
  const plan = executionPlan(tasks);

  // Assert
  assertEquals(plan.layers.length, 3);
  assertEquals(plan.dag.length, tasks.length);
});

Deno.test("executionPlan handles async operations", async () => {
  const plan = await createAsyncPlan();
  assertEquals(plan.status, "success");
});

Deno.test("executionPlan throws on circular dependencies", () => {
  const circularTasks = createCircularTasks();
  
  assertThrows(
    () => executionPlan(circularTasks),
    Error,
    "Circular dependency detected"
  );
});

Test Coverage

Aim for comprehensive coverage of:

Happy Path

Test the main use case with valid inputs and expected outputs.

Edge Cases

Test boundary conditions, empty inputs, and unusual but valid scenarios.

Error Conditions

Test error handling, invalid inputs, and failure modes.

Integration

Test how components work together in realistic scenarios.

Test Organization

// Group related tests
Deno.test("TaskExecutor", async (t) => {
  await t.step("executes single task", () => {
    // Test implementation
  });

  await t.step("handles dependencies", () => {
    // Test implementation
  });

  await t.step("reports failures", () => {
    // Test implementation
  });
});

Pull Request Guidelines

PR Title Format

Use the same format as commit messages:

feat(axiom): add custom edge rule support
fix(runbook): resolve dependency cycle detection
docs: improve contributing guide clarity

PR Description Template

Include the following in your PR description:

## What does this change?
Brief description of the changes

## Why is this needed?
Explain the motivation and use case

## How was it tested?
- [ ] Unit tests added/updated
- [ ] Manual testing performed
- [ ] Documentation updated

## Breaking changes?
None / List any breaking changes

## Related issues
Closes #123

Clear Communication

A well-written PR description helps reviewers understand your changes quickly and provides context for future reference.

Review Process

Automated Checks

All automated checks (tests, linting, formatting) must pass.

Code Review

At least one maintainer will review your code and provide feedback.

Address Feedback

Make requested changes and push updates to your branch.

Merge

Once approved, your PR will be squashed and merged.

After Your PR is Merged

Your contribution will be included in the next release. Thank you for making Spry better! 🎉

Getting Help

Need assistance? We're here to help:

GitHub Issues

Check existing issues or create a new one.

Discussions

Ask questions in GitHub Discussions.

Documentation

Browse the documentation for guides and API reference.

Code of Conduct

We are committed to providing a welcoming and inclusive environment. All contributors are expected to:

  • Be respectful and considerate
  • Welcome newcomers and help them get started
  • Give and receive constructive feedback gracefully
  • Focus on what's best for the community
  • Show empathy towards other community members

License

By contributing to Spry, you agree that your contributions will be licensed under the project's MIT License.

** Thank You**

Every contribution, no matter how small, helps make Spry better for everyone. We appreciate your time and effort!

How is this guide?

Last updated on

On this page