|
1 | 1 | # Releasing
|
2 | 2 |
|
3 |
| -These instructions describe how to cut a new release. |
4 |
| - |
5 |
| -**You should always start from this doc when initiating a release.** |
6 |
| - |
7 |
| -MDC follows the ["git flow"](http://nvie.com/posts/a-successful-git-branching-model/) style of |
8 |
| -development, where the default branch is called `develop`. `stable` (instead of the traditional |
9 |
| -`master`) is reserved for releases. The `develop` branch is periodically copied to a release candidate, |
10 |
| -tested, and then merged into `stable`, which serves as the stable "vetted" branch. |
11 |
| - |
12 |
| -## A note on the role of the release engineer |
13 |
| - |
14 |
| -Each release is driven by a single **release engineer**, who is also a Googler. The release engineer |
15 |
| -is expected to do the following, in order of priority: |
16 |
| - |
17 |
| -- Do not break Google. |
18 |
| -- Cut a release early in the working calendar week. |
19 |
| -- Land a release at least once every calendar week. |
20 |
| -- (Optional) Share something new with the team while you're waiting for tests to pass. |
21 |
| - |
22 |
| -If something is stopping the release engineer from achieving any of the above goals, the culprit |
23 |
| -code should be removed immediately from the release. |
24 |
| - |
25 |
| -Importantly: **do not** block the cutting of the weekly release on a PR or a piece of functionality |
26 |
| -you'd like to land. If your PR hasn't landed by the time the release is cut, it's not making it into |
27 |
| -that week's release. If your PR is important, cut a hotfix release in addition to the |
28 |
| -typical weekly release. |
29 |
| - |
30 |
| -If you are not able to cut a release Wednesday morning, cut it Tuesday evening before you leave the |
31 |
| -office. |
32 |
| - |
33 |
| -Please post regular updates about the status of the release to the team's chat room. This helps inform the |
34 |
| -team of the status of the release, and also encourages team problem solving in the event that something is |
35 |
| -stuck. At minimum, the following inflection points should be noted: |
36 |
| - |
37 |
| -- The release is being initiated. |
38 |
| -- Internal testing of the release has begun. |
39 |
| -- Internal testing of the release has ended. |
40 |
| -- The release has been submitted internally. |
41 |
| -- The release has been published to CocoaPods. |
42 |
| - |
43 |
| -For Googlers, also read [go/mdc-release-engineering](http://go/mdc-release-engineering) for additional details. |
44 |
| - |
45 |
| -## Before you start |
46 |
| - |
47 |
| -### First time setup |
48 |
| - |
49 |
| -Install [brew](https://brew.sh/), [sourcekitten](https://github.com/jpsim/SourceKitten), and [git-lfs](https://git-lfs.github.com/): |
50 |
| - |
51 |
| - brew install sourcekitten |
52 |
| - brew install git-lfs |
53 |
| - |
54 |
| -Please follow [using git-lfs instructions](https://github.com/material-components/material-components-ios/blob/2b6da5f10438081e5a7b2211e27336c6846433e5/contributing/tools.md#using-git-lfs) if you have already cloned the repository. |
55 |
| - |
56 |
| -Verify that xcode-select is pointing to an Xcode installation directory: |
57 |
| - |
58 |
| - xcode-select -p |
59 |
| - |
60 |
| - # Example output: |
61 |
| - # /Applications/Xcode.app/Contents/Developer |
62 |
| - |
63 |
| -If not, select the Xcode you have installed. For example: |
64 |
| - |
65 |
| - sudo xcode-select --switch /Applications/Xcode.app |
66 |
| - |
67 |
| -### Create a clean clone |
68 |
| - |
69 |
| -Make sure you are working from a direct clone of the main Git repository. The scripts involved |
70 |
| -assume that the remote "origin" is the actual repository and not your fork. Since most contributors |
71 |
| -will be working day-to-day with a fork, consider creating a separate clone just for releases. |
72 |
| - |
73 |
| - git clone [email protected]:material-components/material-components-ios.git mdc-ios-release |
74 |
| - cd mdc-ios-release |
75 |
| - |
76 |
| -### Configure the merge strategy for `.gitattributes` |
77 |
| - |
78 |
| -We have two different versions of `.gitattributes` in the `develop` and |
79 |
| -`stable` branches. To avoid conflicts (or accidental merges) between the two |
80 |
| -branches, we define a custom merge strategy just for that file. After cloning |
81 |
| -the repository, be sure to run this command: |
82 |
| - |
83 |
| - git config merge.gitattributes.driver true |
84 |
| - |
85 |
| -## Cutting and testing the release |
86 |
| - |
87 |
| -Our entire release process is encoded into the `release` script in the scripts/ directory. |
88 |
| -Read the [tool's readme](../scripts/README-release.md) to learn more about the tool. |
89 |
| - |
90 |
| -### Cut a release branch |
91 |
| - |
92 |
| -Run the following command to cut a release: |
93 |
| - |
94 |
| - scripts/release cut |
95 |
| - |
96 |
| -Note: if for some reason `cut` fails, first ensure that nobody else is in the middle of cutting a release by visiting the repo and verifying that a release-candidate does not already exist because aborting the release will delete the remote release candidate. If that isn't the case, then please run `scripts/release abort` and try again. |
97 |
| - |
98 |
| -You will now have a local `release-candidate` branch, a new section in CHANGELOG.md titled |
99 |
| -"release-candidate", and the `release-candidate` branch will have been pushed to GitHub. |
100 |
| - |
101 |
| -#### Hotfixing |
102 |
| - |
103 |
| -If you need to cut a hotfix release, run the following command instead: |
104 |
| - |
105 |
| - scripts/release cut --hotfix |
106 |
| - |
107 |
| -A hotfix release is like a regular release, but its scope is limited specifically to the fix. Hotfix |
108 |
| -release candidates start from origin/stable rather than origin/develop. |
109 |
| - |
110 |
| -If the hotfix is to fix a regression or a problematic commit in a recent release, the ideal |
111 |
| -path forward is to revert that commit using the `git revert <commit-hash>` command and opening a PR with that change to the develop branch. |
112 |
| -After that PR is merged, you should cherry-pick the revert commit into the `release-candidate` branch: `git cherry-pick <commit-hash>`. |
113 |
| - |
114 |
| -Other than the steps above regarding hotfixing, the entire release process stays the same. |
115 |
| - |
116 |
| -#### Create a Pull Request for the Release Branch |
117 |
| - |
118 |
| -If you have not clicked [the release candidate pull request comparison |
119 |
| -link](https://github.com/material-components/material-components-ios/compare/stable...release-candidate) |
120 |
| -provided in the script do so now. |
121 |
| - |
122 |
| -At this point you should also create the initial Release Candidate pull request using the URL |
123 |
| -that the `cut` script generated. |
124 |
| - |
125 |
| -Name the Pull Request title "{WIP} Release Candidate." until you are able to provide the version as the title. |
126 |
| - |
127 |
| -Add the group `material-components/release-blocking-clients` to the pull request's reviewers. This is the mechanism by which |
128 |
| -release-blocking clients are notified of a new release. |
129 |
| - |
130 |
| -**Do not use GitHub's big green button to merge the approved pull request.** Release are an |
131 |
| -exception to our normal squash-and-merge procedure. |
132 |
| - |
133 |
| -#### Verify CocoaPods podspec and trunk access |
134 |
| - |
135 |
| -Send our local podspec through the CocoaPods linter: |
136 |
| - |
137 |
| - pod lib lint MaterialComponents.podspec --skip-tests --allow-warnings |
138 |
| - |
139 |
| -CocoaPods publishes a directory of publicly available pods through its **trunk** service. |
140 |
| -Note: Ensure that you can [push the podspec](#publish-to-cocoapods) later by checking for `MaterialComponents` in your list of available `Pods` when you: |
141 |
| - |
142 |
| - pod trunk me |
143 |
| - |
144 |
| -If this fails or MaterialComponents is not listed [register an account and session](https://guides.cocoapods.org/making/getting-setup-with-trunk.html). |
145 |
| - |
146 |
| -### Start internal testing |
147 |
| - |
148 |
| -You can now start the internal release testing process documented at [go/mdc-releasing](http://go/mdc-releasing#requirements). |
149 |
| - |
150 |
| -### Resolve any failures |
151 |
| - |
152 |
| -Push `release-candidate` to GitHub with `git push origin release-candidate` as you make changes. |
153 |
| -This allows other people and machines to track the progress of the release. |
154 |
| - |
155 |
| -#### Make any necessary changes |
156 |
| - |
157 |
| -You, or clients, may find problems with the release that need fixing before continuing. You have two |
158 |
| -options for making those changes: |
159 |
| - |
160 |
| -1. If the change does not touch library code and is trivial, then you can make the change directly |
161 |
| -on the release candidate branch. |
162 |
| -1. If the change touches library code, is non-trivial, or you just want a second opinion, create a |
163 |
| -pull request *targeting `release-candidate`* and get it reviewed. |
164 |
| - |
165 |
| -Note that in both cases, changes made to the release candidate branch will be merged back into |
166 |
| -`develop` at the end of the release. |
167 |
| - |
168 |
| -## Determining the new version and drafting the release notes |
169 |
| - |
170 |
| -The two most important bits of metadata about a release is the *new version number* and the *release |
171 |
| -notes*. While we have tooling to help, your job is to make sure these are correct. If you're not |
172 |
| -familiar with [MDC's version number policy](versions.md), please review it now. |
173 |
| - |
174 |
| -To figure out the release number you will need to examine the release's changes. |
175 |
| - |
176 |
| -You have several tools available for deciding if a release is major, minor, or a patch. |
177 |
| - |
178 |
| -### Review the API diff |
179 |
| - |
180 |
| -CHANGELOG.md automatically includes the latest set of public API changes as part of the `cut` command. |
181 |
| -Inspect the API changes to get a quick sense of whether there might be an API-breaking change. |
182 |
| - |
183 |
| -1. If any part of a public API is deleted or changed, then this release is a *major* release. |
184 |
| -1. If any public API's nullability annotations have changed then this release is a *major* release. |
185 |
| -1. Otherwise, if any public APIs added, then this release is a *minor* release. |
186 |
| -1. Otherwise, this release *might* still be a bug fix release. |
187 |
| - |
188 |
| -### New Features / Top Level Description |
189 |
| - |
190 |
| -In the "New Features" sub-category generated by the API diff tool, please provide more detail as to what is new in the release, also providing examples on how to use the added public API properties/methods. For instance if you have added the method `setShadowWidth:` to `MDCCard` an example usage would be: |
191 |
| -```swift |
192 |
| -let card = MDCCard() |
193 |
| -card.setShadowWidth(10) |
194 |
| -``` |
195 |
| - |
196 |
| -In the top level description please provide a sentence explaining the overall release. Something along the lines of: |
197 |
| -"This minor/major/patch release includes X and Y along with some Z." |
198 |
| - |
199 |
| -### Verify API changes |
200 |
| - |
201 |
| -While we do primarily lean on the api_diff tool to call out API diffs, it isn't perfect. For each |
202 |
| -API change, open the source at the latest checkout and verify that the API change does, in fact, |
203 |
| -reflect the change that occurred. |
204 |
| - |
205 |
| -Adjust the API diffs in CHANGELOG.md based on your visual inspection of the code. |
206 |
| - |
207 |
| -Commit the final results to your branch. |
208 |
| - |
209 |
| - git add CHANGELOG.md |
210 |
| - git commit -m "Hand-modified CHANGELOG.md API diff." |
211 |
| - git push origin release-candidate |
212 |
| - |
213 |
| -### Identify visual changes |
214 |
| - |
215 |
| -We do not presently have an automated way to identify visual changes between releases. See [GitHub |
216 |
| -issue #290](https://github.com/material-components/material-components-ios/issues/290) for a |
217 |
| -discussion on the topic. |
218 |
| - |
219 |
| -### [Optional] Sanity check: inspect the changes |
220 |
| - |
221 |
| -#### Diff just the components |
222 |
| - |
223 |
| -The final sanity check is to visually inspect the diff. |
224 |
| - |
225 |
| -> If you have configured Git with a GUI diff tool (`git difftool`) like [Kaleidoscope](https://itunes.apple.com/us/app/kaleidoscope/id587512244?mt=12), then you can add |
226 |
| -> `--use_diff_tool` to `scripts/release diff` below. |
227 |
| -
|
228 |
| -Generate a list of component public header changes: |
229 |
| - |
230 |
| - scripts/release headers |
231 |
| - |
232 |
| -Show changes to component headers: |
233 |
| - |
234 |
| - scripts/release diff components/*/src/*.h |
235 |
| - |
236 |
| -Show all changes to components: |
237 |
| - |
238 |
| - scripts/release diff components/*/src/ |
239 |
| - |
240 |
| -#### Diff everything |
241 |
| - |
242 |
| -Show all changes that are part of this release: |
243 |
| - |
244 |
| - scripts/release diff |
245 |
| - |
246 |
| -### Classify the release type |
247 |
| - |
248 |
| -You should now be able to identify the release type and its new version number. Bump the release |
249 |
| -(change the version number everywhere): |
250 |
| - |
251 |
| - scripts/release bump <major.minor.patch> |
252 |
| - |
253 |
| -Commit the results to your branch: |
254 |
| - |
255 |
| - git commit -am "Bumped version number to $(scripts/print_version)." |
256 |
| - git push origin release-candidate |
257 |
| - |
258 |
| -Update the PR title to the release version. The format is typically "vX.Y.Z" (*e.g.*, v72.0.1). |
259 |
| -Once this is done, send the PR out for review. Add "material-components/core-ios-team" to the |
260 |
| -list of Reviewers. Also add anyone else you think might need to review specific changes in the |
261 |
| -release candidate. |
262 |
| - |
263 |
| -## Consider running `scripts/release notes` again |
264 |
| - |
265 |
| -Run `scripts/release notes` again and copy paste it into the `CHANGELOG.md` after |
266 |
| -`## Component changes` if you |
267 |
| - |
268 |
| -* cherry picked a change to add it to the release or |
269 |
| -* reverted any commit to rollback any PR. |
270 |
| - |
271 |
| -## Testing with release-blocking clients |
272 |
| - |
273 |
| -Before you can merge the release branch into either develop or stable you **must** get the release |
274 |
| -go-ahead from the following clients: |
275 |
| - |
276 |
| -- Google: must verify that the release branch passes all internal tests. If you are a Googler, see |
277 |
| - the internal "mirroring" document for further instructions. Notably you **must not continue** this |
278 |
| - releasing process until the internal synchronization CL has been tested. |
279 |
| - |
280 |
| ---- |
281 |
| - |
282 |
| - |\___/| |
283 |
| - (,\ /,)\ |
284 |
| - / / \ DRAGON SAYS HALT: |
285 |
| - (@_^_@)/ \ READ THE ABOVE SECTION BEFORE CONTINUING. |
286 |
| - W//W_/ \ DO NOT MERGE OR CUT ANY RELEASES UNTIL |
287 |
| - (//) | \ YOU'VE DONE SO. |
288 |
| - (/ /) _|_ / ) \ |
289 |
| - (// /) '/,_ _ _/ (~^-. |
290 |
| - (( // )) ,-{ _ `. |
291 |
| - (( /// )) '/\ / \ |
292 |
| - (( ///)) `. { } \ |
293 |
| - ((/ )) .----~-.\ \-' ~-__ |
294 |
| - ///.----..> \ \_ ~--____ |
295 |
| - ///-._ _ _ _} ~-------------- |
296 |
| - |
297 |
| ---- |
298 |
| - |
299 |
| -## Merge the release candidate branch |
300 |
| - |
301 |
| -Once the release-candidate has **passed all "Required" GitHub presubmit tests** and **all internal presubmit tests**, you may merge the release into the |
302 |
| -`develop` and `stable` branches using the `release` script. |
303 |
| - |
304 |
| -**Do not use GitHub's big green button to merge the approved pull request.** Release are an |
305 |
| -exception to our normal squash-and-merge procedure. |
306 |
| - |
307 |
| - # Did you listen to the dragon? |
308 |
| - # |
309 |
| - # Do not run this until all release-blocking clients have given the go-ahead. |
310 |
| - # Ensure that you've checked off every item in the commit message's checklist. |
311 |
| - # |
312 |
| - scripts/release merge <version> |
313 |
| - |
314 |
| -Once you've resolved any merge conflicts your local `develop` and `stable` branches will both |
315 |
| -include the latest changes from `release-candidate`. |
316 |
| - |
317 |
| -You must merge to **both** develop and stable. This is the mechanism by which we ensure that |
318 |
| -stable matches develop. |
319 |
| - |
320 |
| -## Push the branches to GitHub |
321 |
| - |
322 |
| -You can now push the merged release candidate to GitHub so that you can complete the final |
323 |
| -synchronization within Google. |
324 |
| - |
325 |
| - git push origin stable develop |
326 |
| - |
327 |
| -You can now sync to the desired stable release. [go/mdc-releasing#re-run-the-import-script-against-githubstable](http://go/mdc-releasing#re-run-the-import-script-against-githubstable). Once you've submitted |
328 |
| -the internal CL, continue below to tag and publish the release. |
329 |
| - |
330 |
| -## Publish the official release |
331 |
| - |
332 |
| -> Have all release-blocking clients given the go-ahead? **Do not create the official release |
333 |
| -> until all release-blocking clients are ready**. Otherwise you might publish a release that |
334 |
| -> isn't actually stable. |
335 |
| -
|
336 |
| -You can now publish the release to GitHub: |
337 |
| - |
338 |
| - scripts/release publish <version> |
339 |
| - |
340 |
| -## Publish to Cocoapods |
341 |
| - |
342 |
| - git checkout stable |
343 |
| - pod trunk push MaterialComponents.podspec --skip-tests --allow-warnings |
344 |
| - |
345 |
| -## Coordinate with release-blocking clients to finish work |
346 |
| - |
347 |
| -Any work that was started by the [Release-blocking clients](#release-blocking-clients) |
348 |
| -(dragon) step above may need to be finalized. |
349 |
| - |
350 |
| -Also follow last instructions in the [internal release instructions](http://go/mdc-releasing) |
| 3 | +The MDC-iOS release process takes places whenever a significant body of work |
| 4 | +needs to be made generally available, but typically once a week. The release |
| 5 | +process follows a set of general steps: |
| 6 | + |
| 7 | +1. A `release-candidate` branch is created and a Pull Request is created. |
| 8 | +2. The CHANGELOG and library version number are updated. |
| 9 | +3. The release is copied into Google for internal testing. |
| 10 | +4. Any unexpected breakages or problems are fixed immediately or reverted. |
| 11 | +5. The release is published to GitHub and CocoaPods. |
| 12 | + |
| 13 | +If you have any questions about the release process in general, [please open an |
| 14 | +Issue for the project |
| 15 | +maintainers](https://github.com/material-components/material-components-ios/issues/new/choose). |
0 commit comments