|
| 1 | +--- |
| 2 | +name: backport-docs |
| 3 | +description: Cherry-pick documentation changes from master onto a release branch so they appear on the docs.ray.io /latest build |
| 4 | +--- |
| 5 | + |
| 6 | +# Backport docs to a release branch |
| 7 | + |
| 8 | +`docs.ray.io/en/latest` is built from the newest `releases/X.Y.Z` branch, **not** |
| 9 | +from `master`. A docs change merged to `master` shows up only on |
| 10 | +`docs.ray.io/en/master` until it's cherry-picked onto the release branch. Use this |
| 11 | +skill to get already-merged docs onto `/latest`. |
| 12 | + |
| 13 | +Throughout, `<remote>` is the remote that points at `ray-project/ray`. Derive it |
| 14 | +from `git remote -v` — it's `origin` in a direct clone and `upstream` in a clone |
| 15 | +that started as a fork. Don't assume. |
| 16 | + |
| 17 | +## 1. Find the release branch that `/latest` serves |
| 18 | + |
| 19 | +```bash |
| 20 | +git ls-remote --heads <remote> 'refs/heads/releases/*' | sort -t/ -k3 -V | tail -5 |
| 21 | +``` |
| 22 | + |
| 23 | +The highest `releases/X.Y.Z` version is what `/latest` tracks. Fetch it: |
| 24 | + |
| 25 | +```bash |
| 26 | +git fetch <remote> releases/X.Y.Z |
| 27 | +``` |
| 28 | + |
| 29 | +## 2. Identify what's missing on `/latest` |
| 30 | + |
| 31 | +You usually start from a set of already-merged master commits or PRs (for example, |
| 32 | +the docs behind a release blog post). For each candidate, check whether it — or |
| 33 | +equivalent content — is already on the release branch: |
| 34 | + |
| 35 | +- **File missing entirely:** |
| 36 | + `git cat-file -e <remote>/releases/X.Y.Z:doc/source/<path>.md` |
| 37 | +- **File present but content differs:** |
| 38 | + `git diff <remote>/releases/X.Y.Z..<remote>/master -- doc/source/<path>.md` |
| 39 | +- **Which master commits touch a page (newest first):** |
| 40 | + `git log --oneline --no-merges <remote>/releases/X.Y.Z..<remote>/master -- doc/source/<path>.md` |
| 41 | + |
| 42 | +## 3. Check for prior backports (avoid duplicates) |
| 43 | + |
| 44 | +Equivalent content is often already on the release branch under a **different SHA** |
| 45 | +(a prior cherry-pick). Re-applying it will conflict or produce an empty commit. |
| 46 | +Before picking a PR, search the release-branch history for it: |
| 47 | + |
| 48 | +```bash |
| 49 | +git log --oneline <remote>/releases/X.Y.Z --grep "#<PR_NUMBER>)" |
| 50 | +``` |
| 51 | + |
| 52 | +If it's already there, skip that commit. Confirm with a file diff |
| 53 | +(`git diff <remote>/releases/X.Y.Z..<remote>/master -- <path>`); an empty diff means |
| 54 | +the page is already up to date on `/latest`. |
| 55 | + |
| 56 | +Also check nothing is already in flight: |
| 57 | + |
| 58 | +```bash |
| 59 | +gh pr list --repo ray-project/ray --state open --base releases/X.Y.Z |
| 60 | +gh pr list --repo ray-project/ray --state open --search "<PR_NUMBER> in:title,body" |
| 61 | +``` |
| 62 | + |
| 63 | +## 4. Cherry-pick onto a worktree of the release branch |
| 64 | + |
| 65 | +```bash |
| 66 | +git worktree add -b <branch> .worktrees/<branch> <remote>/releases/X.Y.Z |
| 67 | +cd .worktrees/<branch> |
| 68 | +``` |
| 69 | + |
| 70 | +Apply the chosen commits in **chronological (oldest-first)** order, preserving |
| 71 | +provenance (`-x`) and DCO sign-off (`--signoff`, required — see |
| 72 | +`doc/source/ray-contribute/agent-development.md`): |
| 73 | + |
| 74 | +```bash |
| 75 | +git cherry-pick -x --signoff <sha1> <sha2> ... |
| 76 | +``` |
| 77 | + |
| 78 | +**Keep the backport tight.** Cherry-pick only the feature/fix commits. Leave out |
| 79 | +broad, non-feature commits that happen to touch the same files (site-wide |
| 80 | +frontmatter/SEO passes, terminology renames, tooling like vendored references). |
| 81 | +Their hunks will remain as harmless residual diffs against master. |
| 82 | + |
| 83 | +### Resolving conflicts |
| 84 | + |
| 85 | +Conflicts here almost always come from an **excluded** commit that the picked |
| 86 | +commit carried as adjacent context (for example, `html_meta` frontmatter the |
| 87 | +release branch doesn't have). Resolve toward the release branch's state for those |
| 88 | +excluded hunks, and keep only the feature substance. If the whole page turns out to |
| 89 | +be already backported (step 3), `git cherry-pick --skip` it. |
| 90 | + |
| 91 | +## 5. Verify the build won't break |
| 92 | + |
| 93 | +The docs build runs with `fail_on_warning: true` (`.readthedocs.yaml`), so an |
| 94 | +unresolved cross-reference or a toctree entry pointing at a nonexistent file fails |
| 95 | +the build. For every file the backport changed: |
| 96 | + |
| 97 | +- **Cross-references resolve on the branch.** Collect the `{ref}` and `{doc}` |
| 98 | + targets and confirm each label exists: |
| 99 | + ```bash |
| 100 | + git grep -nE "^\(<label>\)=" -- 'doc/source/**' # MyST label |
| 101 | + git grep -nE "^\.\. _<label>:" -- 'doc/source/**' # rST label |
| 102 | + ``` |
| 103 | +- **New toctree entries point at files that exist** on the branch. |
| 104 | +- Sanity-check that each changed file matches master except for the hunks you |
| 105 | + intentionally excluded: |
| 106 | + `git diff HEAD..<remote>/master -- <path>`. |
| 107 | + |
| 108 | +A local docs build (see the "Building the Ray documentation" section of |
| 109 | +`doc/source/ray-contribute/docs.md`) is the strongest check before handing off. |
| 110 | + |
| 111 | +## 6. Open the PR |
| 112 | + |
| 113 | +Push the branch to `ray-project/ray` (not a fork, if you have push access) and open |
| 114 | +against the release branch: |
| 115 | + |
| 116 | +```bash |
| 117 | +git push -u <remote> <branch> |
| 118 | +gh pr create --repo ray-project/ray \ |
| 119 | + --base releases/X.Y.Z --head <branch> --draft \ |
| 120 | + --title "[cherry-pick][X.Y.Z][docs] <summary>" \ |
| 121 | + --body-file <body> |
| 122 | +``` |
| 123 | + |
| 124 | +- Match the release branch's existing title convention: `[cherry-pick][X.Y.Z]...`. |
| 125 | +- Open as **draft** — Ray's contribution policy requires a human to review every |
| 126 | + line and run tests before it requests review. |
| 127 | +- The PR body must state why it isn't a duplicate, what testing ran, and that AI |
| 128 | + assistance was used (see `AGENTS.md`). Note any commits you deliberately excluded |
| 129 | + and any already-present backports you skipped. |
| 130 | +- Keep internal tracking keys out of the PR title, body, and commits. |
0 commit comments