Skip to main content
Thank you for your interest in contributing to OmniFocus Jira Sync! This guide will help you get started with reporting bugs, requesting features, and submitting code contributions.

Ways to Contribute

There are several ways you can contribute:
  • Report bugs: Help identify and fix issues
  • Request features: Suggest new functionality
  • Submit pull requests: Contribute code improvements
  • Improve documentation: Help others understand the plugin
  • Share feedback: Let us know how we can improve

Reporting Bugs

Before Opening an Issue

  1. Search existing issues to avoid duplicates
  2. Check the troubleshooting guide at Troubleshooting
  3. Verify you’re using the latest version of the plugin
  4. Test with a fresh configuration to rule out local issues

Creating a Bug Report

Open a new issue on GitHub with: Required Information:
  • Title: Clear, concise description of the issue
  • Steps to reproduce: Detailed steps to recreate the bug
  • Expected behavior: What should happen
  • Actual behavior: What actually happens
  • Environment:
    • OmniFocus version
    • macOS version
    • Plugin version
  • Console logs: Relevant output from Console.app (filter for “OmniFocus”)
Optional but Helpful:
  • Screenshots or screen recordings
  • Sample JQL query (redact sensitive project names if needed)
  • Error messages from Jira API responses
Example Bug Report:
**Bug**: Tasks not syncing after upgrading to macOS Sonoma

**Steps to Reproduce**:
1. Upgrade to macOS 14.0 (Sonoma)
2. Open OmniFocus
3. Run "Sync Jira"
4. Error appears: "Failed to connect to Jira"

**Expected Behavior**: Sync completes successfully

**Actual Behavior**: Sync fails with network error

**Environment**:
- OmniFocus: 4.1.2
- macOS: 14.0 (Sonoma)
- Plugin: 1.0.0

**Console Logs**:
[Paste relevant logs here]

Security Issues

If you discover a security vulnerability:
  • Do not open a public GitHub issue
  • Email the maintainer directly (see README for contact)
  • Include details about the vulnerability and potential impact
  • We will respond within 48 hours

Requesting Features

Before Requesting

  1. Search existing issues to see if it’s already requested
  2. Check the roadmap (if available) to see if it’s planned
  3. Consider alternatives that might solve your use case

Creating a Feature Request

Open a new issue on GitHub with: Required Information:
  • Title: Clear, concise feature description
  • Problem: What problem are you trying to solve?
  • Proposed solution: How should the feature work?
  • Alternatives considered: What other solutions have you thought about?
  • Use case: How would you use this feature?
Example Feature Request:
**Feature**: Support for Jira Cloud custom fields

**Problem**: I need to sync custom fields from Jira (e.g., Story Points, Sprint) to OmniFocus task notes.

**Proposed Solution**:
Add a configuration option to specify custom fields to sync. Display them in the task notes below the standard fields.

