Thank you for considering contributing to our projects! It's people like you that make open source such a great community.
This project and everyone participating in it is governed by our Code of Conduct. By participating, you are expected to uphold this code.
Before creating bug reports, please check the issue list as you might find out that you don't need to create one. When you are creating a bug report, please include as many details as possible:
- Use a clear and descriptive title
- Describe the exact steps which reproduce the problem
- Provide specific examples to demonstrate the steps
- Describe the behavior you observed after following the steps
- Explain which behavior you expected to see instead and why
- Include screenshots if possible
Enhancement suggestions are tracked as GitHub issues. When creating an enhancement suggestion, please include:
- Use a clear and descriptive title
- Provide a step-by-step description of the suggested enhancement
- Describe the current behavior and explain which behavior you expected to see instead
- Explain why this enhancement would be useful
- Fork the repo and create your branch from
development - If you've added code that should be tested, add tests
- If you've changed APIs, update the documentation
- Ensure the test suite passes
- Make sure your code lints (
composer cs:check) - Create a pull request!
We use a structured branching model to ensure stability across environments. All branches are protected via organization-wide rulesets on the ConductionNL GitHub organization — direct pushes are not allowed. Every change flows through a pull request with peer review and CI checks.
graph LR
F["feature/*\nbugfix/*"] -->|"PR + 1 review\n+ Quality CI ✓"| D[development]
D -->|"PR + 1 review\n+ Quality CI ✓"| B[beta]
B -->|"PR + 2 reviews\n+ Branch CI ✓"| M[main]
H["hotfix/*"] -->|"PR + 1 review\n+ Quality CI ✓"| B
H -->|"PR + 2 reviews\n+ Branch CI ✓"| M
style F fill:#e1f5fe
style D fill:#fff9c4
style B fill:#ffe0b2
style M fill:#c8e6c9
style H fill:#ffcdd2
These rules are enforced organization-wide across all ConductionNL repositories. They cannot be overridden at the repository level.
| Target | Allowed Sources | Reviews | Required CI Checks |
|---|---|---|---|
development |
feature/*, bugfix/* |
1 approving review | Quality CI (lint-check) |
beta |
development, hotfix/*, main (backport) |
1 approving review | Quality CI (lint-check) |
main |
beta, hotfix/* |
2 approving reviews | Branch Protection CI (check-branch, lint-check) |
Branch protection is managed at the organization level, not per-repository. This ensures consistent enforcement across all Conduction apps. The three rulesets are:
- Development Branch Protection — Enforces peer review and Quality CI for all feature work entering
development - Beta Branch Protection — Same requirements as development, gates the path to beta releases
- Main Branch Protection — Stricter: requires 2 reviewers and branch-source validation before stable release
All rulesets also enforce:
- No force pushes
- No branch deletion
- Stale reviews dismissed on new pushes
- All review threads must be resolved before merge
- Feature work happens on
feature/*orbugfix/*branches created fromdevelopment - PRs to
developmentrequire 1 approving peer review and the Quality CI workflow must pass - When ready for beta release, a developer creates a PR from
developmenttobeta— same review + CI requirements - Merging to
betatriggers an automatic beta release to the Nextcloud App Store - When ready for stable release, a developer creates a PR from
betatomain— requires 2 approving reviews and Branch Protection CI - Merging to
maintriggers an automatic stable release to the Nextcloud App Store - Hotfixes can target both
betaandmaindirectly for urgent patches via PR (same review requirements apply) - Branches are automatically deleted after their PR is merged
Important: There are no automatic merges or auto-created PRs between branches. Every promotion (development -> beta -> main) requires a deliberate pull request created by a developer, with peer review and CI passing before merge is allowed.
Every pull request triggers our automated quality pipeline. All checks must pass before a PR can be merged. This ensures that no code enters development, beta, or main without meeting our quality standards.
| Check | Tool | What It Does |
|---|---|---|
| Lint | php -l |
Syntax validation — catches parse errors |
| Code Style | PHPCS | Enforces coding standards (PSR-12 + custom rules) |
| Static Analysis | PHPStan (level 5) | Type checking, undefined methods, dead code |
| Static Analysis | Psalm | Additional type inference and security analysis |
| Mess Detection | PHPMD | Complexity, naming, unused code, design problems |
| Metrics | phpmetrics | Maintainability index, coupling, cyclomatic complexity |
| Check | Tool | What It Does |
|---|---|---|
| JavaScript | ESLint | Enforces JS/Vue coding standards |
| CSS | Stylelint | Enforces CSS/SCSS coding standards |
| Check | What It Does |
|---|---|
| License (npm + composer) | Ensures all dependencies use approved open-source licenses |
| Security (npm + composer) | Checks for known vulnerabilities in dependencies |
# PHP
composer cs:check # PHPCS code style
composer cs:fix # Auto-fix code style
composer phpstan # PHPStan static analysis
composer psalm # Psalm static analysis
composer phpmd # PHPMD mess detection
# Frontend
npm run lint # ESLint
npx stylelint "src/**/*.{css,scss,vue}" # StylelintReleases to the Nextcloud App Store are fully automated via GitHub Actions. They are triggered by merging PRs into beta or main. Version numbers are calculated automatically from PR labels.
graph TD
subgraph "Beta Release"
D[development] -->|"Developer creates PR"| BP1{"Quality CI\npasses?"}
BP1 -->|"Yes"| BM["Merge PR to beta"]
BP1 -->|"No"| BF["Fix issues\nre-push"]
BF --> BP1
BM --> BT{Version Bump\nfrom PR label}
BT -->|"label: major"| BV1["v2.0.0-beta.20260319"]
BT -->|"label: minor"| BV2["v1.1.0-beta.20260319"]
BT -->|"label: patch\n(default)"| BV3["v1.0.1-beta.20260319"]
BV1 & BV2 & BV3 --> BB["Build & Package"]
BB --> BU["Upload to App Store\n(nightly channel)"]
BB --> BG["Create GitHub\npre-release"]
end
subgraph "Stable Release"
B2[beta] -->|"Developer creates PR"| SP1{"Branch Protection\nCI passes?"}
SP1 -->|"Yes"| SM["Merge PR to main"]
SP1 -->|"No"| SF["Fix issues"]
SF --> SP1
SM --> ST{Version Bump\nfrom PR label}
ST -->|"from PR labels"| SV["v1.1.0"]
SV --> SB["Build & Package"]
SB --> SU["Upload to App Store\n(stable channel)"]
SB --> SG["Create GitHub release\nwith changelog"]
end
style D fill:#fff9c4
style BM fill:#ffe0b2
style SM fill:#c8e6c9
style BU fill:#e1bee7
style SU fill:#e1bee7
style BF fill:#ffcdd2
style SF fill:#ffcdd2
Add a label to your PR to control the version bump:
| Label | Version Change | When to Use |
|---|---|---|
major |
1.0.0 → 2.0.0 |
Breaking changes, major redesigns |
minor |
1.0.0 → 1.1.0 |
New features, non-breaking additions |
patch (default) |
1.0.0 → 1.0.1 |
Bug fixes, small improvements |
Each release automatically:
- Bumps the version in
appinfo/info.xml - Builds the app (composer install, npm build)
- Creates a signed tarball
- Uploads to the Nextcloud App Store
- Creates a GitHub release with auto-generated changelog
Documentation is built with Docusaurus and deployed to GitHub Pages.
- Documentation source lives in the
docs/(ordocusaurus/) folder on any branch - Push or merge to the
documentationbranch triggers the build - Docusaurus builds the static site
- The site is deployed to GitHub Pages with a custom domain (e.g.,
openregister.app)
Each app has its own documentation site — see the app's README for its URL.
- Create a feature request issue describing your proposed changes
- Fork the repository
- Create a new branch:
git checkout -b feature/[issue-number]/[feature-name] - Make your changes
- Run quality checks:
composer cs:checkandcomposer phpstan - Push to your fork and open a Pull Request
- Wait for Quality CI to pass, address any failures
- Request review from a team member
We use Conventional Commits:
feat:for new featuresfix:for bug fixeschore:for maintenance tasksdocs:for documentation changesrefactor:for code refactoring- Use the present tense and imperative mood
- Limit the first line to 72 characters
Add labels to categorize your PR in the automated changelog:
feature/enhancement— New features (appears under "Added")bug/fix— Bug fixes (appears under "Fixed")docs— Documentation updatesrefactor/chore— Code improvements (appears under "Changed")skip-changelog— Exclude from changelog
- Install PHP 8.1+ and Node.js 20+
- Install Composer
- Clone the repository
- Run
composer installandnpm install - Configure your Nextcloud development environment
- Join the Common Ground Slack
- Follow us on X
- Read our updates on LinkedIn
By contributing, you agree that your contributions will be licensed under the same license as the project (EUPL-1.2 unless stated otherwise).