diff --git a/doc/contributing/maintaining/maintaining-icu.md b/doc/contributing/maintaining/maintaining-icu.md index e83aa8a5b0c4..93dbda2c7d95 100644 --- a/doc/contributing/maintaining/maintaining-icu.md +++ b/doc/contributing/maintaining/maintaining-icu.md @@ -177,9 +177,19 @@ make clean tools/license-builder.sh ``` -* Update the URL and hash for the full ICU file in `tools/icu/current_ver.dep`. - It should match the ICU URL used in the first step. When this is done, the - following should build with small ICU. +* Verify the PGP signature of the full ICU file: + +```bash +gpgv --keyring tools/dep_updaters/icu.kbx \ + icu4c-*-sources.tgz.asc icu4c-*-sources.tgz +``` + +* If the release was signed with a key not present in that keyring, update it + from the [ICU `KEYS` file](https://github.com/unicode-org/icu/blob/HEAD/KEYS) + after confirming the new key out-of-band. +* Update the URL and SHA-256 hash for the full ICU file in + `tools/icu/current_ver.dep`. It should match the ICU URL used in the first + step. When this is done, the following should build with small ICU. ```bash # clean up diff --git a/tools/dep_updaters/icu.kbx b/tools/dep_updaters/icu.kbx new file mode 100644 index 000000000000..6abb79eaaf37 Binary files /dev/null and b/tools/dep_updaters/icu.kbx differ diff --git a/tools/dep_updaters/update-icu.sh b/tools/dep_updaters/update-icu.sh index 8cd402d93269..4bbac86f0f28 100755 --- a/tools/dep_updaters/update-icu.sh +++ b/tools/dep_updaters/update-icu.sh @@ -1,6 +1,8 @@ #!/bin/sh set -e -# Shell script to update icu in the source tree to a specific version +# Shell script to update icu in the source tree to a specific version. +# Pass `--update-keys` to update the local copy of the key files after verifying +# the upstream file history. BASE_DIR=$(cd "$(dirname "$0")/../.." && pwd) DEPS_DIR="$BASE_DIR/deps" @@ -36,28 +38,48 @@ NEW_VERSION_TGZ="icu4c-${NEW_VERSION}-sources.tgz" NEW_VERSION_TGZ_URL="https://github.com/unicode-org/icu/releases/download/release-${NEW_VERSION}/${NEW_VERSION_TGZ}" -NEW_VERSION_MD5="https://github.com/unicode-org/icu/releases/download/release-${NEW_VERSION}/icu4c-${NEW_VERSION}-sources.md5" - -CHECKSUM=$(curl -sL "$NEW_VERSION_MD5" | grep "$NEW_VERSION_TGZ" | grep -v "\.asc$" | awk '{print $1}') +WORKSPACE=$(mktemp -d 2> /dev/null || mktemp -d -t 'tmp') +NEW_VERSION_TGZ_PATH="$WORKSPACE/$NEW_VERSION_TGZ" + +cleanup () { + EXIT_CODE=$? + [ -d "$WORKSPACE" ] && rm -rf "$WORKSPACE" + exit $EXIT_CODE +} + +trap cleanup INT TERM EXIT + +echo "Fetching ICU source archive" +curl -sfL -o "$NEW_VERSION_TGZ_PATH" "$NEW_VERSION_TGZ_URL" + +KEYRING="$BASE_DIR/tools/dep_updaters/icu.kbx" +if [ "$1" = "--update-keys" ]; then + KEYS_FILE="$WORKSPACE/KEYS" + GNUPGHOME="$WORKSPACE/gnupg" + mkdir -m 700 "$GNUPGHOME" + echo "Fetching the upstream KEYS file" + curl -sSLfo "$KEYS_FILE" "https://github.com/unicode-org/icu/raw/refs/tags/release-${NEW_VERSION}/KEYS" + GNUPGHOME="$GNUPGHOME" gpg --no-default-keyring --keyring "$WORKSPACE/icu.kbx" --batch --import --import-options import-minimal < "$KEYS_FILE" + mv "$WORKSPACE/icu.kbx" "$KEYRING" +fi -GENERATED_CHECKSUM=$( curl -sL "$NEW_VERSION_TGZ_URL" | md5sum | cut -d ' ' -f1) +echo "Verifying PGP signature" +curl -sfL -o "$NEW_VERSION_TGZ_PATH.asc" "$NEW_VERSION_TGZ_URL.asc" +gpgv --keyring "$KEYRING" "$NEW_VERSION_TGZ_PATH.asc" "$NEW_VERSION_TGZ_PATH" -echo "Comparing checksums: deposited '$CHECKSUM' with '$GENERATED_CHECKSUM'" +CHECKSUM=$(shasum -a 256 "$NEW_VERSION_TGZ_PATH" | cut -d ' ' -f1) +echo "sha256: $CHECKSUM" -if [ "$CHECKSUM" != "$GENERATED_CHECKSUM" ]; then - echo "Skipped because checksums do not match." - exit 0 -fi - -./configure --with-intl=full-icu --with-icu-source="$NEW_VERSION_TGZ_URL" +./configure --with-intl=full-icu --with-icu-source="$NEW_VERSION_TGZ_PATH" "$TOOLS_DIR/icu/shrink-icu-src.py" rm -rf "$DEPS_DIR/icu" -perl -i -pe "s|\"url\": .*|\"url\": \"$NEW_VERSION_TGZ_URL\",|" "$TOOLS_DIR/icu/current_ver.dep" - -perl -i -pe "s|\"md5\": .*|\"md5\": \"$CHECKSUM\"|" "$TOOLS_DIR/icu/current_ver.dep" +URL="$NEW_VERSION_TGZ_URL" SHA256="$CHECKSUM" "$NODE" -e ' + const { URL: url, SHA256: sha256 } = process.env; + console.log(JSON.stringify([{ url, sha256 }], null, 2)); +' > "$TOOLS_DIR/icu/current_ver.dep" rm -rf out "$DEPS_DIR/icu" "$DEPS_DIR/icu4c*" diff --git a/tools/icu/current_ver.dep b/tools/icu/current_ver.dep index 3d923fec865a..577b585578ee 100644 --- a/tools/icu/current_ver.dep +++ b/tools/icu/current_ver.dep @@ -1,6 +1,6 @@ [ { "url": "https://github.com/unicode-org/icu/releases/download/release-78.3/icu4c-78.3-sources.tgz", - "md5": "a7b736b570ef0e180c96a31715a00c78" + "sha256": "3a2e7a47604ba702f345878308e6fefeca612ee895cf4a5f222e7955fabfe0c0" } ]