**Alternatives Considered**:
- Manually adding fields to JQL query (doesn't sync to OmniFocus)
- Using Jira labels instead (not as flexible)

**Use Case**:
Our team uses Story Points to estimate work. I'd like to see these in OmniFocus to prioritize tasks.

Development Setup

Prerequisites

  • macOS with OmniFocus installed
  • Node.js (for linting only)
  • Git for version control
  • Jira instance with API access for testing

Getting Started

  1. Fork the repository on GitHub
  2. Clone your fork:
    git clone https://github.com/YOUR-USERNAME/omnifocus-jira-sync.git
    cd omnifocus-jira-sync
    
  3. Install dependencies (for linting):
    npm install
    
  4. Create a symbolic link to the OmniFocus Plug-Ins directory:
    ln -s "$(pwd)/omnifocus-jira-sync.omnifocusjs" \
      ~/Library/Mobile\ Documents/iCloud~com~omnigroup~OmniFocus/Documents/Plug-Ins/
    
    Alternatively, copy the plugin directory:
    cp -r omnifocus-jira-sync.omnifocusjs/ \
      ~/Library/Mobile\ Documents/iCloud~com~omnigroup~OmniFocus/Documents/Plug-Ins/
    
  5. Restart OmniFocus completely (⌘Q, then relaunch)
  6. Verify the plugin loaded:
    • Go to Automation → Plug-Ins
    • Look for “Jira Sync”

Making Changes

  1. Create a feature branch:
    git checkout -b feature/your-feature-name
    
  2. Make your changes to the plugin files
  3. Test your changes:
    • Restart OmniFocus to load updated code
    • Run Configure JIRA Sync to set up test credentials
    • Run Sync Jira or Sync Jira Full to test
    • Check Console.app for debug output (filter for “OmniFocus”)
  4. Run the linter:
    npm run lint
    
  5. Commit your changes with a conventional commit message:
    git commit -m "feat: add support for custom fields"
    

Manual Testing

There is no automated test suite. Test your changes manually by: Configuration Testing:
  • Test with invalid credentials (should show error)
  • Test with invalid JQL query (should show error)
  • Test with valid configuration (should save successfully)
  • Test connection test button
Sync Testing:
  • Test first sync (all new tasks)
  • Test incremental sync (some updated, some unchanged)
  • Test full sync with cleanup
  • Test status changes (active → completed → reopened)
  • Test due date updates
  • Test parent issue changes (if project organization is enabled)
Edge Cases:
  • Empty JQL results
  • Large result sets (100+ issues)
  • Issues with no description
  • Issues with complex formatting
  • Network failures (disconnect Wi-Fi during sync)
Debugging:
  • Open Console.app (Applications → Utilities → Console)
  • Filter for “OmniFocus” in the search bar
  • Click Start to stream logs
  • Run your action and observe output
  • Look for errors, warnings, or unexpected behavior

Coding Standards

Language & Style

JavaScript Environment:
  • ES6+ syntax (const/let, arrow functions, async/await, template literals, destructuring)
  • No Node.js or browser APIs
  • No btoa(), fetch(), or XMLHttpRequest
  • Use OmniFocus-specific APIs (URL.FetchRequest, Preferences, Credentials, etc.)
Code Style:
  • 2-space indentation
  • Single quotes for strings
  • Semicolons required
  • camelCase for variables and functions
  • UPPER_CASE for constants
  • Descriptive variable names
Action File Structure:
/* global PlugIn Version Preferences Credentials Task Tag URL Alert Form */
(() => {
  const action = new PlugIn.Action(async function(selection, sender) {
    // Action implementation
  });

  action.validate = function(selection, sender) {
    // Validation logic
    return true;
  };

  return action;
})();

Linting

Run ESLint before submitting:
npm run lint
Fix auto-fixable issues:
npm run lint -- --fix

Code Comments

  • Use comments to explain why, not what
  • Document complex algorithms or non-obvious logic
  • Add JSDoc comments for exported functions
  • Avoid redundant comments that restate the code
Good:
// Retry with exponential backoff to handle transient network failures
for (let attempt = 0; attempt <= RETRY_MAX_ATTEMPTS; attempt++) {
  // ...
}
Bad:
// Loop 3 times
for (let attempt = 0; attempt <= RETRY_MAX_ATTEMPTS; attempt++) {
  // ...
}

Commit Messages

This project uses Conventional Commits:
<type>: <description>

[optional body]

[optional footer]

Commit Types

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • refactor: Code refactoring (no functional changes)
  • perf: Performance improvements
  • test: Adding or updating tests
  • chore: Maintenance tasks (dependencies, build config, etc.)
  • style: Code style changes (formatting, whitespace, etc.)

Examples

Feature:
feat: add support for custom field mapping

Allows users to specify additional Jira fields to sync to OmniFocus task notes.
Configured via the "Custom Fields" setting in the configuration dialog.
Bug Fix:
fix: handle empty JQL query gracefully

Previously, an empty JQL query would cause a 400 error from Jira.
Now displays a user-friendly error message prompting the user to enter a query.
Documentation:
docs: update installation instructions for OmniFocus 4

OmniFocus 4 changed the Plug-Ins directory location.
Updated README with the new path.
Refactor:
refactor: extract status mapping logic to jiraCommon

Moves getStatusMappings() to jiraCommon.js to avoid duplication
between syncJira.js and syncJiraFull.js.

Breaking Changes

If your commit introduces a breaking change, add BREAKING CHANGE: in the footer:
feat: change settings key format

BREAKING CHANGE: Settings are now stored as JSON instead of individual keys.
Users will need to reconfigure the plugin after upgrading.

Pull Request Process

Before Submitting

  1. Rebase on main to ensure a clean history:
    git fetch origin
    git rebase origin/main
    
  2. Run the linter:
    npm run lint
    
  3. Test manually in OmniFocus
  4. Update documentation if needed
  5. Update CHANGELOG.md under [Unreleased] for user-facing changes

Creating a Pull Request

  1. Push your branch to your fork:
    git push origin feature/your-feature-name
    
  2. Open a Pull Request on GitHub against the main branch
  3. Fill out the PR template with:
    • Description of changes
    • Motivation and context
    • How to test
    • Checklist of completed tasks
  4. Link related issues (e.g., “Fixes #123”)

PR Guidelines

Do:
  • Keep PRs focused on a single change
  • Include clear commit messages
  • Update documentation and CHANGELOG
  • Test thoroughly before submitting
  • Respond to review feedback promptly
Don’t:
  • Submit PRs with unrelated changes
  • Include merge commits (use rebase instead)
  • Push directly to main
  • Force push to shared branches
  • Ignore linter errors

Code Review

All PRs require review before merging:
  • Maintainers will review your code for:
    • Correctness and functionality
    • Code quality and style
    • Performance implications
    • Security considerations
    • Documentation completeness
  • You may be asked to make changes
  • Address feedback by pushing new commits
  • Once approved, a maintainer will merge your PR

Merge Strategy

  • Squash merge is preferred for clean history
  • Your commits will be squashed into a single commit on main
  • The squashed commit will use your PR title as the commit message
  • Ensure your PR title follows conventional commit format

Documentation

Good documentation is just as important as good code:

README Updates

Update the README if your changes:
  • Add new features
  • Change installation steps
  • Modify configuration options
  • Alter usage instructions

Code Documentation

Document your code:
  • Add comments for complex logic
  • Use JSDoc for exported functions
  • Explain non-obvious decisions
  • Document function parameters and return values

User-Facing Documentation

If adding a user-facing feature, consider adding:
  • Usage examples
  • Configuration instructions
  • Troubleshooting tips
  • FAQ entries

Community Guidelines

Code of Conduct

Be respectful and inclusive:
  • Use welcoming and inclusive language
  • Respect differing viewpoints and experiences
  • Accept constructive criticism gracefully
  • Focus on what’s best for the community
  • Show empathy towards other community members

Communication

GitHub Issues:
  • Use for bug reports and feature requests
  • Search before opening new issues
  • Provide clear, detailed information
  • Stay on topic
Pull Requests:
  • Use for code contributions
  • Keep discussions focused on the code
  • Be open to feedback
Discussions:
  • Use GitHub Discussions (if enabled) for questions and general discussion
  • Help others when you can

Recognition

Contributors are recognized in:
  • GitHub Contributors list
  • CHANGELOG.md (for significant contributions)
  • Release notes
Thank you for contributing to OmniFocus Jira Sync!

Additional Resources

Build docs developers (and LLMs) love