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
4 changes: 3 additions & 1 deletion skills/rhdh-jira/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ Before attempting any REST API or GraphQL call:
| `scripts/parse_issues.py` | Flatten, enrich, and filter acli JSON output. Solves the core problem: `acli search --json` can't return custom fields (team, story points, sprint). Pipe search results in, get clean data out. Use `--enrich` to fetch full fields, `-f team="X"` to filter by team. |
| `scripts/command-metadata.json` | Single source of truth for sub-command descriptions and argument hints. |
| `scripts/validate_components.py` | Validate `references/fields.md` component catalog against live Jira projects (RHIDP + RHDHPLAN). Reports drift in both directions. Run with `--json` for structured output. |
| `scripts/jira-wiki-to-adf.py` | Convert a filled Jira wiki markup template to Atlassian Document Format JSON for use with `acli --description-file`. Handles `hN.` headings, `* ` bullets, `# ` ordered lists, `(?)` / `(/)` task items, `*bold*`, `_italic_`, `{{monospace}}`, backtick code. Usage: `python scripts/jira-wiki-to-adf.py input.txt > output.adf.json` |

## Projects

Expand Down Expand Up @@ -150,7 +151,7 @@ Load only what the current task requires.
3. **`--yes` is mandatory for mutations.** All `edit`, `transition`, `assign`, and `link create` commands prompt interactively without it. Always pass `--yes`.
4. **`--fields` is restrictive on search.** Only accepts `key`, `summary`, `status`, `assignee`, `issuetype`, `priority`, `description`, `labels`. For components, sprint, fixVersions, and all custom fields — use `--json` or `scripts/parse_issues.py --enrich`.
5. **Team field has two JQL syntaxes.** `customfield_10001` cannot be used in JQL WHERE clauses. However, `"Team[Team]" = {teamId}` (using the team UUID, not display name) works. Use the UUID syntax for JQL filtering; use `customfield_10001.name` in post-processing only when you need the display name from JSON output.
6. **ADF vs plain text.** Reading descriptions via `--json` returns Atlassian Document Format (nested JSON). Creating/editing with `--description` accepts plain text. Don't try to round-trip ADF through `--description`.
6. **ADF is required for formatted descriptions.** Reading descriptions via `--json` returns Atlassian Document Format (nested JSON). Jira Cloud's editor is ADF-native — plain text and Jira wiki markup (`h1.`, `*bold*`) both render as literal characters in the UI. For formatted descriptions, fill a wiki markup template then run `scripts/jira-wiki-to-adf.py <input.txt> <output.json>` to convert to ADF, then pass via `--description-file`. Both `acli create` and `acli edit` accept ADF JSON via `--description-file`. Do not use Jira wiki markup in description files expecting it to render.
7. **Acceptance Criteria field is almost always null.** Scan the description for "Requirements", "Acceptance Criteria", or bullet-style criteria instead of checking `customfield_10718`.
8. **`--enrich` is MANDATORY for custom fields AND labels.** Both `acli search --json` and `acli view KEY --json` (without `--fields "*all"`) return only basic fields (assignee, issuetype, priority, status, summary). Labels, story points, team, sprint, size, and components will all appear as empty/null — looking like the data isn't set when it actually is. Always use `scripts/parse_issues.py --enrich` to get custom field data. Skipping `--enrich` is the #1 cause of false "missing data" reports.
9. **`acli` cannot set arbitrary custom fields.** `acli jira workitem edit` does not have a `--custom` flag. Fields like Team, Size, Story Points, and Release Note Type can only be updated via the Jira REST API. Use `PUT /rest/api/3/issue/{key}` with the field payload (see `references/rest-api-fallback.md` for curl examples and payload formats). Find the token file at `.jira-token` next to the `acli` executable (discover the path with `readlink -f "$(which acli)"` or `where acli`). Never read the token file into context.
Expand All @@ -162,6 +163,7 @@ Load only what the current task requires.
15. **Don't remove `rhdh-X.Y-candidate` labels.** Candidate labels track release targeting. Removing them without PM approval can silently drop a feature from release tracking.
16. **Feature→Epic child links use Parent Link, not issuelinks.** Cross-project parent-child relationships (RHDHPLAN Feature → RHIDP Epic) use the `Parent Link` field (`customfield_10018`), not `issuelinks`. To find child Epics of a Feature, use JQL: `project = RHIDP AND type = Epic AND "Parent Link" = RHDHPLAN-XXX`. Checking `issuelinks` will show zero results and produce false "no child Epics" reports.
17. **REST `/rest/api/3/search` returns 410 Gone.** This endpoint has been removed. Use POST to `/rest/api/3/search/jql` with body `{"jql": "...", "fields": [...], "maxResults": N}` instead. This only affects direct REST calls — `acli search` still works.
18. **`acli workitem create` does not support `--priority`, `--component`, or `--yes`.** These flags exist on `edit`, `transition`, and `assign` but not on `create` — passing them causes "unknown flag" errors. After creating an issue, set priority, components, size (`customfield_10795`), and parent link (`customfield_10018`) together in a single `PUT /rest/api/3/issue/{key}` call.

