Contributing to Opik

July 8, 2026 ยท View on GitHub

Thanks for your interest in contributing to Opik.

If you are looking for setup instructions and contribution workflows, start with our docs:

You can also read and edit those docs directly in this repository:

  • apps/opik-documentation/documentation/fern/docs/contributing/overview.mdx
  • apps/opik-documentation/documentation/fern/docs/contributing/local-development.mdx

Please review the CLA before contributing:

Repository layout at a glance

  • apps/: deployable services and product surfaces (backend, frontend, docs, and supporting backends)
  • sdks/: SDKs (python, typescript, opik_optimizer) and code generation
  • tests_end_to_end/: end-to-end suites and helpers
  • deployment/: Docker and Helm deployment assets

Component-specific guides

Fast path

  1. Open or confirm a tracked issue first (Fixes #... or Resolves #...).
  2. Create a branch: {username}/{ticket}-{summary} where ticket is OPIK-####, issue-####, or NA.
  3. Keep changes scoped to the requested area.
  4. Run relevant formatters, linters, and tests before opening a PR.
  5. Open a draft PR with GitHub CLI: gh pr create --draft.
  6. Fill .github/pull_request_template.md completely.

GitHub Actions workflows

Workflow files in .github/workflows/ are validated with actionlint, which runs as a hook in the unified ๐Ÿ™ Code Quality workflow (and locally via pre-commit) on changed workflow files. The pre-commit framework builds the pinned actionlint from source automatically โ€” no manual install needed. Run make hooks once per clone to enable it locally.

Dockerfiles

Dockerfiles are linted with hadolint, which runs as a hook in the unified ๐Ÿ™ Code Quality workflow (and locally via pre-commit) on changed Dockerfiles. It uses hadolint's default rule set; the handful of intentionally-suppressed rules are annotated inline in each Dockerfile with a # hadolint ignore= comment and a reason. The hook runs hadolint via its Docker image, so it needs only Docker โ€” no manual install. To run it directly on a single file: docker run --rm -i ghcr.io/hadolint/hadolint < path/to/Dockerfile.

Generated files (do not edit manually)

  • apps/opik-backend/src/main/resources/model_prices_and_context_window.json
  • apps/opik-frontend/src/data/model_prices_and_context_window.json

These files are regenerated by automation from upstream BerriAI/litellm. Use the updater workflow or approved automation, not direct edits.

Commit and PR conventions

  • First commit (used as PR title source):
    • [<TICKET-KEY>] [BE|FE|SDK|DOCS|INFRA|NA] <type>: <summary>
  • Follow-up commits:
    • <type>(<scope>): <summary> where type is one of feat, fix, refactor, test, docs, chore.
  • Include screenshots/videos for user-facing UI changes.
  • Keep customer names, non-public internal references, and sensitive operational context out of public PR text.

Referencing Jira tickets in commit messages and the PR body

The GitHub for Jira app links a PR to a Jira ticket's Development panel whenever it finds an issue key (OPIK-1234, project key + hyphen + digits) in the branch name, PR title, PR body, or any commit message. It matches on the pattern alone โ€” it can't tell "this PR resolves the ticket" from "this just mentions it" โ€” and the link can't be removed afterward. To keep a ticket's Development panel reflecting only the work that actually touched it:

  • Tickets this PR resolves โ†’ keep the hyphen: OPIK-1234. Jira links/URLs are fine and wanted. A PR may resolve more than one ticket โ€” list all of them this way.
  • Tickets related but not resolved in this PR (an escalation, a fix that references an older ticket โ€” anything not in the PR title or branch) โ†’ replace the hyphen with an underscore (OPIK_7000) so the scanner can't match it, and do not paste a Jira URL for them (the URL contains the hyphenated key and links anyway).
  • Branch name, PR title, and the ## Issues section are unaffected โ€” resolved tickets use normal OPIK-1234 keys there.

This applies to new PRs only; once a stray key has linked a ticket it generally can't be un-linked.

AI-assisted contributions

AI assistance is allowed, but human authors remain accountable for correctness, licensing, and security.

Rules:

  • Always run relevant tests/linters for touched code.
  • Always be explicit about human/users interaction with produced output.
  • Always review prior issues, pull requests, and existing code for related solutions.
  • Always address system-generated reviews (Baz, Greptile).
  • Never submit unreviewed AI output.
  • Never include secrets, tokens, private prompts, internal system instructions, or customer-sensitive data in generated/public content.
  • Never disclose vulnerabilities, exploit steps, or incident details in public issues/PRs (use private maintainer/security channels).
  • Include the PR template AI watermark/disclosure block when AI is used.

Code quality (pre-commit)

Linters and formatters are orchestrated by the pre-commit framework from the single root .pre-commit-config.yaml (the source of truth for which checks run on which paths).

  • Install once per clone: pip install pre-commit (or brew install pre-commit), then make hooks. Use pre-commit 3.0+ (developed on 4.x); the hook is shared across all worktrees, so install it once.
  • On commit, only the hooks matching your changed files run. If a formatter fixes a file, the commit is aborted and the fixes are left unstaged โ€” review them, git add, and commit again.
  • Run the same checks over your whole branch diff: make precommit. Full-repo audit: make precommit-all.
  • Java (Spotless), frontend/TS (ESLint + typecheck) hooks use the repo's own Maven/Node toolchains, so they only run for contributors already set up for those areas.

Agent/editor setup

  • Cursor compatibility: make cursor (.cursor -> .agents)
  • Codex compatibility: make codex (.codex -> .agents, generates AGENTS.override.md from .agents/rules/*.mdc)
  • Claude sync: make claude (syncs .agents to .claude)
  • Git hooks: make hooks (installs the pre-commit framework hook; see Code quality above)