Contributing
Contributing to QualOps
Section titled “Contributing to QualOps”Thank you for your interest in contributing to QualOps! This document provides guidelines and instructions for contributing.
Development Setup
Section titled “Development Setup”# Clone the repositorygit clone https://github.com/eggai-tech/qualops.gitcd qualops
# Install dependenciesnpm install
# Run testsnpm test
# Run lintingnpm run lint
# Buildnpm run buildMaking Changes
Section titled “Making Changes”Branch Naming
Section titled “Branch Naming”Use descriptive branch names:
feat/- New featuresfix/- Bug fixesdocs/- Documentation changesrefactor/- Code refactoringchore/- Maintenance tasks
Commit Messages
Section titled “Commit Messages”Follow Conventional Commits:
feat: add new review pass for security checksfix: handle empty file arrays in pipelinedocs: update README with new configuration optionschore: update dependenciesUpdating the Changelog
Section titled “Updating the Changelog”Every PR must update CHANGELOG.md under the [Unreleased] section (unless it’s a documentation-only or CI change).
Add your changes under the appropriate subsection:
## [Unreleased]
### Added- New feature description
### Changed- Change description
### Fixed- Bug fix description
### Removed- Removed feature descriptionPRs that only touch docs/, .github/, examples/, or root config files are auto-skipped by CI — no label needed.
Pull Request Process
Section titled “Pull Request Process”- Create a feature branch from
main - Make your changes
- Update
CHANGELOG.mdunder[Unreleased] - Ensure all tests pass:
npm test - Ensure linting passes:
npm run lint - Create a Pull Request to
main - Wait for CI to pass and request review
PR Requirements
Section titled “PR Requirements”- All CI checks must pass
- At least one approval required
- Changelog must be updated (or
skip-changeloglabel applied)
Release Process
Section titled “Release Process”QualOps ships on two tiers:
@beta— pre-release track for internal users. Consumed asuses: eggai-tech/qualops@betaornpm install @eggai/qualops@beta.@stable— production track for external clients. Consumed asuses: eggai-tech/qualops@stableor the defaultnpm install @eggai/qualops.
beta and stable are movable lightweight git tags. They are moved automatically by CI on every release or promotion. Never move them by hand. If you find them out of sync, see docs/tdr/0001-release-process.md.
Cutting a beta release
Section titled “Cutting a beta release”- Make sure
[Unreleased]inCHANGELOG.mdreflects all the changes you intend to ship. - Go to Actions → Create Release PR → Run workflow.
- Enter a pre-release version, e.g.
0.3.0-beta.1. - Review the PR the workflow opens. It bumps
package.jsononly —[Unreleased]is intentionally left untouched on beta releases. - Merge the PR. CI will:
- Tag the commit
v0.3.0-beta.1(immutable). - Publish
@eggai/qualops@0.3.0-beta.1to npm with thebetadist-tag (latestis not touched). - Create a GitHub Release marked as pre-release.
- Force-move the
betagit tag to the release commit.
- Tag the commit
Promoting a beta to stable
Section titled “Promoting a beta to stable”Soak the beta for at least 5–7 days by running it against internal workloads. When you’re confident:
- Go to Actions → Promote to Stable → Run workflow.
- Fill in:
beta_version: the beta you want to promote (e.g.,0.3.0-beta.1).stable_version: the clean version (e.g.,0.3.0).reason: short justification — gets surfaced in the PR and the audit log.
- The workflow:
- Verifies the beta exists on npm with the
betadist-tag. - Branches off the exact commit that
v$BETA_VERSIONtags. - Bumps
package.jsonto$STABLE_VERSIONand moves[Unreleased]entries into[$STABLE_VERSION]. - Opens a release PR labelled
promotion.
- Verifies the beta exists on npm with the
- Review the PR. Check the diff against
main— if other PRs have landed since the beta, decide whether those changes need additional soaking before promotion. - Merge the PR. CI will:
- Tag
v0.3.0. - Publish
@eggai/qualops@0.3.0to npm with the defaultlatestdist-tag. - Create a GitHub Release.
- Force-move the
stablegit tag and mark the release as--latest.
- Tag
Hotfixes
Section titled “Hotfixes”For an urgent fix to the current stable without going through beta:
git checkout -b hotfix/0.3.1 stable(branch directly off thestabletag).- Apply the fix and update
CHANGELOG.mdunder[Unreleased]. - Run Create Release PR with
0.3.1. Merge. - CI publishes
@eggai/qualops@0.3.1tolatestand force-movesstableto the new commit. - Open a separate PR to merge the fix forward into
main.
Version guidelines
Section titled “Version guidelines”We follow Semantic Versioning:
- MAJOR (
1.0.0): Breaking changes. - MINOR (
0.3.0): New features, backward compatible. - PATCH (
0.3.1): Bug fixes, backward compatible.
Pre-release suffix: -beta.N (e.g., 0.3.0-beta.1, 0.3.0-beta.2). The -rc.N and -alpha.N suffixes are also accepted by the workflow and follow the same dist-tag handling as -beta.
Troubleshooting
Section titled “Troubleshooting”stableandbetagit tags point at unexpected commits. Do not move them manually. Open an issue — the recovery path is to run aPromote to Stable(orCreate Release PRfor beta) for the version you want them to point at; CI will overwrite the tag.- A release workflow fails partway. Check the auto-generated failure issue — it lists which stage failed. If
publish-npmsucceeded but a later stage failed, re-running the workflow is safe (later stages are idempotent). Ifpublish-npmitself failed, check npm for partial state before retrying. Create Release PRleft arelease/v*branch behind after a failure. Delete it manually withgit push origin --delete release/vX.Y.Zand re-run.
The full design rationale lives in docs/tdr/0001-release-process.md.
Code Style
Section titled “Code Style”- TypeScript with strict mode
- ESLint + Prettier for formatting
- Run
npm run lint:fixbefore committing
Testing
Section titled “Testing”# Run all testsnpm test
# Run specific test filenpx jest path/to/test.spec.ts
# Run tests in watch modenpx jest --watch
# Run with coveragenpx jest --coverageQuestions?
Section titled “Questions?”Open an issue or reach out to the maintainers.