|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Hydrogen Release Process |
| 6 | + |
| 7 | +### Overview |
| 8 | +Hydrogen uses a sophisticated automated release system built on Changesets, GitHub Actions, and npm workspaces. Understanding this flow is critical for contributing effectively. |
| 9 | + |
| 10 | +### Release Flow: From PR to Production |
| 11 | + |
| 12 | +1. **Developer creates PR with changes** |
| 13 | + - If changes affect `packages/*/src/**` or `packages/*/package.json`, a changeset is required |
| 14 | + - Run `npm run changeset add` to create a changeset file **(MANUAL)** |
| 15 | + - Changeset specifies which packages are affected and version bump type (patch/minor/major) |
| 16 | + |
| 17 | +2. **On merge to main, TWO parallel processes occur:** |
| 18 | + |
| 19 | + a) **Next Release (immediate)** **(AUTOMATIC)** |
| 20 | + - Every push to main (except release commits) triggers `next-release.yml` |
| 21 | + - Creates snapshot version: `0.0.0-next-{SHA}-{timestamp}` |
| 22 | + - ALL packages are published with `next` tag |
| 23 | + - Available immediately for testing latest changes |
| 24 | + |
| 25 | + b) **Version PR Creation (if changesets exist)** **(AUTOMATIC)** |
| 26 | + - `changesets.yml` workflow runs |
| 27 | + - If changesets are found, creates OR updates open CI release PR |
| 28 | + - PR title: `[ci] release 2025-05` (current latest branch) |
| 29 | + - **Important**: This PR accumulates ALL changesets from merged PRs |
| 30 | + - Multiple PRs can be merged before a release (e.g., 10 PRs = 10 changesets in one Version PR) |
| 31 | + - The Version PR automatically updates as new changesets are merged |
| 32 | + |
| 33 | +3. **Production Release - Batched (manual step)** |
| 34 | + - **Releases are batched**: Maintainers decide when to release (could be after 1 PR or 10 PRs) |
| 35 | + - The Version PR accumulates all pending changesets since last release |
| 36 | + - Maintainer reviews accumulated changes and merges the Version PR when ready **(MANUAL)** |
| 37 | + - On merge, `changesets.yml` publishes to npm with `latest` tag **(AUTOMATIC)** |
| 38 | + - Only packages with changesets get new versions **(AUTOMATIC)** |
| 39 | + - Internal dependencies updated with patch versions **(AUTOMATIC)** |
| 40 | + - Post-release actions: |
| 41 | + - Compiles templates to `dist` branch **(AUTOMATIC)** |
| 42 | + - Sends Slack notification (if Hydrogen package included) **(AUTOMATIC)** |
| 43 | + |
| 44 | +4. **Post-Release: Enabling Upgrades (manual step)** |
| 45 | + - After npm publication, `docs/changelog.json` must be updated **(MANUAL)** |
| 46 | + - This enables the `h2 upgrade` command to detect the new version |
| 47 | + - Without this step, developers cannot upgrade using the CLI |
| 48 | + - Process: |
| 49 | + - Update `docs/changelog.json` with release information **(MANUAL)** |
| 50 | + - Include version, dependencies, features, fixes, and upgrade steps **(MANUAL)** |
| 51 | + - Commit and push to main branch **(MANUAL)** |
| 52 | + - Changes are served via https://hydrogen.shopify.dev/changelog.json **(AUTOMATIC)** |
| 53 | + |
| 54 | + **How `h2 upgrade` works:** |
| 55 | + - Fetches changelog.json from hydrogen.shopify.dev (proxies to the raw content of this file on the `main` branch in the Hydrogen repo) |
| 56 | + - Compares user's current version against available versions |
| 57 | + - Shows features, fixes, and breaking changes for upgrade path |
| 58 | + - Generates local upgrade instructions file in `.hydrogen/` directory |
| 59 | + - Updates package.json dependencies based on changelog specifications |
| 60 | + |
| 61 | +### Understanding Batched Releases |
| 62 | + |
| 63 | +**Key Point**: Not every merged PR triggers a release! |
| 64 | + |
| 65 | +- When you merge a PR with a changeset, it does NOT immediately release to npm |
| 66 | +- Instead, your changeset is added to the open CI release PR |
| 67 | +- This PR accumulates changesets from ALL merged PRs since the last release |
| 68 | +- Maintainers decide when to merge this PR to trigger an actual release |
| 69 | +- This allows batching multiple features/fixes into a single release |
| 70 | + |
| 71 | +**Example Timeline**: |
| 72 | +- Monday: 3 PRs merged with changesets → Version PR has 3 changesets |
| 73 | +- Tuesday: 2 more PRs merged → Version PR now has 5 changesets |
| 74 | +- Wednesday: 4 more PRs merged → Version PR now has 9 changesets |
| 75 | +- Thursday: Maintainer merges Version PR → All 9 changes released together |
| 76 | + |
| 77 | +### Multi-Package Releases |
| 78 | +- Each package versions independently (no fixed/linked packages in changesets config) |
| 79 | +- Single changeset can specify multiple packages |
| 80 | +- Example: PR changes both `@shopify/hydrogen` and `@shopify/cli-hydrogen` |
| 81 | + - Both packages listed in changeset |
| 82 | + - Each gets appropriate version bump |
| 83 | + - Published together when Version PR merged |
| 84 | + |
| 85 | +### Other Release Types |
| 86 | + |
| 87 | +**Snapshot Testing (`/snapit`)** |
| 88 | +- Comment `/snapit` on any PR |
| 89 | +- Creates snapshot version for testing |
| 90 | +- Publishes specific packages for PR validation |
| 91 | + |
| 92 | +**Back-fix Releases** |
| 93 | +- Push to calver branches (e.g., `2025-01`) |
| 94 | +- Publishes with branch name as npm tag |
| 95 | +- Used for patching previous versions |
| 96 | + |
| 97 | +### Manual vs Automatic Steps |
| 98 | + |
| 99 | +#### Manual Steps (Human Intervention Required) |
| 100 | + |
| 101 | +1. **Developer Actions** |
| 102 | + - **Create changesets**: Run `npm run changeset add` for any PR with code changes |
| 103 | + - **Skeleton changes**: MUST include `@shopify/cli-hydrogen` in the changeset |
| 104 | + - This ensures the CLI bundles the latest skeleton template |
| 105 | + - Without this, new projects will scaffold with outdated templates |
| 106 | + - **Write PR descriptions**: Include clear explanations of changes |
| 107 | + - **Request snapshot builds**: Comment `/snapit` on PR to test changes |
| 108 | + |
| 109 | +2. **Maintainer Actions - Regular Releases** |
| 110 | + - **Merge Version PR**: Review and merge the auto-generated open CI release PR to trigger npm publication |
| 111 | + - **Update changelog.json**: After npm release, manually update this file to enable `h2 upgrade` command |
| 112 | + - **Monitor releases**: Verify packages published correctly and Slack notifications sent |
| 113 | + |
| 114 | +3. **Maintainer Actions - CLI Releases** |
| 115 | + - When cli-hydrogen has updates, create a PR in the Shopify CLI repo and coordinate with Shopify CLI team to request patch release |
| 116 | + - **Update skeleton after CLI release**: Once @shopify/cli releases, update skeleton's package.json |
| 117 | + - **Second cli-hydrogen release**: Often required to bundle the updated skeleton |
| 118 | + |
| 119 | +4. **Maintainer Actions - Major Version Changes** |
| 120 | + - **Update latestBranch**: Edit `.github/workflows/changesets.yml` line 32 when moving to new major version |
| 121 | + - Example: Change `echo "latestBranch=2025-01"` to `echo "latestBranch=2025-05"` |
| 122 | + - Required quarterly with new Storefront API versions |
| 123 | + - **Configure back-fix branches**: Add old calver branches to `.github/workflows/changesets-back-fix.yml` |
| 124 | + - Enables continued patches to previous versions |
| 125 | + - Never add the current calver branch |
| 126 | + |
| 127 | +#### Automatic Steps (CI/CD Handles) |
| 128 | + |
| 129 | +1. **On Every Push to Main** |
| 130 | + - Next release publishes immediately with tag `next` |
| 131 | + - Version: `0.0.0-next-{SHA}-{timestamp}` |
| 132 | + - All packages published regardless of changesets |
| 133 | + |
| 134 | +2. **When Changesets Exist on Main** |
| 135 | + - Version PR automatically created |
| 136 | + - Title: `[ci] release {latestBranch}` |
| 137 | + - Contains version bumps and CHANGELOG updates |
| 138 | + |
| 139 | +3. **When Version PR is Merged** |
| 140 | + - Packages publish to npm with `latest` tag |
| 141 | + - Only packages with changesets get new versions |
| 142 | + - Templates compile and push to `dist` branch |
| 143 | + - Slack notification sent (if Hydrogen package included) |
| 144 | + - GitHub releases created with changelogs |
| 145 | + |
| 146 | +4. **When `/snapit` is Commented** |
| 147 | + - Snapshot version created for PR |
| 148 | + - Packages published with unique tag |
| 149 | + - PR comment updated with installation instructions |
| 150 | + |
| 151 | +5. **On Push to Calver Branches** |
| 152 | + - Back-fix version PR created |
| 153 | + - Publishes with branch name as npm tag when merged |
| 154 | + |
| 155 | +### Version Strategy |
| 156 | +- Hydrogen versions follow calendar versioning (calver) |
| 157 | +- Format: `YYYY.MAJOR.MINOR/PATCH` |
| 158 | +- Example: `2025.5.0` means: |
| 159 | + - `2025` - year |
| 160 | + - `5` - major release cycle (tied to Storefront API versions) |
| 161 | + - `0` - minor/patch number |
| 162 | +- Tied to Shopify Storefront API versions |
| 163 | +- Breaking changes possible every 3 months with API updates |
| 164 | +- Hydrogen releases a new "major" version with **every** Storefront API version update, regardless of whether or not there are breaking changes between the Storefront API versions |
| 165 | + |
| 166 | + |
| 167 | +### CLI Dependency Graph |
| 168 | +The Hydrogen CLI system works through a plugin architecture: |
| 169 | + |
| 170 | +``` |
| 171 | +Developer's Project (e.g., skeleton template) |
| 172 | + ├── package.json |
| 173 | + │ └── devDependencies |
| 174 | + │ └── @shopify/cli (~3.80.4) |
| 175 | + │ |
| 176 | + └── npm scripts |
| 177 | + └── "shopify hydrogen dev" commands |
| 178 | + ↓ |
| 179 | + @shopify/cli (main CLI) |
| 180 | + ↓ |
| 181 | + @shopify/cli-hydrogen (plugin) |
| 182 | + ↓ |
| 183 | + Hydrogen commands available |
| 184 | +``` |
| 185 | + |
| 186 | +**How it works:** |
| 187 | +- **@shopify/cli**: The main Shopify CLI installed in project's devDependencies |
| 188 | +- **@shopify/cli-hydrogen**: Plugin package that adds `hydrogen` subcommands |
| 189 | +- When `@shopify/cli` detects `@shopify/cli-hydrogen` in dependencies, it loads the plugin |
| 190 | +- This enables commands like `shopify hydrogen dev`, `shopify hydrogen build`, etc. |
| 191 | +- The plugin uses oclif framework for command structure and hooks |
| 192 | + |
| 193 | +**Example flow:** |
| 194 | +1. Developer runs `npm run dev` in their project |
| 195 | +2. This executes `shopify hydrogen dev --codegen` |
| 196 | +3. `@shopify/cli` receives the command and delegates to `@shopify/cli-hydrogen` |
| 197 | +4. The hydrogen plugin executes the dev server with MiniOxygen |
| 198 | + |
| 199 | +## Skeleton Template and Project Scaffolding |
| 200 | + |
| 201 | +### Skeleton Template Location |
| 202 | +The skeleton template is the default starter template for new Hydrogen projects: |
| 203 | +- Located at `templates/skeleton/` in the Hydrogen repo |
| 204 | +- Serves as the foundation for `npm create @shopify/hydrogen@latest` |
| 205 | +- Includes both TypeScript configuration (default) and can be transpiled to JavaScript |
| 206 | + |
| 207 | +### How Project Scaffolding Works |
| 208 | + |
| 209 | +When developers run `npm create @shopify/hydrogen@latest`: |
| 210 | + |
| 211 | +1. **Package Resolution** |
| 212 | + - npm resolves `@shopify/create-hydrogen` package |
| 213 | + - This package calls the `hydrogen init` command from `@shopify/cli-hydrogen` |
| 214 | + |
| 215 | +2. **Template Fetching** |
| 216 | + - Downloads the latest Hydrogen release tarball from GitHub |
| 217 | + - Uses GitHub API: `https://api.github.com/repos/shopify/hydrogen/releases/latest` |
| 218 | + - Extracts the skeleton template from the tarball |
| 219 | + - Falls back to local template if running within Hydrogen monorepo |
| 220 | + |
| 221 | +3. **Template Compilation** (during release) |
| 222 | + - On production releases, templates are compiled to the `dist` branch |
| 223 | + - Creates both TypeScript (`skeleton-ts`) and JavaScript (`skeleton-js`) versions |
| 224 | + - The `dist` branch serves as a stable source for templates |
| 225 | + |
| 226 | +### Critical: Skeleton Changes Require CLI Updates |
| 227 | + |
| 228 | +**When modifying the skeleton template, you MUST**: |
| 229 | +1. Create a changeset that includes BOTH: |
| 230 | + - The skeleton template changes |
| 231 | + - A version bump for `@shopify/cli-hydrogen` |
| 232 | +2. This ensures the CLI contains a snapshot of the latest skeleton in its `dist/assets/templates` directory |
| 233 | +3. Without this, newly scaffolded projects will use an outdated skeleton template |
| 234 | + |
| 235 | +**Why this matters**: The `@shopify/cli-hydrogen` package bundles the skeleton template. If you don't bump its version when changing the skeleton, the CLI will continue distributing the old template version. |
| 236 | + |
| 237 | +### CLI Release Coordination (Circular Dependency) |
| 238 | + |
| 239 | +The CLI system has an inherent circular dependency that requires careful coordination: |
| 240 | + |
| 241 | +**The Circular Dependency Problem**: |
| 242 | +``` |
| 243 | +@shopify/cli-hydrogen (bundles skeleton) |
| 244 | + ↓ is included in |
| 245 | +@shopify/cli (main Shopify CLI) |
| 246 | + ↓ is used by |
| 247 | +skeleton template's devDependencies |
| 248 | + ↓ which is bundled in |
| 249 | +@shopify/cli-hydrogen (circular!) |
| 250 | +``` |
| 251 | + |
| 252 | +**Release Process to Handle This**: |
| 253 | + |
| 254 | +1. **First Release**: |
| 255 | + - Release `@shopify/cli-hydrogen` with new features/fixes |
| 256 | + - Trigger `@shopify/cli` release to include updated `cli-hydrogen` |
| 257 | + - Problem: The skeleton bundled in `cli-hydrogen` still references the OLD `@shopify/cli` version |
| 258 | + |
| 259 | +2. **Second Release Required**: |
| 260 | + - Update skeleton's `package.json` to use new `@shopify/cli` version |
| 261 | + - Create another changeset bumping `@shopify/cli-hydrogen` |
| 262 | + - Release again so future `cli-hydrogen` bundles the updated skeleton |
| 263 | + |
| 264 | +**Example Timeline**: |
| 265 | +- Day 1: Release `@shopify/cli-hydrogen@8.1.0` with new command |
| 266 | +- Day 2: `@shopify/cli@3.80.0` released with updated hydrogen plugin |
| 267 | +- Day 3: Update skeleton to use `@shopify/cli@~3.80.0` |
| 268 | +- Day 4: Release `@shopify/cli-hydrogen@8.1.1` with updated skeleton |
| 269 | +- Result: New projects now have access to the new command |
| 270 | + |
| 271 | +**Key Takeaways**: |
| 272 | +- This process often requires TWO cli-hydrogen releases for complete updates |
| 273 | +- The circular dependency makes the process complex but is currently unavoidable |
| 274 | +- Always check that skeleton's CLI version matches the features available in cli-hydrogen |
0 commit comments