## Error Handling

Expand Down
2 changes: 1 addition & 1 deletion skills/rhdh-jira/references/acli-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ acli jira filter get --id 10001
| Labels | Not available via `--fields` | Array of strings |
| Fix versions | Not available via `--fields` | Array of version objects |

When writing descriptions, use `--description "plain text"`. When reading, be aware `--json` returns ADF — don't try to round-trip it.
When writing formatted descriptions, fill a wiki markup template then convert with `scripts/jira-wiki-to-adf.py` and pass via `--description-file` (see Gotcha #6 in SKILL.md). When reading, be aware `--json` returns ADF — don't try to round-trip it.

## Custom Fields and `--enrich`

Expand Down
15 changes: 12 additions & 3 deletions skills/rhdh-jira/references/support.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,14 @@ When a product defect is identified:
2. Comment on the RHDHSUPP issue with the RHDHBUGS link — this tells the customer when the fix is expected

```bash
# Create the bug
# Convert wiki markup to ADF (required — plain wiki text is not rendered by Jira)
BUG_ADF=$(mktemp) # on Windows: use %TEMP% or Python tempfile
python scripts/jira-wiki-to-adf.py bug_description.txt "$BUG_ADF"

# Create the bug (note: --yes does not exist on create, see Gotcha #18)
acli jira workitem create --project RHDHBUGS --type Bug \
--summary "Login fails when SSO token expires during session" \
--description-file bug_description.txt \
--description-file "$BUG_ADF" \
--label "rhdh-customer" \
--assignee "@me"

Expand All @@ -96,9 +100,14 @@ When a support case reveals a missing capability:
2. Encourage customer to follow up with their account team to prioritize with Product Management

```bash
# Convert wiki markup to ADF (required — plain wiki text is not rendered by Jira)
FEATURE_ADF=$(mktemp) # on Windows: use %TEMP% or Python tempfile
python scripts/jira-wiki-to-adf.py feature_request.txt "$FEATURE_ADF"

# Create the feature request (note: --yes does not exist on create, see Gotcha #18)
acli jira workitem create --project RHDHPLAN --type "Feature Request" \
--summary "Support OIDC token refresh in admin console" \
--description-file feature_request.txt
--description-file "$FEATURE_ADF"

acli jira workitem link create --out RHDHSUPP-456 --in RHDHPLAN-123 --type "Related" --yes
```
Expand Down
11 changes: 7 additions & 4 deletions skills/rhdh-jira/references/templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@ Implement SSO integration for admin console.
...
EOF

# Create the issue
# Convert wiki markup to ADF (required — plain wiki text is not rendered by Jira)
ISSUE_ADF=$(mktemp)
python scripts/jira-wiki-to-adf.py issue-desc.txt "$ISSUE_ADF"

# Create the issue (note: --yes does not exist on create, see Gotcha #18)
acli jira workitem create --project RHIDP --type Epic \
--summary "SSO Integration for Admin Console" \
--description-file issue-desc.txt \
--assignee "@me" \
--yes
--description-file "$ISSUE_ADF" \
--assignee "@me"
```

## Field Requirements at Creation
Expand Down
29 changes: 20 additions & 9 deletions skills/rhdh-jira/references/to-epic.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,27 +86,38 @@ Run the pre-creation check from `references/duplicates.md`. Search RHIDP Epics (

### Step 8 — Create Epic

Fill the template. Create the issue:
Fill the template. Then convert to ADF using the helper script (see Gotcha #6). `acli create` accepts ADF via `--description-file`:
Comment thread
johnmcollier marked this conversation as resolved.

```bash
EPIC_ADF=$(mktemp) # on Windows: use %TEMP% or Python tempfile
python scripts/jira-wiki-to-adf.py epic-filled.txt "$EPIC_ADF"
```

Create the issue — note `--priority`, `--component`, and `--yes` do not exist on `create` (see Gotcha #18):

```bash
acli jira workitem create --project RHIDP --type Epic \
--summary "Epic summary" \
--description-file /tmp/epic-desc.txt \
--assignee "ACCOUNT_ID" \
--priority "Major" \
--component "Plugins" \
--yes
--description-file "$EPIC_ADF" \
--assignee "ACCOUNT_ID"
```

If a parent Feature exists, link via REST:
Then set priority, components, size, and parent Feature link together in one REST call. Cross-project parent links accept either `customfield_10018` or `parent.key` — do not use `issuelinks` (see Gotcha #16):

```bash
curl -s -X PUT -u "$AUTH" -H "Content-Type: application/json" \
-d '{"fields": {"parent": {"key": "RHDHPLAN-XXX"}}}' \
-d '{
"fields": {
"priority": {"name": "Major"},
"components": [{"name": "Catalog"}],
"customfield_10795": {"value": "M"},
"customfield_10018": "RHDHPLAN-XXX"
}
}' \
"https://redhat.atlassian.net/rest/api/3/issue/RHIDP-XXX"
```

Set Team and Size via REST — follow API preference order in SKILL.md.
Set Team via REST — follow API preference order in SKILL.md.

### Step 9 — Comments

Expand Down
32 changes: 25 additions & 7 deletions skills/rhdh-jira/references/to-feature.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,37 @@ If a likely duplicate Feature is found, present it and ask: "This may already ex

### Step 7 — Create Feature

Fill the template with grill results. Save to a temp file. Create the issue:
Fill the template with grill results. Save to a temp file. Then convert to ADF using the helper script (see Gotcha #6). `acli create` accepts ADF via `--description-file`:

```bash
FEATURE_ADF=$(mktemp) # on Windows: use %TEMP% or Python tempfile
python scripts/jira-wiki-to-adf.py feature-filled.txt "$FEATURE_ADF"
```

Create the issue — note `--priority` and `--yes` do not exist on `create` (see Gotcha #18):

```bash
acli jira workitem create --project RHDHPLAN --type Feature \
--summary "Feature summary" \
--description-file /tmp/feature-desc.txt \
--description-file "$FEATURE_ADF" \
--assignee "ACCOUNT_ID" \
--priority "Major" \
--label "rhdh-2.1-candidate" \
--yes
--label "rhdh-2.1-candidate"
```

Then set priority, Team, and Size together in one REST call:

```bash
curl -s -X PUT -u "$AUTH" -H "Content-Type: application/json" \
-d '{
"fields": {
"priority": {"name": "Major"},
"customfield_10795": {"value": "M"}
}
}' \
"https://redhat.atlassian.net/rest/api/3/issue/RHDHPLAN-XXX"
```

Set additional fields via REST if needed (Team, Size) — follow API preference order in SKILL.md.
Set Team via REST — follow API preference order in SKILL.md.

### Step 8 — Comments

Expand All @@ -132,7 +150,7 @@ If yes:
2. For each team, invoke the `to-epic` workflow with context carried down from this Feature:
- The Feature's scope, AC, and customer considerations are established — don't re-grill on these
- The Epic grill narrows to: delivery scope for *this team*, dependencies, team-specific AC
3. Each Epic is automatically linked to the parent Feature via `parent` field
3. Each Epic is automatically linked to the parent Feature via `customfield_10018` (cross-project parent link — see Gotcha #16 and to-epic.md Step 8)

## Error Handling

Expand Down
43 changes: 28 additions & 15 deletions skills/rhdh-jira/references/to-issue.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,36 +119,49 @@ Run the pre-creation check from `references/duplicates.md`. Scope to the target

### Step 9 — Create Issue

Fill the template. Create the issue:
Fill the appropriate template (`assets/templates/story.txt`, `task.txt`, or `bug.txt`) with grill results, then convert to ADF using the helper script (see Gotcha #6). `acli create` accepts ADF via `--description-file`:

```bash
ISSUE_ADF=$(mktemp) # on Windows: use %TEMP% or Python tempfile
python scripts/jira-wiki-to-adf.py story-filled.txt "$ISSUE_ADF"
```

Create the issue — note `--priority`, `--component`, and `--yes` do not exist on `create` (see Gotcha #18):

```bash
# Story
acli jira workitem create --project RHIDP --type Story \
--summary "Story summary" \
--description-file /tmp/story-desc.txt \
--assignee "ACCOUNT_ID" \
--priority "Major" \
--component "Plugins" \
--yes
--description-file "$ISSUE_ADF" \
--assignee "ACCOUNT_ID"

# Bug (different project)
acli jira workitem create --project RHDHBUGS --type Bug \
--summary "Bug summary" \
--description-file /tmp/bug-desc.txt \
--priority "Critical" \
--yes
--description-file "$ISSUE_ADF"

# Spike (Task with prefix)
acli jira workitem create --project RHIDP --type Task \
--summary "SPIKE: Research multi-source catalog merging" \
--description-file /tmp/spike-desc.txt \
--assignee "ACCOUNT_ID" \
--priority "Major" \
--component "Plugins" \
--yes
--description-file "$ISSUE_ADF" \
--assignee "ACCOUNT_ID"
```

Then set priority, component, and story points together in one REST call:

```bash
curl -s -X PUT -u "$AUTH" -H "Content-Type: application/json" \
-d '{
"fields": {
"priority": {"name": "Major"},
"components": [{"name": "Plugins"}],
"customfield_10028": 5
}
}' \
"https://redhat.atlassian.net/rest/api/3/issue/RHIDP-YYY"
```

If a parent Epic exists, link via REST:
If a parent Epic exists, link via REST (same-project RHIDP→RHIDP uses native `parent` field):

```bash
curl -s -X PUT -u "$AUTH" -H "Content-Type: application/json" \
Expand Down
Loading
Loading