• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# ICU version upgrade
2
3Upgrade the ICU on Android to the new upstream version. The new upstream versions can be found at
4https://github.com/unicode-org/icu/releases.
5
6The below contains the steps and commands in order to upgrade the ICU version in the AOSP.
7
8# Prerequisites
91. Install the prerequisite tools
10   * See http://site.icu-project.org/repository
11   * [git-lts](https://git-lfs.github.com/) has to be installed to pull binaries correctly from the github.
12   * [git-filter-repo](https://github.com/newren/git-filter-repo) for rewriting the `Change-Id` later.
132. Generate a github read-access token and setup a local ~/.m2/setting.xml
14   * See http://cldr.unicode.org/development/maven. This is required to download
15     the prebuilt ICU to break the circular dependency between CLDR and icu.
163. Check out aosp/main
17   * http://go/repo-init/aosp-main-with-phones
18
19# Branch Structure
201. `external/icu` project in the AOSP,
21   * We **rebase** Android-specific patches on the `icu-staging` branch. Then we merge into
22     `aosp/main` later.
232. `external/cldr` project
24   * We use the **`aosp/upstream-release-cldr** as the mirror of the upstream release branch.
25     We don’t modify this branch with Android patches, but merge this branch
26     into aosp/main where the Android patches are located.
27
28# Verifying the cleanliness
291. Build the clean source of AOSP
30   ```shell
31   source build/envsetup.sh
32   lunch aosp_cf_x86_64_phone-trunk_staging-userdebug
33   m
34   ```
35   The build should succeed. Otherwise, your local repo may be broken. Please consider to re-sync.
362. Verify that the generated artifacts are clean
37   * If you re-run the generation scripts and it causes new changes, some patches are missing
38     in the sources, e.g. `icu4j/` and `icu4c` or `external/cldr`.
39   * The scripts include
40   ```shell
41   external/icu/tools/updatecldrdata.py
42   external/icu/tools/updateicudata.py
43   system/timezone/update-tzdata.py
44   external/icu/tools/srcgen/generate_android_icu4j.sh
45   external/icu/tools/icu4c_srcgen/generate_libandroidicu.py
46   external/icu/tools/icu4c_srcgen/generate_ndk.py
47   ```
48
49# Steps
501. Configure the versions and temp directory
51
52   * Customize the following environment variables.
53     The following example targets the ICU 76.1 and CLDR 46.0 version.
54   ```shell
55   export ICU_VERSION=76
56   export ICU_MINOR_VERSION=1
57   export CLDR_VERSION=46
58   export ICU_UPGRADE_BUG=1234567890 # buganizer bug
59   # Initially empty directory to store upstream source
60   export UPSTREAM_CLDR_GIT=/media/user/disk/icu-git/cldr
61   export UPSTREAM_ICU_GIT=/media/user/disk/icu-git/icu
62   ```
63
642. Copy the CLDR sources into the `upstream-release-cldr` branch
65
66   2a. Copy sources
67    ```shell
68    export CLDR_UPSTREAM_BRANCH=release-${CLDR_VERSION}
69
70    cd ${ANDROID_BUILD_TOP}/external/cldr
71    git fetch aosp upstream-release-cldr
72    git branch ${CLDR_UPSTREAM_BRANCH} --track aosp/upstream-release-cldr
73    git checkout ${CLDR_UPSTREAM_BRANCH}
74
75    git clone https://github.com/unicode-org/cldr.git ${UPSTREAM_CLDR_GIT}
76
77    git --git-dir=${UPSTREAM_CLDR_GIT}/.git --work-tree=${UPSTREAM_CLDR_GIT} fetch
78    git --git-dir=${UPSTREAM_CLDR_GIT}/.git --work-tree=${UPSTREAM_CLDR_GIT} checkout ${CLDR_UPSTREAM_BRANCH}
79    rm -rf *
80    cp -r ${UPSTREAM_CLDR_GIT}/* .
81    git clean -dfX # Remove ignored files
82    git add -A
83    git commit -F- <<EOF
84    Copy upstream ${CLDR_UPSTREAM_BRANCH}
85
86    Bug: ${ICU_UPGRADE_BUG}
87    Test: n/a
88    EOF
89    # Upload this CL to upstream-release-cldr branch
90    repo upload --cbr .
91    ```
92
93   2b. Merge the upstream sources with patches in `aosp/main`
94    ```shell
95    export CLDR_BRANCH=cldr${CLDR_VERSION}-main
96    git branch ${CLDR_BRANCH} --track aosp/main
97    git checkout ${CLDR_BRANCH}
98    git merge ${CLDR_UPSTREAM_BRANCH} -m "
99    Merge CLDR ${CLDR_VERSION} in upstream-release-cldr into aosp/main
100
101    Bug: ${ICU_UPGRADE_BUG}
102    Test: external/icu/tools/updatecldrdata.py
103    "
104    ```
105
106   2c. Resolve any merge conflicts with the Android-specific patches.
107      Continue creating the merge commit
108    ```shell
109    git merge --continue
110    ```
111
112   2d. Upload the CL to main branch
113    ```shell
114    repo upload --cbr .
115    ```
116
1173. Copy ICU upstream sources into external/icu
118    ```shell
119    cd ${ANDROID_BUILD_TOP}/external/icu
120    export ICU_BRANCH=icu-staging
121    export UPSTREAM_RELEASE_TAG=release-${ICU_VERSION}-${ICU_MINOR_VERSION}
122    git fetch aosp main ${ICU_BRANCH}
123    git branch ${ICU_BRANCH} --track aosp/${ICU_BRANCH}
124    git checkout ${ICU_BRANCH}
125    # Merge main into the staging branch.
126    git merge --no-ff aosp/main -m
127    "
128    Merge branch aosp/main into ${ICU_BRANCH}
129
130    Bug: ${ICU_UPGRADE_BUG}
131    Test: n/a
132    "
133    # Clone the upstream CLDR repo locally to ${UPSTREAM_ICU_GIT}
134    test -d ${UPSTREAM_ICU_GIT} || git clone https://github.com/unicode-org/icu.git ${UPSTREAM_ICU_GIT}
135
136    git --git-dir=${UPSTREAM_ICU_GIT}/.git --work-tree=${UPSTREAM_ICU_GIT} fetch
137    git --git-dir=${UPSTREAM_ICU_GIT}/.git --work-tree=${UPSTREAM_ICU_GIT} checkout ${UPSTREAM_RELEASE_TAG}
138    find icu4j/ -type f,d ! -regex ".*/\(Android.mk\|Android.bp\|adjust_icudt_path.mk\|liblayout-jarjar-rules.txt\|.gitignore\|AndroidTest.xml\)" -delete
139    find icu4c/ -type f,d ! -regex ".*/\(Android.mk\|Android.bp\|.gitignore\|AndroidTest.xml\)" -delete
140    cp -r ${UPSTREAM_ICU_GIT}/icu4j .
141    cp -r ${UPSTREAM_ICU_GIT}/icu4c .
142    git checkout HEAD -- icu4c/.gitignore icu4j/.gitignore # Android has extra .gitignores. Use our version.
143    rm -r tools/cldr
144    cp -r ${UPSTREAM_ICU_GIT}/tools/cldr tools/cldr
145
146    git add -A
147    git commit -F- <<EOF
148    Copy ICU ${UPSTREAM_RELEASE_TAG} into aosp/${ICU_BRANCH}
149
150    Copy the files with the following commands:
151    find icu4j/ -type f,d ! -regex ".*/\(Android.mk\|Android.bp\|adjust_icudt_path.mk\|liblayout-jarjar-rules.txt\|.gitignore\|AndroidTest.xml\)" -delete
152    find icu4c/ -type f,d ! -regex ".*/\(Android.mk\|Android.bp\|.gitignore\|AndroidTest.xml\)" -delete
153    cp -r \${UPSTREAM_ICU_GIT}/icu4j .
154    cp -r \${UPSTREAM_ICU_GIT}/icu4c .
155    git checkout HEAD -- icu4c/.gitignore icu4j/.gitignore
156    rm -r tools/cldr
157    cp -r \${UPSTREAM_ICU_GIT}/tools/cldr tools/cldr
158    EOF
159    ```
160
1614. Apply Android-specific patches into `external/icu`
162
163   4a. Cherry-pick the patches from the last staging branch. For example using the following query for ICU 71 patches
164      * https://android-review.git.corp.google.com/q/%22Android+patch%22+branch:icu-staging+status:merged
165      * The cherry-pick command is
166        ```shell
167        git cherry-pick <first_patch_in_the_chain>~1..<last_patch_in_the_chain>
168        ```
169   4b. Cherry-pick the patches since the ICU upgrade
170      * Find the patches with this query.
171           https://r.android.com/q/%2522Android+patch%2522+project:platform/external/icu+status:merged+-owner:automerger+-owner:android-build-coastguard-worker%2540google.com+branch:main
172   4c. Reset `Change-Id` in the cherry-picked CLs
173      * ```shell
174        THE_COPY_COMMIT=$(git log --pretty=format:'%h' -n 1 --grep "Copy ICU ${UPSTREAM_RELEASE_TAG} into aosp/${ICU_BRANCH}")
175        git filter-branch -f --msg-filter 'sed "s/Change-Id: .*//g"' ${THE_COPY_COMMIT}..HEAD
176        git rebase -i ${THE_COPY_COMMIT} # It should open vim
177        # Replace pick with reword in vim `%s/pick /reword /g`
178        # Close all commit message edits with :wq in vim
179        # It triggers the git-hook to generate a Change-Id.
180        # TODO: Find a better way to generate Change-Id
181        ```
1825. Regenerate and commit the artifacts
183
184   5a. Update icu source data files
185   ```shell
186   croot external/icu
187   tools/updatecldrdata.py
188
189   git add -A
190   git commit  -F- <<EOF
191   Regenerated source data files with Android CLDR patches
192
193   Source data files updated using:
194   tools/updatecldrdata.py
195
196   Test: n/a
197   EOF
198   ```
199
200   5b. Update icu binary data files
201   ```shell
202   tools/updateicudata.py
203   git add -A
204   git commit -F- <<EOF
205   Regenerated binary data files with Android CLDR patches
206
207   Binary data files updated using:
208   tools/updateicudata.py
209
210   Test: n/a
211   EOF
212   ```
213
214   5c. Pin the public API surface temporarily
215      * We will later expose the new APIs after submitting the version upgrade CLs.
216   ```shell
217   ./tools/srcgen/generate_allowlisted_public_api.sh
218   git add -A
219   git commit -F- <<EOF
220   Pin the current API list
221
222   Test: ./tools/srcgen/generate_allowlisted_public_api.sh
223   EOF
224   ```
225
226   5d. Regenerate android_icu4j/
227      * Commands
228      ```shell
229      tools/srcgen/generate_android_icu4j.sh
230
231      git add -A
232      git commit -F- <<EOF
233      Regenerate android_icu4j/ from icu4j/
234
235      android_icu4j files updated using:
236      tools/srcgen/generate_android_icu4j.sh
237
238      Test: n/a
239      EOF
240      ```
241      * If any java patches are not applied perfectly, remove the .orig and
242         .rej files with the following command
243      ```shell
244      find android_icu4j/ -name *.orig -delete
245      # Please manually update and resolve conflict of the java doc in android_icu4j/
246      git commit -amend
247      # Regenerate the patch files
248      ./tools/srcgen/javadoc_patches/create_patches.sh
249      git add -A && git commit -F- <<EOF
250      Regenerate java doc patches
251
252      Test: n/a
253      EOF
254      ```
255
256   5e. Re-genereate libandroidicu/ sources
257   ```shell
258   ./tools/icu4c_srcgen/generate_libandroidicu.py
259   git add -A && git commit  -F- <<EOF
260   Regenerate libandroidicu
261
262   The command:
263   ./tools/icu4c_srcgen/generate_libandroidicu.py
264
265   Test: n/a
266   EOF
267   ```
268
269   5f. Regenerate libicu/ sources
270      * Commands
271      ```shell
272      ./tools/icu4c_srcgen/generate_ndk.py
273
274      git add -A && git commit -a  -F- <<EOF
275      Regenerate libicu.so and ICU4C CTS headers
276
277      The command:
278      ./tools/icu4c_srcgen/generate_ndk.py
279
280      Test: n/a
281      EOF
282      ```
283      * Review the changes in libicu/ndk_headers/unicode. Check that
284         no ABI change is in the C struct or API signature.
285      ```shell
286      git diff HEAD~1 ./libicu/ndk_headers/
287      ```
288      * May need to run this to update .patch files
289      ```shell
290      # Manually update doxygen doc in the .h headers in libicu/ndk_headers
291      ./tools/icu4c_srcgen/doc_patches/create_patches.sh
292      git add -A && git commit  -F- <<EOF
293      Regenerate patches in libicu headers
294      EOF
295      ```
296
297   5g. [Not required for every ICU release] Increment Distro major version
298      * See https://android.googlesource.com/platform/system/timezone/+/main/README.android
299        for details. Usually, it’s needed only when it’s the first ICU upgrade
300        in the Android dessert release.
301
302   5h. Generate time zone files
303   ```shell
304   cd $ANDROID_BUILD_TOP/system/timezone
305   repo start ${ICU_BRANCH} .
306   ./update-tzdata.py
307   git add -A
308   git commit -F- <<EOF
309   Regenerate data files for ICU ${ICU_VERSION} upgrade
310
311   Binary data files updated using:
312   system/timezone/update-tzdata.py
313
314   This updates the ICU version number inside of icu_tzdata.dat but doesn't
315   change the timezone data itself.
316
317   Bug: ${ICU_UPGRADE_BUG}
318   Test: n/a
319   EOF
320
321   # If only the build time in icu4c/source/data/misc/zoneinfo64.txt, this step isn't needed.
322   cd $ANDROID_BUILD_TOP/external/icu
323   git add -A
324   git commit -F- <<EOF
325   Regenerate tz-related data files
326
327   Data files updated using:
328   system/timezone/update-tzdata.py
329
330   Bug: ${ICU_UPGRADE_BUG}
331   Test: n/a
332   EOF
333   ```
334
335   * Ideally, it should not generate new time zone data files if tzdata has been updated for a new
336     tzdb release
337   * If it updates time zone data, there could be extra changes from CLDR. Talk to
338     android-libcore-team@ how to deal with the updates, because they may need to cherry-pick
339     them into tzdata module updates.
340
341   5i. Update the version numbers in the METADATA
342      1. Update the external/icu/README.version
343      2. Update version and upgrade date in external/cldr/METADATA
344      3. `git commit` the file change
345
346   5j. Regenerate frameworks/base/libs/androidfw/LocaleDataTables.cpp
347   ```shell
348   croot frameworks/base
349   ./tools/localedata/extract_icu_data.py $ANDROID_BUILD_TOP > libs/androidfw/LocaleDataTables.cpp
350   git commit -a -F- <<EOF
351   Regenerate LocaleDataTables.cpp due to ICU ${ICU_VERSION} upgrade
352
353   The command:
354   ./tools/localedata/extract_icu_data.py \$ANDROID_BUILD_TOP > libs/androidfw/LocaleDataTables.cpp
355
356   Bug: ${ICU_UPGRADE_BUG}
357   Test: atest FrameworksCoreTests:android.text.format
358   EOF
359   ```
3606. Build and run test
361
362   6a. Build by `m droid cts`
363
364   6b. Run the device tests by `atest CtsIcu4cTestCases CtsIcuTestCases CtsLibcoreTestCases CtsLibcoreOjTestCases CtsBionicTestCases CtsTextTestCases minikin_tests -- --abi x86_64 # the primary ABI`
365
366   6c. [No longer needed] Run the host-side test by
367      * ICU4J host-side test `ant check`
368      * ICU4C host-side test `make CINTLTST_OPTS=-w INTLTEST_OPTS=-w check`
369         (Currently, it has some failing tests. No of failures?)
370
371   6d. If libcore/ tests are changed, verify the change
372      * To verify the test change in ART MTS, run `m mts && mts-tradefed run mts-art` on Android S.
373      * To verify the test change on LUCI bot, run `art/tools/run-libcore-tests.sh --mode=host`, because LUCI uses older ICU versions.
374
3757. Upload the CLs to gerrit for code reviews from `aosp/icu${ICU_VERSION}` in `external/icu` and `aosp/upstream-release-cldr` in `external/cldr`
376    ```shell
377    repo upload --cbr -o nokeycheck -o uploadvalidator~skip --no-verify .
378    ```
3798. Merge `aosp/icu*` branch to aosp/main
380    ```shell
381    cd $ANDROID_BUILD_TOP/external/icu
382    repo start icu${ICU_VERSION}-main .
383    git merge --no-ff icu${ICU_VERSION} -m "
384    Merge branch aosp/icu${ICU_VERSION} into aosp/main
385
386    Bug: ${ICU_UPGRADE_BUG}
387    Test: atest CtsIcu4cTestCases CtsIcuTestCases CtsLibcoreTestCases CtsLibcoreOjTestCases CtsBionicTestCases CtsTextTestCases minikin_tests
388    "
389    ```
3909. Upload and submit changes from external/icu, external/cldr, libcore, frameworks/base, system/timezone
391
392    10a. `repo upload --cbr -o uploadvalidator~skip --no-verify .`
393
394    10b. Code review  the diff in `android_icu4j/src/main/tests/android/icu/extratest/expected_transliteration_id_list.txt`
395       * If a transliteration id is removed from the list, it may introduce
396          app compatibility issues if the app depends on them. However, app
397         has been warned to check the availability before invoking them.
398          https://developer.android.com/reference/android/icu/text/Transliterator#getAvailableIDs()
39910. After submitting all the CLs to aosp/main, expose the new stable ICU4J APIs to Android SDK
400    ```shell
401    rm tools/srcgen/allowlisted-public-api.txt
402    ./tools/generate_android_icu4j.sh
403    # Modify Icu4jTransform.java to allowlist more classes if needed. Check the error message for the details
404    m update-api droid
405
406    git commit -a -F- <<EOF
407    Expose the new stable APIs from ICU4J ${ICU_VERSION}
408
409    According to the upstream API coverage report external/icu/icu4j/coverage-exclusion.txt,
410    the methods should have API coverage running in the existing CtsIcuTestCases.
411
412    Bug: ${ICU_UPGRADE_BUG}
413    Test: atest CtsIcuTestCases
414    EOF
415    ```
41611. Send email android-libcore@ and icu-team@ to announce this.
417    1. Some Android teams may have dependency on the new ICU version for other features.
418    2. Email template
419   ```text
420   Hi, Libcore and ICU team,
421
422   ICU <version> just landed Android AOSP.
423   https://android.googlesource.com/platform/external/icu/+/main/README.version
424   as well as Android S (or Android 12).
425   https://googleplex-android.googlesource.com/platform/external/icu/+/sc-dev/README.version
426
427   Note:
428   - Contains bug fixes / build changes with a small set of API methods added.
429   - Unicode stays at version 14, and no new version has been published yet.
430   ```
431
432
433## Historic version of this doc
434http://g3doc/third_party/icu/g3doc/update/android