Skip to content
Open
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
14 changes: 12 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ The following rule governs code contributions:

## Issues and Planning

* We use GitHub issues to track bugs and enhancement requests.
We follow a shared issue lifecycle across all `cloudoperators` repositories. See the **[Issue Lifecycle documentation](./ISSUE_LIFECYCLE.md)** for the full process including:

* Please provide as much context as possible when you open an issue. The information you provide must be comprehensive enough to reproduce that issue for the assignee.
* Automatic triage labeling
* Triage decision matrix
* Definition of Ready
* Refinement workflow
* Sprint/quarter planning

Quick links:

* [Issues needing triage (org-wide)](https://github.com/issues?q=org%3Acloudoperators+label%3Aneeds-triage+is%3Aopen+sort%3Acreated-asc)
* [Backlog (org-wide)](https://github.com/issues?q=org%3Acloudoperators+label%3Abacklog+is%3Aopen)
* [Project board](https://github.com/orgs/cloudoperators/projects/9)
99 changes: 99 additions & 0 deletions ISSUE_LIFECYCLE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Issue Lifecycle

This document defines the issue workflow used across all repositories in the `cloudoperators` organization.

## Overview

```mermaid
flowchart TD
A([Issue Opened]) -->|auto-labeled by workflow| B[needs-triage]
B --> C{Triage}

C -->|clear & well-scoped| D[label: backlog]
C -->|unclear scope| E[labels: needs-refinement + backlog]
C -->|duplicate / out of scope / won't fix| F([Closed])
C -->|missing info| G[label: needs-more-info]

G -->|reporter responds| C

E --> H[Refinement]
H -->|Definition of Ready met| D

D -->|issue-project-sync workflow| I[(cloudoperators project #9)]
Comment thread
uwe-mayer marked this conversation as resolved.
I --> J[Sprint / Quarter Planning]
J --> K([In Progress → Done])
```

## Stages

### 1. Issue Opened → `needs-triage`

Every new issue is automatically labeled `needs-triage` by the `issue-triage` workflow. A welcome comment is posted directing the reporter to this document. No manual action is required from the reporter.

### 2. Triage (target: within 5 business days)

Maintainers review issues using the org-wide triage view:

🔗 **[All issues needing triage](https://github.com/issues?q=org%3Acloudoperators+label%3Aneeds-triage+is%3Aopen+sort%3Acreated-asc)**

A maintainer removes `needs-triage` and takes **exactly one** of these actions:

| Outcome | Action |
|---|---|
| Clear and well-scoped | Add label **`backlog`** — triggers automatic addition to the project |
| Unclear scope or missing acceptance criteria | Add label **`needs-refinement`** + add label **`backlog`** |
| Needs more info from reporter | Add label **`needs-more-info`** and post a comment specifying what is needed |
| Duplicate | Close with comment: "Duplicate of #NNN." |
| Out of scope / won't fix | Close with a short explanation comment |

**Rules:**
- Always remove `needs-triage` when taking action.
- Always post a comment when closing an issue.
- When adding `needs-more-info`, be specific — do not just say "more info needed".

### 3. Refinement → ready for implementation

Issues labeled `needs-refinement` are discussed asynchronously in comments or during a refinement session. Use the project refinement view for priority ordering:

🔗 **[Refinement view (project #9)](https://github.com/orgs/cloudoperators/projects/9/views/6)**

An issue meets the **Definition of Ready** when ALL of the following are true:

- [ ] Has a clear, single-sentence problem statement
- [ ] Has testable acceptance criteria (e.g., `- [ ] criterion`)
- [ ] Dependencies are identified (linked issues, or explicitly noted as none)

Once ready, the maintainer removes `needs-refinement`. The issue remains in the backlog, ready to be pulled into a sprint.

### 4. Backlog → Sprint / Quarter

During sprint or quarter planning, maintainers move issues from the backlog into the upcoming iteration. The `backlog` label is removed manually when an issue is assigned to a sprint or quarter.

## Label Reference

| Label | Applied by | Meaning |
|---|---|---|
| `needs-triage` | Automation (on open) | New issue, not yet reviewed |
| `needs-refinement` | Maintainer | Needs scoping before implementation |
| `needs-more-info` | Maintainer | Waiting on reporter for details |
| `backlog` | Maintainer | Ready for planning; triggers addition to project #9 |
| `bug` | Issue template | Regression or unintended behavior |
| `feature` | Issue template | New capability request |

## Repositories using this workflow

- [greenhouse](https://github.com/cloudoperators/greenhouse)
- [shoot-grafter](https://github.com/cloudoperators/shoot-grafter)
- [repo-guard](https://github.com/cloudoperators/repo-guard)
- [cloudctl](https://github.com/cloudoperators/cloudctl)
- [owner-label-injector](https://github.com/cloudoperators/owner-label-injector)

## Quick Links

| View | URL |
|---|---|
| All issues needing triage | [org-wide `needs-triage`](https://github.com/issues?q=org%3Acloudoperators+label%3Aneeds-triage+is%3Aopen+sort%3Acreated-asc) |
| Backlog (all repos) | [org-wide `backlog`](https://github.com/issues?q=org%3Acloudoperators+label%3Abacklog+is%3Aopen) |
| Needs refinement | [org-wide `needs-refinement`](https://github.com/issues?q=org%3Acloudoperators+label%3Aneeds-refinement+is%3Aopen) |
| Project board | [cloudoperators project #9](https://github.com/orgs/cloudoperators/projects/9) |
| Refinement view | [project #9, view 6](https://github.com/orgs/cloudoperators/projects/9/views/6) |
109 changes: 109 additions & 0 deletions skills/issue-triage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Skill: Issue Triage

## Description

This skill teaches an agent how to triage GitHub issues across all repositories in the `cloudoperators` organization. Use it whenever you are asked to triage, label, close, or comment on an issue.

The full human-readable process is in [ISSUE_LIFECYCLE.md](../ISSUE_LIFECYCLE.md).

---

## Trigger

Activate this skill when asked to:

- Triage an issue
- Review a `needs-triage` issue
- Apply or suggest labels on an issue
- Determine whether an issue is ready for the backlog

---

## Step-by-Step Triage Process

### 1. Check the current state

Before acting, check:

- Does the issue have `needs-triage`? If not, it may already be triaged — confirm before making changes.
- Does the issue have enough information to make a routing decision?

### 2. Apply exactly one outcome

Remove `needs-triage` and apply one of the following — never more than one:

| Situation | Action |
|---|---|
| Issue is clear, scoped, and has acceptance criteria | Add label `backlog` |
| Issue scope is unclear or acceptance criteria are missing | Add labels `needs-refinement` + `backlog` |
| Issue is missing details needed to evaluate | Add label `needs-more-info` + post a comment specifying exactly what is needed |
| Issue is a duplicate | Close with a comment: "Duplicate of #<number>." |
| Issue is out of scope / won't fix | Close with a short explanation comment |

**Rules:**

- Never apply `backlog` without removing `needs-triage`.
- Always post a comment when closing an issue.
- When adding `needs-more-info`, be specific — do not just say "more info needed".
- The `issue-project-sync` workflow automatically adds issues with `backlog` to the project board. Do not manually add issues to the project.

### 3. Before applying `backlog` without `needs-refinement` — check the Definition of Ready

Only apply `backlog` alone (without `needs-refinement`) when ALL of the following are true:

- [ ] Has a clear, single-sentence problem statement
- [ ] Has testable acceptance criteria (e.g. `- [ ] criterion`)
- [ ] Dependencies are identified (linked issues, or explicitly noted as none)

If any item is missing, apply both `needs-refinement` and `backlog`, and note what is missing in a comment.

### 4. Do not touch the project board

When `backlog` is applied, the `issue-project-sync` GitHub Action workflow automatically adds the issue to [cloudoperators project #9](https://github.com/orgs/cloudoperators/projects/9). Do not manually add issues to the project.

---

## Label Reference

| Label | Applied by | Meaning |
|---|---|---|
| `needs-triage` | Automation (on open) | New issue, not yet reviewed |
| `needs-refinement` | Maintainer / agent | Needs scoping before implementation |
| `needs-more-info` | Maintainer / agent | Waiting on reporter for details |
| `backlog` | Maintainer / agent | Ready for planning; triggers project addition |
| `bug` | Issue template | Regression or unintended behavior |
| `feature` | Issue template | New capability request |

---

## Example Triage Comments

**Sending to refinement:**
> Routing to refinement. The problem statement is clear, but the acceptance criteria are missing. Could you add a list of testable criteria so we can properly scope this before implementation?

**Requesting more information:**
> Marking as `needs-more-info`. To evaluate this issue we need:
>
> - The version where this behaviour was observed
> - The full error message or relevant log output
>
> Please update the issue and we will re-triage.

**Closing as duplicate:**
> Closing as duplicate of #42. Please follow that issue for updates. If you believe this is a distinct problem, reopen with additional context.

**Closing as out of scope:**
> Thank you for the report. After review, this falls outside the current scope of the project. We are closing this for now. If the situation changes, feel free to reopen.

**Approving to backlog:**
> Triaged. This is well-scoped with clear acceptance criteria. Moving to the backlog for sprint planning.

---

## Useful Views

| View | URL |
|---|---|
| All issues needing triage | [org-wide `needs-triage`](https://github.com/issues?q=org%3Acloudoperators+label%3Aneeds-triage+is%3Aopen+sort%3Acreated-asc) |
| Backlog (all repos) | [org-wide `backlog`](https://github.com/issues?q=org%3Acloudoperators+label%3Abacklog+is%3Aopen) |
| Refinement view | [project #9, view 6](https://github.com/orgs/cloudoperators/projects/9/views/6) |
67 changes: 67 additions & 0 deletions workflows/issue-project-sync/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Issue Project Sync Workflow

A reusable composite action that automatically adds issues to [cloudoperators project #9](https://github.com/orgs/cloudoperators/projects/9) when the `backlog` label is applied. Uses the official [actions/add-to-project](https://github.com/actions/add-to-project) action under the hood.

## Usage

Create `.github/workflows/issue-project-sync.yaml` in your repository:

```yaml
name: Issue Project Sync
on:
issues:
types: [labeled]

permissions:
issues: read

jobs:
sync:
if: github.event.label.name == 'backlog'
runs-on: ubuntu-latest
steps:
- uses: cloudoperators/common/workflows/issue-project-sync@main
with:
GH_TOKEN: ${{ secrets.GH_PROJECT_TOKEN }}
```

## What it does

1. Triggered when any label is added to an issue
2. Filters to only run when the `backlog` label is applied
3. Uses `actions/add-to-project` to add the issue to the organization project

## Prerequisites

### Org-level secret: `GH_PROJECT_TOKEN`

This workflow requires a GitHub token with elevated permissions to write to organization projects. Set this up once at the org level:

1. Go to **GitHub → cloudoperators → Settings → Secrets and variables → Actions**
2. Click **New organization secret**
3. Configure:
- **Name:** `GH_PROJECT_TOKEN`
- **Value:** A Personal Access Token (classic) or GitHub App token with scopes:
- `project` (read/write)
- `repo` (to read issue metadata)
- **Repository access:** Select the repositories using this workflow:
- `greenhouse`
- `shoot-grafter`
- `repo-guard`
- `cloudctl`
- `owner-label-injector`

### Labels

The `backlog` label must exist in the repository:

```bash
gh label create "backlog" --color "0e8a16" --description "Ready for sprint planning; triggers project addition" --repo cloudoperators/<repo-name>
```

## Inputs

| Input | Required | Default | Description |
|---|---|---|---|
| `GH_TOKEN` | **Yes** | — | GitHub token with `project` scope (org-level secret) |
| `PROJECT_URL` | No | `https://github.com/orgs/cloudoperators/projects/9` | Full URL of the GitHub project |
20 changes: 20 additions & 0 deletions workflows/issue-project-sync/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: issue-project-sync
description: Add issues labeled with 'backlog' to the cloudoperators project #9

inputs:
GH_TOKEN:
description: 'GitHub token with project write scope. Must be an org-level secret with project and repo permissions.'
required: true
PROJECT_URL:
description: 'The full URL of the GitHub project to add issues to'
required: false
default: 'https://github.com/orgs/cloudoperators/projects/9'

runs:
using: "composite"
steps:
- name: Add issue to project
uses: actions/add-to-project@v1.0.2
with:
project-url: ${{ inputs.PROJECT_URL }}
github-token: ${{ inputs.GH_TOKEN }}
Comment on lines +18 to +20
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
with:
project-url: ${{ inputs.PROJECT_URL }}
github-token: ${{ inputs.GH_TOKEN }}
with:
project-url: ${{ inputs.PROJECT_URL }}
github-token: ${{ inputs.GH_TOKEN }}
labeled: needs-refinement

53 changes: 53 additions & 0 deletions workflows/issue-triage/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Issue Triage Workflow

A reusable composite action that automatically labels new issues with `needs-triage` and posts a welcome comment directing the reporter to the [Issue Lifecycle documentation](../../ISSUE_LIFECYCLE.md).

## Usage

Create `.github/workflows/issue-triage.yaml` in your repository:

```yaml
name: Issue Triage
on:
issues:
types: [opened]

permissions:
issues: write

jobs:
triage:
runs-on: ubuntu-latest
steps:
- uses: cloudoperators/common/workflows/issue-triage@main
```

> **Important:** The calling workflow **must** declare `permissions: issues: write`. Without this, the action will fail in repos/orgs where the default `GITHUB_TOKEN` is read-only.

## What it does

1. Adds the `needs-triage` label to the newly opened issue
2. Posts a welcome comment with:
- Acknowledgment of the issue
- Link to the Issue Lifecycle documentation
- Reminder of what information helps with triage

## Prerequisites

- The `needs-triage` label must exist in the repository (see label setup below)
- The calling workflow must grant `permissions: issues: write`
- The default `GITHUB_TOKEN` is sufficient for the token — no additional secrets needed

Comment thread
uwe-mayer marked this conversation as resolved.
## Label Setup

Create the required label in your repository:

```bash
gh label create "needs-triage" --color "fbca04" --description "New issue, not yet reviewed" --repo cloudoperators/<repo-name>
```

## Inputs

| Input | Required | Default | Description |
|---|---|---|---|
| `GH_TOKEN` | No | `github.token` | GitHub token with issues write permission |
Loading