|
| 1 | +--- |
| 2 | +name: prep-product-update |
| 3 | +description: Use when the user shares an OpenMetadata GitHub release link (github.com/open-metadata/OpenMetadata/releases/tag/X.Y.Z-release) or the product-updates page URL for a version, and wants the site's product update page prepared. Also use when asked to "prep the product update", "draft the changelog", "add release notes", or "generate the release page" for a new version of open-metadata-site. |
| 4 | +--- |
| 5 | + |
| 6 | +# Prep OpenMetadata Product Update |
| 7 | + |
| 8 | +## Overview |
| 9 | + |
| 10 | +The user maintains open-metadata-site (this repo). Each OpenMetadata release needs a matching markdown file under `content/product-updates/` and a metadata entry in `content/product-updates/versions.json`. This skill takes a release identifier (a GitHub release URL or the product-updates page URL) and produces both files in the exact style the site already uses. |
| 11 | + |
| 12 | +## Inputs Accepted |
| 13 | + |
| 14 | +- `https://github.com/open-metadata/OpenMetadata/releases/tag/X.Y.Z-release` |
| 15 | +- `https://open-metadata.org/product-updates#vX.Y.Z-changelog` |
| 16 | +- Bare version + link — anything containing `X.Y.Z` is enough to derive the tag. |
| 17 | + |
| 18 | +## Workflow |
| 19 | + |
| 20 | +Follow these steps in order. Do not skip. |
| 21 | + |
| 22 | +### 1. Parse the version |
| 23 | + |
| 24 | +Extract `X.Y.Z` from the link. The GitHub tag is `X.Y.Z-release`. The site version string is `vX.Y.Z`. The file is `content/product-updates/vX.Y.Z.md`. |
| 25 | + |
| 26 | +### 2. Confirm the previous release |
| 27 | + |
| 28 | +Read `content/product-updates/versions.json` to find the most recent published version. Use its tag (e.g. `1.13.3-release`) as the base for the GitHub compare. Note its `id` — the new file's `id` is `max(id) + 1`. |
| 29 | + |
| 30 | +### 3. Pull the release notes and commit list |
| 31 | + |
| 32 | +Try the release body first: |
| 33 | + |
| 34 | +```bash |
| 35 | +rtk gh api repos/open-metadata/OpenMetadata/releases/tags/X.Y.Z-release | jq -r '.body' |
| 36 | +``` |
| 37 | + |
| 38 | +If `body` is `null` or empty (common when the release is still being cut), fall back to the compare API and paginate manually — 100 per page — because releases regularly exceed 100 commits and `--paginate` gets swallowed by rtk's jq filter: |
| 39 | + |
| 40 | +```bash |
| 41 | +gh api "repos/open-metadata/OpenMetadata/compare/PREV-release...X.Y.Z-release?per_page=100&page=1" > /tmp/p1.json |
| 42 | +gh api "repos/open-metadata/OpenMetadata/compare/PREV-release...X.Y.Z-release?per_page=100&page=2" > /tmp/p2.json |
| 43 | +jq -r '.commits[] | "\(.sha[0:8]) \(.commit.message | split("\n")[0])"' /tmp/p*.json > /tmp/commits.txt |
| 44 | +``` |
| 45 | + |
| 46 | +Check `.total_commits` first to know how many pages to fetch. |
| 47 | + |
| 48 | +### 4. Read the previous version file as a style reference |
| 49 | + |
| 50 | +`content/product-updates/vPREV.md` shows the exact tone, grouping, and formatting for a maintenance release. Match it: |
| 51 | + |
| 52 | +- **One-sentence release summary** at the top of `## Changelog`, calling out the themes (e.g. "connector reliability, search and lineage correctness, governance workflow stability"). |
| 53 | +- **Group by area** using the emoji headings from `content/product-updates/README.md`: |
| 54 | + - 🔌 Connectors & Ingestion |
| 55 | + - 📊 Data Quality |
| 56 | + - 🔍 Search & Discovery |
| 57 | + - 🛡️ Data Governance & Quality |
| 58 | + - 🔗 Lineage |
| 59 | + - 🤖 MCP Server / Automations |
| 60 | + - 🔐 Authentication |
| 61 | + - ⚙️ Platform |
| 62 | + - 🎛️ UI |
| 63 | + - 🔒 Security |
| 64 | + - 📣 Notifications |
| 65 | + - ⚠️ Backward Incompatible Changes (only if present) |
| 66 | +- **Each bullet is one line**: `**Short problem statement** [#PR](url): what the fix does + why it matters.` Focus on user-facing symptoms, not internal refactors. |
| 67 | + |
| 68 | +### 5. Filter commits |
| 69 | + |
| 70 | +Drop from the changelog: |
| 71 | + |
| 72 | +- CI / workflow tweaks (`ci:`, `test(playwright):`, `test(e2e):`, `fix(e2e):`, `chore:`, `build fix`, `nit`, "Revert" followed by a re-apply) |
| 73 | +- Merge commits and branch rebases |
| 74 | +- Version bump commit itself (`chore(release): bump version to X.Y.Z`) |
| 75 | +- Test flake fixes that don't affect end users |
| 76 | +- Anything that got reverted with no re-apply |
| 77 | + |
| 78 | +Keep: |
| 79 | + |
| 80 | +- Connector fixes with a named connector (Snowflake, Databricks, Oracle, BigQuery, MLflow, Tableau, Trino, Unity Catalog, Fivetran, KafkaConnect, ADLS, BurstIQ, etc.) |
| 81 | +- Security bumps that clear a specific CVE or upgrade a runtime (Debian, Python, netty, thrift, BouncyCastle, httpclient5, c3p0, sqlparse, libthrift, etc.) — group these together under 🔒 Security |
| 82 | +- Search, lineage, governance, workflow, and MCP fixes |
| 83 | +- Backend fixes with visible impact (async delete, pagination, API endpoints, permissions) |
| 84 | +- Real UI regressions and new UI affordances |
| 85 | +- **Migrations** — always call these out (search for "migration" in the commit body if unsure) |
| 86 | +- Anything explicitly marked "Fixes #NNNN" |
| 87 | + |
| 88 | +If a fix was reverted, then re-applied later in the same release, cite the final PR only. |
| 89 | + |
| 90 | +### 6. Look up PR titles when unclear |
| 91 | + |
| 92 | +The commit subject is usually enough. If a subject is opaque, fetch the PR body: |
| 93 | + |
| 94 | +```bash |
| 95 | +gh pr view NNNN --repo open-metadata/OpenMetadata --json title,body |
| 96 | +``` |
| 97 | + |
| 98 | +Do this sparingly — batch grouping decisions from the subjects first. |
| 99 | + |
| 100 | +### 7. Write the file |
| 101 | + |
| 102 | +Path: `content/product-updates/vX.Y.Z.md`. Frontmatter: |
| 103 | + |
| 104 | +```markdown |
| 105 | +--- |
| 106 | +id: NEXT_ID |
| 107 | +version: vX.Y.Z |
| 108 | +date: Released on Nth <Month> YYYY. |
| 109 | +--- |
| 110 | +``` |
| 111 | + |
| 112 | +- `date` — parse the release's `published_at` from the GitHub API. Format is the site's convention: `Released on 21st August 2026.` with ordinal suffix (`1st`, `2nd`, `3rd`, `4th`…). |
| 113 | +- Body starts with `## Changelog` on line 8 (one blank line above), matching the previous file. |
| 114 | + |
| 115 | +### 8. Update versions.json |
| 116 | + |
| 117 | +Prepend the new version to the array in `content/product-updates/versions.json`: |
| 118 | + |
| 119 | +```json |
| 120 | +{ |
| 121 | + "version": "vX.Y.Z", |
| 122 | + "date": "Released on Nth <Month> YYYY.", |
| 123 | + "hasFeatures": false |
| 124 | +}, |
| 125 | +``` |
| 126 | + |
| 127 | +Set `hasFeatures` to `true` only if the release has a `## Features` section with actual product features (not maintenance fixes). For every `X.Y.Z` patch release, `hasFeatures` is `false`. |
| 128 | + |
| 129 | +### 9. Verify |
| 130 | + |
| 131 | +Before reporting done: |
| 132 | + |
| 133 | +- `rtk proxy grep "^id:" content/product-updates/*.md | sort -t: -k2 -n | tail` — confirm no duplicate IDs. |
| 134 | +- Open `versions.json` and check the new entry is first and the JSON is still valid. |
| 135 | +- Skim the generated markdown once — every bullet should read as a sentence a user cares about, every link should point at a real PR. |
| 136 | + |
| 137 | +## Style Rules (do not violate) |
| 138 | + |
| 139 | +- **One line per fix.** No sub-bullets, no paragraphs. |
| 140 | +- **Bold the problem, not the fix.** Users scan for symptoms. |
| 141 | +- **Cite the merged PR**, not the linked issue. Link format: `[#NNNNN](https://github.com/open-metadata/OpenMetadata/pull/NNNNN)`. |
| 142 | +- **Never fabricate PR numbers.** If you can't find the PR, leave the commit SHA link: `[\`abcdef12\`](https://github.com/open-metadata/OpenMetadata/commit/abcdef12345…)`. |
| 143 | +- **No emojis in bullet text**, only in section headings. |
| 144 | +- **No "we", "our", "the team".** Third-person, present tense. |
| 145 | +- **Group carry-forwards from the previous release only when they were actively reinforced** (a follow-up fix in this release). Otherwise skip — don't rehash last version's changelog. |
| 146 | + |
| 147 | +## Quick Reference |
| 148 | + |
| 149 | +| Task | Command | |
| 150 | +|---|---| |
| 151 | +| Release body | `gh api repos/open-metadata/OpenMetadata/releases/tags/X.Y.Z-release \| jq -r '.body'` | |
| 152 | +| Compare commits | `gh api "repos/open-metadata/OpenMetadata/compare/PREV-release...X.Y.Z-release?per_page=100&page=N"` | |
| 153 | +| PR detail | `gh pr view NNNN --repo open-metadata/OpenMetadata --json title,body` | |
| 154 | +| Next id | `grep "^id:" content/product-updates/*.md \| awk -F: '{print $NF+0}' \| sort -n \| tail -1` | |
| 155 | +| Published date | `gh api repos/open-metadata/OpenMetadata/releases/tags/X.Y.Z-release \| jq -r '.published_at'` | |
| 156 | + |
| 157 | +## Common Mistakes |
| 158 | + |
| 159 | +- **Skipping pagination.** `--paginate` + `jq -s` looks fine but silently truncates when the compare exceeds a page. Always check `.total_commits` and fetch page-by-page. |
| 160 | +- **Copying the raw commit list.** The changelog is curated, not a mirror of `git log`. If a bullet doesn't have a user-facing effect, drop it. |
| 161 | +- **Wrong id.** New files continue the counter from the highest existing `id:`, not from the previous version's id + 1 (patches can be out of order — always take the max). |
| 162 | +- **`hasFeatures: true` on a patch.** A patch never has a Features section. Only major/minor releases do. |
| 163 | +- **Guessed dates.** Read `published_at` from the GitHub API; don't guess from the tag name. |
| 164 | + |
| 165 | +## Verification Checklist |
| 166 | + |
| 167 | +Before ending the turn: |
| 168 | + |
| 169 | +- [ ] `content/product-updates/vX.Y.Z.md` exists with the correct frontmatter. |
| 170 | +- [ ] `content/product-updates/versions.json` has the new entry as its first element. |
| 171 | +- [ ] Every PR link is a real PR on `open-metadata/OpenMetadata`. |
| 172 | +- [ ] Every reverted-and-not-reapplied change is absent. |
| 173 | +- [ ] The one-sentence intro names the themes, not just "maintenance release". |
| 174 | +- [ ] Migrations are called out explicitly. |
| 175 | +- [ ] Security section groups CVE bumps together with the CVE ID where known. |
0 commit comments