Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/enforce-stage-only.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Enforce stage-only merges to main
# Guards the publish branch: the ONLY branch allowed to open a PR into `main`
# is `stage`. Make `source-branch-guard` a required status check on `main`
# (already configured via branch protection) so this cannot be bypassed.
on:
pull_request:
branches: [main]
jobs:
source-branch-guard:
runs-on: ubuntu-latest
steps:
- name: Require PR source to be stage
run: |
if [ "${{ github.head_ref }}" != "stage" ]; then
echo "::error::PRs into 'main' must come from 'stage' (got '${{ github.head_ref }}'). Land your change on 'stage' first, then merge stage -> main."
exit 1
fi
echo "OK: source branch is 'stage'."
31 changes: 31 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Contributing

## Branching & release workflow

This repo publishes **publicly**. The `main` branch is the public release branch — do **not** commit to it directly.

```
feature branch ──► stage ──► (PR) ──► main
(your work) (test) (public release)
```

| Branch | Role | What publishing does |
|--------|------|----------------------|
| `stage` | Integration & testing | `release.yml` publishes charts as `<version>-stage.N` |
| `main` | Public release | `release.yml` publishes the real chart versions |

### How to land a change

1. Branch off `stage`, do your work, open a PR **into `stage`**.
2. Merge to `stage`. The release workflow publishes a `-stage.N` chart you can test against.
3. When it's good, open a PR **from `stage` into `main`** and merge it. That is the *only* way to release publicly.

### Enforcement (so we can't forget)

`main` is protected:

- **Direct pushes are blocked** — everything goes through a PR.
- **Only `stage` may be merged into `main`.** A required status check (`source-branch-guard`, see `.github/workflows/enforce-stage-only.yml`) fails any PR into `main` whose source branch isn't `stage`.
- Force-pushes and branch deletion are blocked, and the rules apply to admins too.

If you find yourself wanting to push to `main` directly: don't. Land it on `stage`, then merge `stage` → `main`.
Loading