mirror of
https://github.com/penpot/penpot.git
synced 2026-09-14 07:59:36 +00:00
📎 Add create-issue skill
This commit is contained in:
parent
fdb5291384
commit
aadae99b91
27
.opencode/skills/create-issue/SKILL.md
Normal file
27
.opencode/skills/create-issue/SKILL.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
name: create-issue
|
||||||
|
description: Create or update GitHub issues (from PR, from draft body, retitle existing). Routes to the canonical flow in `mem:workflow/creating-issues`.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Skill: create-issue
|
||||||
|
|
||||||
|
Entry point for all GitHub issue work. All rules (title derivation, metadata,
|
||||||
|
body templates, Issue Type IDs), all flows, and all `gh` / GraphQL commands
|
||||||
|
live in `mem:workflow/creating-issues` (file:
|
||||||
|
`.serena/memories/workflow/creating-issues.md`). This skill routes to the
|
||||||
|
right flow.
|
||||||
|
|
||||||
|
## When to Use
|
||||||
|
|
||||||
|
- **Create from PR** — PR exists; the issue is the changelog/release unit,
|
||||||
|
the PR is the implementation. Issue = WHAT, PR = HOW.
|
||||||
|
→ memory section **Creating Issues from PRs**
|
||||||
|
- **Create from draft body** — Taiga story, user report, discussion; no PR
|
||||||
|
yet.
|
||||||
|
→ memory section **Creating Issues from Draft Body**
|
||||||
|
- **Retitle existing issue** — current title is vague, prefixed, or stale.
|
||||||
|
→ memory section **Retitling an Existing Issue**
|
||||||
|
|
||||||
|
Everything else (title derivation, metadata policy, body templates, Issue
|
||||||
|
Type IDs, create/verify/cleanup commands) lives in the memory — go to the
|
||||||
|
matching section there.
|
||||||
@ -1,227 +0,0 @@
|
|||||||
---
|
|
||||||
name: gh-issue-from-pr
|
|
||||||
description: Create a user-facing GitHub issue from a PR, separating the WHAT from the HOW, with correct milestone, project, labels, and issue type.
|
|
||||||
---
|
|
||||||
|
|
||||||
# Skill: gh-issue-from-pr
|
|
||||||
|
|
||||||
Create a GitHub issue that captures the **WHAT** (user-facing feature or
|
|
||||||
bug) from an existing PR that describes the **HOW** (implementation).
|
|
||||||
Used when the project board needs an issue as the primary changelog/release unit.
|
|
||||||
|
|
||||||
## When to Use
|
|
||||||
|
|
||||||
- Create a tracking issue from a PR for changelog purposes
|
|
||||||
- Extract the user-facing problem/feature from a PR's implementation details
|
|
||||||
- Assign milestone, project, labels, and issue type to a new issue derived from a PR
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
- `gh` CLI authenticated (`gh auth status`)
|
|
||||||
- Permission to create issues and edit PRs in the target repository
|
|
||||||
|
|
||||||
## Workflow
|
|
||||||
|
|
||||||
### 1. Understand the PR
|
|
||||||
|
|
||||||
```bash
|
|
||||||
gh pr view <PR_NUMBER> --repo penpot/penpot \
|
|
||||||
--json title,body,author,labels,baseRefName,mergedAt,state,milestone
|
|
||||||
```
|
|
||||||
|
|
||||||
Identify:
|
|
||||||
|
|
||||||
- **WHAT** — user-facing problem or feature. Goes into the issue.
|
|
||||||
Describe symptoms and impact, not internal mechanisms.
|
|
||||||
- **HOW** — implementation details. These belong in the PR, not the issue.
|
|
||||||
|
|
||||||
### 2. Determine metadata
|
|
||||||
|
|
||||||
| Field | Source | Rule |
|
|
||||||
|-------|--------|------|
|
|
||||||
| **Title** | PR title | Rewrite from user perspective. Strip leading emoji prefixes (`:bug:`, `:sparkles:`, `:tada:`). Focus on observable behavior. Use imperative mood. Use the `issue-title` skill to generate this. |
|
|
||||||
| **Labels** | PR labels | Copy `community contribution` if present. Skip `bug` and `enhancement` (redundant with Issue Type). Skip workflow labels (`backport candidate`, `team-qa`). |
|
|
||||||
| **Milestone** | PR milestone | **Always copy what's on the PR.** Fetch with: `gh pr view <PR_NUMBER> --json milestone --jq '.milestone.title'` If the PR has no milestone, create the issue without one. |
|
|
||||||
| **Project** | Always `Main` | Penpot uses the `Main` project (number 8) for all issues. |
|
|
||||||
| **Body** | PR's user-facing section | Extract steps to reproduce or feature description. Omit internal details. Use templates below. |
|
|
||||||
| **Issue Type** | PR labels / title | Map: `bug` label or `:bug:` title → `Bug`. `enhancement` label or `:sparkles:` title → `Enhancement`. Feature/epic → `Feature`. Default → `Task`. |
|
|
||||||
|
|
||||||
### 3. Write the issue body
|
|
||||||
|
|
||||||
**Bug template:**
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
### Description
|
|
||||||
|
|
||||||
<what breaks, what the user experiences>
|
|
||||||
|
|
||||||
### Steps to reproduce
|
|
||||||
|
|
||||||
1. <step 1>
|
|
||||||
2. <step 2>
|
|
||||||
|
|
||||||
### Expected behavior
|
|
||||||
|
|
||||||
<what should happen instead>
|
|
||||||
|
|
||||||
### Affected versions
|
|
||||||
|
|
||||||
<version>
|
|
||||||
```
|
|
||||||
|
|
||||||
**Enhancement template:**
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
### Description
|
|
||||||
|
|
||||||
<what the user can now do that they couldn't before>
|
|
||||||
|
|
||||||
### Use case
|
|
||||||
|
|
||||||
<why this is useful, who benefits>
|
|
||||||
|
|
||||||
### Affected versions
|
|
||||||
|
|
||||||
<version>
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Create the issue
|
|
||||||
|
|
||||||
Write the body to a temp file to avoid shell quoting issues:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cat > /tmp/issue-body.md << 'ISSUE_BODY'
|
|
||||||
<body content here>
|
|
||||||
ISSUE_BODY
|
|
||||||
```
|
|
||||||
|
|
||||||
Create:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
gh issue create \
|
|
||||||
--repo penpot/penpot \
|
|
||||||
--title "<Title>" \
|
|
||||||
--label "community contribution" \ # only if PR has this label
|
|
||||||
--milestone "<milestone>" \
|
|
||||||
--project "Main" \
|
|
||||||
--body-file /tmp/issue-body.md
|
|
||||||
```
|
|
||||||
|
|
||||||
Output: `https://github.com/penpot/penpot/issues/<NUMBER>`
|
|
||||||
|
|
||||||
### 5. Assign to the PR author
|
|
||||||
|
|
||||||
Assign the issue to the PR author so they're responsible for it:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
AUTHOR=$(gh pr view <PR_NUMBER> --repo penpot/penpot --json author --jq '.author.login')
|
|
||||||
gh issue edit <ISSUE_NUMBER> --repo penpot/penpot --add-assignee "$AUTHOR"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 6. Set the Issue Type
|
|
||||||
|
|
||||||
`gh issue create` can't set the Issue Type directly. Use GraphQL.
|
|
||||||
|
|
||||||
Get the issue's GraphQL node ID:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
ISSUE_ID=$(gh api graphql -f query='
|
|
||||||
query { repository(owner: "penpot", name: "penpot") {
|
|
||||||
issue(number: <ISSUE_NUMBER>) { id }
|
|
||||||
}}' --jq '.data.repository.issue.id')
|
|
||||||
```
|
|
||||||
|
|
||||||
Issue Type IDs for the Penpot repo:
|
|
||||||
|
|
||||||
| Type | ID |
|
|
||||||
|------|----|
|
|
||||||
| Bug | `IT_kwDOAcyBPM4AX5Nb` |
|
|
||||||
| Enhancement | `IT_kwDOAcyBPM4B_IQN` |
|
|
||||||
| Feature | `IT_kwDOAcyBPM4AX5Nf` |
|
|
||||||
| Task | `IT_kwDOAcyBPM4AX5NY` |
|
|
||||||
| Question | `IT_kwDOAcyBPM4B_IQj` |
|
|
||||||
| Docs | `IT_kwDOAcyBPM4B_IQz` |
|
|
||||||
|
|
||||||
Set it:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
gh api graphql -f query='
|
|
||||||
mutation {
|
|
||||||
updateIssue(input: {
|
|
||||||
id: "'"$ISSUE_ID"'"
|
|
||||||
issueTypeId: "<TYPE_ID>"
|
|
||||||
}) {
|
|
||||||
issue { number issueType { name } }
|
|
||||||
}
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
### 7. Verify
|
|
||||||
|
|
||||||
```bash
|
|
||||||
gh issue view <ISSUE_NUMBER> --repo penpot/penpot \
|
|
||||||
--json title,milestone,projectItems,labels \
|
|
||||||
--jq '{title, milestone: .milestone.title, projects: [.projectItems[].title], labels: [.labels[].name]}'
|
|
||||||
|
|
||||||
gh api graphql -f query='
|
|
||||||
query { repository(owner: "penpot", name: "penpot") {
|
|
||||||
issue(number: <ISSUE_NUMBER>) { issueType { name } }
|
|
||||||
}}' --jq '.data.repository.issue.issueType.name'
|
|
||||||
```
|
|
||||||
|
|
||||||
### 8. Link the PR to the issue
|
|
||||||
|
|
||||||
Append `Closes #<ISSUE_NUMBER>` to the PR body:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
gh pr view <PR_NUMBER> --repo penpot/penpot --json body --jq '.body' > /tmp/pr-body.md
|
|
||||||
printf "\n\nCloses #<ISSUE_NUMBER>\n" >> /tmp/pr-body.md
|
|
||||||
gh pr edit <PR_NUMBER> --repo penpot/penpot --body-file /tmp/pr-body.md
|
|
||||||
|
|
||||||
# Verify
|
|
||||||
gh pr view <PR_NUMBER> --repo penpot/penpot --json body \
|
|
||||||
--jq '.body | test("Closes #<ISSUE_NUMBER>")'
|
|
||||||
```
|
|
||||||
|
|
||||||
**Note:** If the PR is already merged, `Closes` won't auto-close the issue
|
|
||||||
— it only creates the "Development" sidebar link. This is the desired
|
|
||||||
behavior since the issue is a tracking artifact.
|
|
||||||
|
|
||||||
### 9. Clean up
|
|
||||||
|
|
||||||
```bash
|
|
||||||
rm -f /tmp/issue-body.md /tmp/pr-body.md
|
|
||||||
```
|
|
||||||
|
|
||||||
## Label rules
|
|
||||||
|
|
||||||
| PR has | Issue gets |
|
|
||||||
|--------|-----------|
|
|
||||||
| `community contribution` | `community contribution` |
|
|
||||||
| `bug`, `enhancement` | *(skip — redundant with Issue Type)* |
|
|
||||||
| `backport candidate` | *(skip — workflow label)* |
|
|
||||||
| `team-qa` | *(skip — workflow label)* |
|
|
||||||
|
|
||||||
## Issue Type mapping
|
|
||||||
|
|
||||||
| PR label(s) / title prefix | Issue Type |
|
|
||||||
|----------------------------|-----------|
|
|
||||||
| `bug` or `:bug:` | Bug |
|
|
||||||
| `enhancement` or `:sparkles:` or `:tada:` | Enhancement |
|
|
||||||
| Feature / epic | Feature |
|
|
||||||
| Documentation | Docs |
|
|
||||||
| None of the above | Task |
|
|
||||||
|
|
||||||
## Key Principles
|
|
||||||
|
|
||||||
- **Issue = WHAT, PR = HOW.** Never put implementation details in the
|
|
||||||
issue body. The issue is for users, QA, and changelog readers.
|
|
||||||
- **Copy the milestone from the PR.** Don't guess based on branch names.
|
|
||||||
If the PR has no milestone, create the issue without one.
|
|
||||||
- **Set Issue Type via GraphQL** — `gh issue create` can't set it.
|
|
||||||
- **Link via PR body** — `Closes #<NUMBER>` creates the "Development"
|
|
||||||
sidebar link automatically.
|
|
||||||
- **One issue per PR** — even if a PR fixes multiple things, create a
|
|
||||||
single issue that summarizes the overall change.
|
|
||||||
- **Community attribution:** if the PR has the `community contribution`
|
|
||||||
label or the author is not a core team member, add the label to the issue.
|
|
||||||
@ -1,123 +0,0 @@
|
|||||||
---
|
|
||||||
name: issue-title
|
|
||||||
description: Derive a clear, well-formatted title for a GitHub issue from its description body, using descriptive present-tense for bugs and imperative mood for features, always including the "where" (location in the UI/module).
|
|
||||||
---
|
|
||||||
|
|
||||||
# Skill: issue-title
|
|
||||||
|
|
||||||
Derive a concise, descriptive title for a GitHub issue based on its body
|
|
||||||
content. Use **descriptive present tense for bugs** (e.g. "Plugin API
|
|
||||||
crashes when setting text fills") and **imperative mood for features** (e.g.
|
|
||||||
"Add customizable dash and gap controls"). No emoji or type prefixes
|
|
||||||
(`feat:`, `bug:`, `feature:`, etc.).
|
|
||||||
|
|
||||||
Can be used both when **creating a new issue** and when **updating an
|
|
||||||
existing one** that has a vague or outdated title.
|
|
||||||
|
|
||||||
## When to Use
|
|
||||||
|
|
||||||
- Creating a new issue and need a well-formatted title from the draft body
|
|
||||||
- An existing issue has a vague, outdated, or auto-generated title (e.g.
|
|
||||||
`[PENPOT FEEDBACK]: ...`, `feature: ...`)
|
|
||||||
- The current title doesn't reflect the actual content of the description
|
|
||||||
- The title is missing the "where" (which part of the UI/module is affected)
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
- `gh` CLI authenticated (`gh auth status`)
|
|
||||||
|
|
||||||
## Workflow
|
|
||||||
|
|
||||||
### 1. Get the issue body
|
|
||||||
|
|
||||||
For an **existing issue**, fetch it:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
gh issue view <NUMBER> --repo penpot/penpot --json title,body
|
|
||||||
```
|
|
||||||
|
|
||||||
For a **new issue**, read the draft body from wherever it was provided
|
|
||||||
(Taiga link, user report, discussion, etc.).
|
|
||||||
|
|
||||||
### 2. Read the body and derive a title
|
|
||||||
|
|
||||||
Extract the core problem or request from the description. Distinguish between
|
|
||||||
bug reports and feature requests:
|
|
||||||
|
|
||||||
**Bug titles (descriptive, present tense):**
|
|
||||||
Describe the symptom as it appears to the user. Format:
|
|
||||||
`[Where] [present-tense verb] when [condition]`
|
|
||||||
|
|
||||||
- *"Plugin API crashes when setting text fills"*
|
|
||||||
- *"Canvas renders glitches when zooming quickly"*
|
|
||||||
- *"French Canada locale falls back to French (fr) translations"*
|
|
||||||
- *"Text layer content is not deleted when WebGL render is enabled"*
|
|
||||||
|
|
||||||
Do **not** start bug titles with "Fix" or any imperative verb. The title
|
|
||||||
should state what's broken, not command a fix.
|
|
||||||
|
|
||||||
**Feature / Enhancement titles (imperative mood):**
|
|
||||||
Command what should be built. Format:
|
|
||||||
`[Imperative verb] [what] in/on [where]`
|
|
||||||
|
|
||||||
- *"Add customizable dash and gap length controls to dashed strokes in the sidebar"*
|
|
||||||
- *"Show user, timestamp, and hash in the workspace history panel like git commits"*
|
|
||||||
- *"Validate shape on add-object to catch malformed inputs early"*
|
|
||||||
|
|
||||||
**Universal rules (both types):**
|
|
||||||
- **Include the "where"** — specify the UI location or module (e.g.
|
|
||||||
"in the sidebar", "in the workspace history panel", "on the stroke
|
|
||||||
options")
|
|
||||||
- **No prefixes** — strip `bug:`, `feature:`, `feat:`, `:bug:`, `:sparkles:`,
|
|
||||||
`[PENPOT FEEDBACK]`, etc.
|
|
||||||
- **No emoji** — plain text only
|
|
||||||
- **Be specific** — prefer concrete detail over generality. If the
|
|
||||||
description mentions two related problems, capture both.
|
|
||||||
|
|
||||||
**Examples:**
|
|
||||||
|
|
||||||
| Original / draft title | Type | New title |
|
|
||||||
|---|---|---|
|
|
||||||
| `[PENPOT FEEDBACK]: WebGL` | Bug | `Canvas renders glitches when zooming quickly — text appears distorted and nodes have background-colored rectangles` |
|
|
||||||
| `bug: flatten-nested-tokens-json uses $type instead of $value as the DTCG token/group discriminator` | Bug | `Token import fails when group-level type inheritance is used — parser misidentifies groups as tokens` |
|
|
||||||
| `feature: Dashed stroke customization` | Feature | `Add customizable dash and gap length controls to dashed strokes in the sidebar` |
|
|
||||||
| `feature: Add more detail to history of actions` | Feature | `Show user, timestamp, and hash in the workspace history panel like git commits` |
|
|
||||||
|
|
||||||
### 3. Apply the title
|
|
||||||
|
|
||||||
**If updating an existing issue:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
gh issue edit <NUMBER> --repo penpot/penpot --title "<NEW TITLE>"
|
|
||||||
```
|
|
||||||
|
|
||||||
**If creating a new issue:**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
gh issue create --repo penpot/penpot --title "<NEW TITLE>" --body "<BODY>"
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. Confirm
|
|
||||||
|
|
||||||
For updates, the command returns the issue URL. Verify by optionally fetching
|
|
||||||
again:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
gh issue view <NUMBER> --repo penpot/penpot --json title
|
|
||||||
```
|
|
||||||
|
|
||||||
## Key Principles
|
|
||||||
|
|
||||||
- **Bug titles describe the symptom** — present tense, 3rd person:
|
|
||||||
"crashes", "fails", "shows", "is cut off", "does not load". Do not
|
|
||||||
start with "Fix" or "Bug:".
|
|
||||||
- **Feature titles use imperative mood** — command form: "Add", "Show",
|
|
||||||
"Use", "Validate", "Support", "Toggle".
|
|
||||||
- **Always include the "where"** — a title like "Crashes when zooming"
|
|
||||||
is too vague; "Canvas crashes when zooming quickly" is clear.
|
|
||||||
- **No prefixes, no emoji** — strip all type labels and decorative
|
|
||||||
characters from the title.
|
|
||||||
- **Derive from the body, not the current title** — the body contains
|
|
||||||
the real detail; the current title may be auto-generated or stale.
|
|
||||||
- **Two problems → cover both** — if the description has two distinct
|
|
||||||
but related issues, capture both in the title joined by "and".
|
|
||||||
@ -155,6 +155,199 @@ query { repository(owner: "penpot", name: "penpot") {
|
|||||||
rm -f /tmp/issue-body.md
|
rm -f /tmp/issue-body.md
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Creating Issues from PRs
|
||||||
|
|
||||||
|
Used when the project board needs an issue as the primary changelog/release
|
||||||
|
unit and the PR describes the implementation. The issue is the **WHAT**
|
||||||
|
(user-facing), the PR is the **HOW** (implementation).
|
||||||
|
|
||||||
|
### Fetch the PR
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gh pr view <PR_NUMBER> --repo penpot/penpot \
|
||||||
|
--json title,body,author,labels,baseRefName,mergedAt,state,milestone
|
||||||
|
```
|
||||||
|
|
||||||
|
Identify:
|
||||||
|
|
||||||
|
- **WHAT** — user-facing problem or feature. Goes into the issue.
|
||||||
|
Describe symptoms and impact, not internal mechanisms.
|
||||||
|
- **HOW** — implementation details. These belong in the PR, not the issue.
|
||||||
|
|
||||||
|
### Determine metadata
|
||||||
|
|
||||||
|
- **Title:** rewrite from user perspective using the title rules above. Strip
|
||||||
|
leading emoji prefixes (`:bug:`, `:sparkles:`, `:tada:`). Focus on
|
||||||
|
observable behavior.
|
||||||
|
- **Labels:** copy `community contribution` if present on the PR.
|
||||||
|
- **Milestone:** always copy what's on the PR.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gh pr view <PR_NUMBER> --json milestone --jq '.milestone.title'
|
||||||
|
```
|
||||||
|
|
||||||
|
If the PR has no milestone, create the issue without one.
|
||||||
|
- **Project:** `Main`.
|
||||||
|
- **Body:** extract the user-facing section (steps to reproduce or feature
|
||||||
|
description). Omit internal details. Use the templates above.
|
||||||
|
- **Issue Type:** use the mapping table above (also handles `:bug:` /
|
||||||
|
`:sparkles:` / `:tada:` title prefixes).
|
||||||
|
|
||||||
|
### Create the issue
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat > /tmp/issue-body.md << 'ISSUE_BODY'
|
||||||
|
<body content here>
|
||||||
|
ISSUE_BODY
|
||||||
|
|
||||||
|
gh issue create \
|
||||||
|
--repo penpot/penpot \
|
||||||
|
--title "<Title>" \
|
||||||
|
--label "community contribution" \ # only if PR has this label
|
||||||
|
--milestone "<milestone>" \
|
||||||
|
--project "Main" \
|
||||||
|
--body-file /tmp/issue-body.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Output: `https://github.com/penpot/penpot/issues/<NUMBER>`
|
||||||
|
|
||||||
|
### Assign to the PR author
|
||||||
|
|
||||||
|
```bash
|
||||||
|
AUTHOR=$(gh pr view <PR_NUMBER> --repo penpot/penpot --json author --jq '.author.login')
|
||||||
|
gh issue edit <ISSUE_NUMBER> --repo penpot/penpot --add-assignee "$AUTHOR"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Set Issue Type and verify
|
||||||
|
|
||||||
|
See the **Setting the Issue Type** and **Verification** sections above — the
|
||||||
|
GraphQL mutations and `gh issue view` calls are identical regardless of how
|
||||||
|
the issue was sourced.
|
||||||
|
|
||||||
|
### Link the PR to the issue
|
||||||
|
|
||||||
|
Append `Closes #<ISSUE_NUMBER>` to the PR body:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gh pr view <PR_NUMBER> --repo penpot/penpot --json body --jq '.body' > /tmp/pr-body.md
|
||||||
|
printf "\n\nCloses #<ISSUE_NUMBER>\n" >> /tmp/pr-body.md
|
||||||
|
gh pr edit <PR_NUMBER> --repo penpot/penpot --body-file /tmp/pr-body.md
|
||||||
|
|
||||||
|
# Verify
|
||||||
|
gh pr view <PR_NUMBER> --repo penpot/penpot --json body \
|
||||||
|
--jq '.body | test("Closes #<ISSUE_NUMBER>")'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** If the PR is already merged, `Closes` won't auto-close the issue —
|
||||||
|
it only creates the "Development" sidebar link. This is the desired
|
||||||
|
behavior since the issue is a tracking artifact.
|
||||||
|
|
||||||
|
### Clean up
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rm -f /tmp/issue-body.md /tmp/pr-body.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rules for this flow
|
||||||
|
|
||||||
|
- **One issue per PR** — even if a PR fixes multiple things, create a single
|
||||||
|
issue that summarizes the overall change.
|
||||||
|
- **Community attribution:** if the PR has the `community contribution`
|
||||||
|
label or the author is not a core team member, add the label to the issue.
|
||||||
|
- **Don't put implementation details in the issue body** — the issue is for
|
||||||
|
users, QA, and changelog readers.
|
||||||
|
|
||||||
|
## Creating Issues from Draft Body
|
||||||
|
|
||||||
|
Used when the user provides a draft body from elsewhere (Taiga story, user
|
||||||
|
report, discussion transcript) and there is no PR yet.
|
||||||
|
|
||||||
|
### Get the body
|
||||||
|
|
||||||
|
Read the draft body from wherever it was provided. If the user gives only a
|
||||||
|
vague one-liner, ask them to expand it (steps to reproduce, expected vs.
|
||||||
|
actual, use case) before proceeding.
|
||||||
|
|
||||||
|
### Derive the title
|
||||||
|
|
||||||
|
Apply the title rules in the **Title Derivation** section above. Distinguish
|
||||||
|
bug vs. feature from the body content:
|
||||||
|
|
||||||
|
- Steps to reproduce + expected vs. actual → bug
|
||||||
|
- "would be nice", "add support for", "allow users to" → feature / enhancement
|
||||||
|
|
||||||
|
### Choose a body template
|
||||||
|
|
||||||
|
Use the bug or enhancement template from the **Issue Body Template** section
|
||||||
|
above. Fill in placeholders with the user-provided details. If the body
|
||||||
|
doesn't fit either, ask the user which template to use.
|
||||||
|
|
||||||
|
### Determine metadata
|
||||||
|
|
||||||
|
- **Project:** `Main` (always).
|
||||||
|
- **Milestone:** ask the user if not obvious; otherwise omit.
|
||||||
|
- **Labels:** usually none for new user-reported issues. Add
|
||||||
|
`community contribution` if the user is a non-team contributor.
|
||||||
|
- **Issue Type:** use the mapping table above (bug description → Bug; feature
|
||||||
|
request → Enhancement or Feature).
|
||||||
|
|
||||||
|
### Create the issue
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat > /tmp/issue-body.md << 'ISSUE_BODY'
|
||||||
|
<body content here>
|
||||||
|
ISSUE_BODY
|
||||||
|
|
||||||
|
gh issue create \
|
||||||
|
--repo penpot/penpot \
|
||||||
|
--title "<Title>" \
|
||||||
|
--label "community contribution" \ # only if applicable
|
||||||
|
--milestone "<milestone>" \ # only if provided
|
||||||
|
--project "Main" \
|
||||||
|
--body-file /tmp/issue-body.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Set Issue Type and verify
|
||||||
|
|
||||||
|
Same GraphQL mutation and `gh issue view` commands as in the
|
||||||
|
**Setting the Issue Type** and **Verification** sections above.
|
||||||
|
|
||||||
|
### Clean up
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rm -f /tmp/issue-body.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Retitling an Existing Issue
|
||||||
|
|
||||||
|
Used when an issue's current title is vague, prefixed, or no longer matches
|
||||||
|
the body (e.g. `[PENPOT FEEDBACK]: ...`, `feature: ...`).
|
||||||
|
|
||||||
|
### Fetch the issue
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gh issue view <NUMBER> --repo penpot/penpot --json title,body
|
||||||
|
```
|
||||||
|
|
||||||
|
### Derive a new title
|
||||||
|
|
||||||
|
Read the body (not the current title) and apply the title rules in the
|
||||||
|
**Title Derivation** section above.
|
||||||
|
|
||||||
|
### Apply the new title
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gh issue edit <NUMBER> --repo penpot/penpot --title "<NEW TITLE>"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Confirm
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gh issue view <NUMBER> --repo penpot/penpot --json title
|
||||||
|
```
|
||||||
|
|
||||||
## See Also
|
## See Also
|
||||||
|
|
||||||
- Creating issues **from PRs** (separating WHAT from HOW): `mem:workflow/creating-prs`
|
- End-to-end orchestration entry point: the `create-issue` skill at
|
||||||
|
`.opencode/skills/create-issue/SKILL.md`. The skill is a thin entry
|
||||||
|
point; this memory is the canonical home for all issue-creation rules.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user