223 lines
7.1 KiB
Markdown
223 lines
7.1 KiB
Markdown
<!--
|
|
Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
|
|
|
SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
# FILE INFORMATION
|
|
DEFGROUP: MokoStandards.Documentation
|
|
INGROUP: MokoStandards.Workflows
|
|
REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards-API
|
|
PATH: /docs/workflows/cascade-dev.md
|
|
VERSION: 02.00.00
|
|
BRIEF: Documentation for the cascade main → dev workflow
|
|
-->
|
|
|
|
[](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards)
|
|
|
|
# Cascade Main → Dev Workflow
|
|
|
|
**Status**: ✅ Active | **Version**: 02.00.00 | **Last Updated**: 2026-05-07
|
|
|
|
## Table of Contents
|
|
|
|
- [Overview](#overview)
|
|
- [How It Works](#how-it-works)
|
|
- [Workflow Triggers](#workflow-triggers)
|
|
- [Configuration](#configuration)
|
|
- [Conflict Resolution](#conflict-resolution)
|
|
- [Skipping Cascade](#skipping-cascade)
|
|
- [Deployment](#deployment)
|
|
- [Troubleshooting](#troubleshooting)
|
|
- [Related Documentation](#related-documentation)
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
The **Cascade Main → Dev** workflow automatically forward-merges `main` into all open branches (`dev`, `rc/*`, `beta/*`, `alpha/*`) after every push to `main`. This keeps all development and pre-release branches in sync with stable releases without manual intervention.
|
|
|
|
### Purpose
|
|
|
|
- **Sync**: Ensure all open branches (`dev`, `rc/*`, `beta/*`, `alpha/*`) always include the latest stable code from `main`
|
|
- **Automation**: Eliminate manual merge-forward after releases
|
|
- **Conflict Detection**: Surface merge conflicts early via auto-created PRs
|
|
- **Safety**: Never force-pushes or overwrites — creates PRs for manual resolution when needed
|
|
|
|
### Key Features
|
|
|
|
✅ **API-Only**: No repository checkout required — uses Gitea REST API exclusively
|
|
✅ **Idempotent**: Safe to run multiple times — detects existing PRs and skips duplicates
|
|
✅ **Conflict-Safe**: Creates a PR for manual resolution when auto-merge fails
|
|
✅ **Skip Support**: Opt out per-commit with `[skip cascade]` or `[skip ci]`
|
|
✅ **Deployed Org-Wide**: Active on all governed (non-platform/standards) repositories
|
|
|
|
---
|
|
|
|
## How It Works
|
|
|
|
```
|
|
Push to main
|
|
↓
|
|
Discover target branches (dev, dev/*, rc/*, beta/*, alpha/*)
|
|
↓ (skip if none found)
|
|
For each target branch:
|
|
↓
|
|
Compare main vs branch (commits ahead)
|
|
↓ (skip if already in sync)
|
|
Create PR (main → branch)
|
|
↓ (reuse existing if one is open)
|
|
Check mergeable
|
|
├─ Clean → Auto-merge PR ✅
|
|
└─ Conflicts → Leave PR open for manual resolution ⚠️
|
|
```
|
|
|
|
### Step-by-Step
|
|
|
|
1. **Branch Discovery**: Queries all branches via paginated API, filters to targets matching `dev`, `dev/*`, `rc/*`, `beta/*`, `alpha/*`
|
|
2. **Diff Check**: For each target, queries `GET /repos/{owner}/{repo}/compare/{branch}...main` — if `total_commits` is 0, the branch is already in sync
|
|
3. **PR Creation**: Creates a PR via `POST /repos/{owner}/{repo}/pulls` with `head: main`, `base: {branch}`
|
|
4. **Duplicate Prevention**: Before creating, checks for existing open PRs with the same head/base
|
|
5. **Auto-Merge**: If `mergeable: true`, merges via `POST /repos/{owner}/{repo}/pulls/{index}/merge` with merge style
|
|
6. **Conflict Handling**: If `mergeable: false`, the PR stays open with a clear description for manual resolution
|
|
|
|
---
|
|
|
|
## Workflow Triggers
|
|
|
|
| Trigger | Condition |
|
|
|---------|-----------|
|
|
| `push` to `main` | Every push (PR merges, bot commits, direct pushes) |
|
|
| `workflow_dispatch` | Manual trigger from Gitea Actions UI |
|
|
|
|
### Automatic Skipping
|
|
|
|
The workflow skips execution when:
|
|
- The commit message contains `[skip ci]`
|
|
- The commit message contains `[skip cascade]`
|
|
|
|
---
|
|
|
|
## Configuration
|
|
|
|
### Environment Variables
|
|
|
|
| Variable | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `GITEA_URL` | `https://git.mokoconsulting.tech` | Gitea instance URL |
|
|
| `GITEA_ORG` | `github.repository_owner` | Organization name |
|
|
| `GITEA_REPO` | `github.event.repository.name` | Repository name |
|
|
|
|
### Secrets
|
|
|
|
| Secret | Required | Description |
|
|
|--------|----------|-------------|
|
|
| `GA_TOKEN` | Yes | Gitea API token with repo write + PR permissions |
|
|
|
|
### Runner
|
|
|
|
Runs on `ubuntu-latest` — no special runner requirements.
|
|
|
|
---
|
|
|
|
## Conflict Resolution
|
|
|
|
When the auto-merge detects conflicts:
|
|
|
|
1. The workflow creates (or reuses) a PR titled `chore: cascade main → {branch} ({sha}) [skip ci]`
|
|
2. The PR body explains the conflict and links to the workflow
|
|
3. The workflow exits successfully (not a failure — conflicts are expected)
|
|
4. A developer must:
|
|
- Check out the PR locally
|
|
- Resolve conflicts
|
|
- Push the resolution
|
|
- Merge the PR
|
|
|
|
### Common Conflict Sources
|
|
|
|
- **Version files**: `README.md` VERSION header, `updates.xml` (dev has different version than main)
|
|
- **Changelog**: Both branches modified `CHANGELOG.md`
|
|
- **CI configs**: Workflow files modified independently on both branches
|
|
|
|
---
|
|
|
|
## Skipping Cascade
|
|
|
|
### Per-Commit
|
|
|
|
Add `[skip cascade]` to the commit message:
|
|
|
|
```bash
|
|
git commit -m "chore: version bump [skip cascade]"
|
|
```
|
|
|
|
### Per-Push
|
|
|
|
The `[skip ci]` tag also prevents cascade (since the workflow checks both).
|
|
|
|
---
|
|
|
|
## Deployment
|
|
|
|
The workflow file `.gitea/workflows/cascade-dev.yml` is deployed to all governed repositories (non-platform, non-standards, non-template repos).
|
|
|
|
### Excluded Repositories
|
|
|
|
- `gitea-org-config`, `org-profile`, `gitea-private`, `gitea-server-setup` — Platform/infra
|
|
- `MokoStandards`, `MokoStandards-API`, `MokoTesting` — Standards repos
|
|
- `MokoStandards-Template-*`, `MokoDoliProjTemplate` — Template repos
|
|
|
|
### Adding to a New Repository
|
|
|
|
The cascade workflow is automatically deployed by the bulk sync process. To manually add:
|
|
|
|
1. Copy `.gitea/workflows/cascade-dev.yml` from any governed repo
|
|
2. Ensure the repo has at least one target branch (`dev`, `rc/*`, `beta/*`, or `alpha/*`)
|
|
3. Ensure `GA_TOKEN` secret is configured
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Cascade Not Triggering
|
|
|
|
**Symptom**: Push to main but no cascade run
|
|
|
|
**Causes**:
|
|
1. Commit message contains `[skip ci]` or `[skip cascade]`
|
|
2. Workflow file missing from repo
|
|
3. `GA_TOKEN` secret not configured
|
|
|
|
**Solution**: Check Actions tab for skipped runs; verify workflow file exists on `main`
|
|
|
|
### Cascade Creates PR But Doesn't Merge
|
|
|
|
**Symptom**: PR created but left open
|
|
|
|
**Cause**: Merge conflicts between `main` and the target branch
|
|
|
|
**Solution**: Resolve conflicts locally and merge the PR manually
|
|
|
|
### "No cascade target branches found" Message
|
|
|
|
**Symptom**: Workflow logs show "No cascade target branches found"
|
|
|
|
**Cause**: Repository doesn't have any target branches (`dev`, `rc/*`, `beta/*`, `alpha/*`)
|
|
|
|
**Solution**: Create a target branch from main: `git checkout -b dev main && git push origin dev`
|
|
|
|
---
|
|
|
|
## Related Documentation
|
|
|
|
- [Branch Protection Setup](./branch-protection.md)
|
|
- [Dev Branch Tracking](./dev-branch-tracking.md)
|
|
- [Workflow Architecture](./workflow-architecture.md)
|
|
- [Bulk Repository Sync](./bulk-repo-sync.md)
|
|
|
|
## Changelog
|
|
|
|
| Version | Date | Changes |
|
|
|---------|------|---------|
|
|
| 01.00.00 | 2026-05-07 | Initial release — PR-based merge with conflict detection |
|
|
| 02.00.00 | 2026-05-07 | Cascade to all open branches (dev, rc/*, beta/*, alpha/*), not just dev |
|