# Contributing to Moko Consulting Projects

Thank you for your interest in contributing. All Moko Consulting repositories follow this universal workflow and version policy.

## Branching Workflow

```
feature/* ──PR──> dev ──draft PR──> (renamed to rc) ──merge──> main
```

### Step by step

1. **Create a feature branch** from `dev`:
   ```bash
   git checkout dev && git pull
   git checkout -b feature/my-change
   ```

2. **Work and commit** on your feature branch. Push to origin.

3. **Open a PR**: `feature/my-change` → `dev`. After review and checks, merge it.

4. **When ready for release**, open a **draft PR**: `dev` → `main`.
   - This automatically renames the source branch to `rc` (release candidate)
   - An RC pre-release is built and uploaded

5. **Alpha and beta branches** are created by manually renaming the branch before the RC stage:
   - Rename `dev` to `alpha` for early testing → alpha pre-release is built
   - Rename `alpha` to `beta` for feature-complete testing → beta pre-release is built
   - When the draft PR is created, the branch is renamed to `rc`

6. **Once PR checks pass** on the `rc` branch, mark the PR as ready and merge to `main`.

7. **Merging to main** triggers the stable release pipeline:
   - Minor version bump (e.g., `02.09.xx` → `02.10.00`)
   - Stability suffix stripped (clean version)
   - Gitea release created with ZIP/tar.gz packages
   - `updates.xml` updated (Joomla extensions)
   - `dev` branch recreated from `main`

### Branch summary

| Branch | Purpose | Created by |
|--------|---------|-----------|
| `feature/*` | New features and fixes | Developer |
| `dev` | Integration branch | Auto-recreated after release |
| `alpha` | Alpha pre-release testing | Manual rename from `dev` |
| `beta` | Beta pre-release testing | Manual rename from `alpha` |
| `rc` | Release candidate | Auto-renamed on draft PR to main |
| `main` | Stable releases | Protected, merge only |
| `version/XX.YY.ZZ` | Archived release snapshots | Auto-created by CI |

### Protected branches

| Branch | Direct push | Merge via |
|--------|------------|-----------|
| `main` | Blocked (CI bot whitelisted) | PR merge only |
| `dev` | Blocked (CI bot whitelisted) | PR merge from feature/* |
| `rc` | Blocked (CI bot whitelisted) | Auto-created on draft PR |
| `alpha` | Blocked (CI bot whitelisted) | Manual rename |
| `beta` | Blocked (CI bot whitelisted) | Manual rename |
| `feature/*` | Open | N/A (source branch) |

## Version Policy

### Format

All versions use `XX.YY.ZZ` — three two-digit segments, zero-padded:

- **XX** — Major version (breaking changes)
- **YY** — Minor version (new features, bumped on release to main)
- **ZZ** — Patch version (auto-incremented on every push to dev/feature branches)

Rollover: patch `99` → `00` increments minor; minor `99` → `00` increments major.

### Stability suffixes

Each branch appends a suffix to indicate stability:

| Branch | Suffix | Example |
|--------|--------|---------|
| `main` | (none) | `02.09.00` |
| `dev` | `-dev` | `02.09.01-dev` |
| `feature/*` | `-dev` | `02.09.01-dev` |
| `alpha` | `-alpha` | `02.09.01-alpha` |
| `beta` | `-beta` | `02.09.01-beta` |
| `rc` | `-rc` | `02.09.01-rc` |

### Auto version bump

On every push to `dev`, `feature/*`, or `patch/*`:

1. Patch version incremented
2. Stability suffix `-dev` applied
3. All version-bearing files updated (manifests, CHANGELOG, PHP headers, etc.)
4. Commit created with `[skip ci]` to avoid loops

### Release version flow

Version bumps happen at specific release events:

| Event | Bump | Example |
|-------|------|---------|
| Feature merged to dev | Patch bump after dev release | `02.09.01-dev` → release → `02.09.02-dev` |
| Dev promoted to RC | Minor bump | `02.09.02-dev` → `02.10.00-rc` |
| RC merged to main | Minor bump | `02.10.00-rc` → `02.11.00` (stable) |
| Dev recreated from main | Patch bump | `02.11.00` → `02.11.01-dev` |

### Release stream copies

When a higher-stability release is published, copies are created for all lesser streams with the same base version:

- **RC `02.10.00-rc`** also creates: `02.10.00-dev`, `02.10.00-alpha`, `02.10.00-beta`
- **Stable `02.11.00`** also creates: `02.11.00-dev`, `02.11.00-alpha`, `02.11.00-beta`, `02.11.00-rc`

This ensures Joomla sites on ANY stability channel see the update (Joomla only shows versions higher than what's installed).

### Version files

The version tools update all files containing version stamps:

- `.mokogitea/manifest.xml` (canonical source)
- Joomla XML manifests (`<version>` tag)
- `README.md`, `CHANGELOG.md` (`VERSION:` pattern)
- `package.json`, `pyproject.toml`
- Any text file with a `VERSION: XX.YY.ZZ` label

Files synced from other repos (with a `# REPO:` header) are not touched.

## Code Standards

- **PHP**: PSR-12, tabs for indentation
- **Copyright**: all files must include the Moko Consulting copyright header
- **License**: SPDX identifier `GPL-3.0-or-later` (or as specified per repo)
- **Attribution**: use `Authored-by: Moko Consulting` in commits, not individual names

## Commit Messages

Use conventional commit format:

```
type(scope): short description

Optional body with context.

Authored-by: Moko Consulting
```

Types: `feat`, `fix`, `chore`, `docs`, `style`, `refactor`, `test`, `ci`

Special flags in commit messages:
- `[skip ci]` — skip all CI workflows
- `[skip bump]` — skip auto version bump only

## Reporting Issues

Use the repository's issue tracker with the appropriate template.

---

*Moko Consulting <hello@mokoconsulting.tech>*
