Add script to sync common files between templates/example

Bug: 431150957
Test: ./sync-common.sh

Change-Id: I2ff94471cba2fa5078b92a40bd248f0c6a552930
diff --git a/example/settings.gradle.kts b/example/settings.gradle.kts
index 5f8cba2..13a00ec 100644
--- a/example/settings.gradle.kts
+++ b/example/settings.gradle.kts
@@ -1,5 +1,5 @@
 /*
- * Copyright 2024 The Android Open Source Project
+ * Copyright 2024-2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -39,7 +39,7 @@
     id("com.android.security.autorepro.submission") version "1.0.1-alpha1" apply false
 }
 
-rootProject.name = "autorepro-example"
+rootProject.name = "autorepro-submission"
 
 // glob and include gradle projects
 fileTree(rootDir) {
diff --git a/sync-common.sh b/sync-common.sh
new file mode 100755
index 0000000..5b2dfd2
--- /dev/null
+++ b/sync-common.sh
@@ -0,0 +1,119 @@
+#!/bin/bash
+#
+# Copyright 2025 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+###############################################################################
+# What this script does and why we need it?
+# This script synchronizes common configuration files from `example/` (the
+# source of truth) to all project templates in `templates/*/`. This ensures all
+# templates are up-to-date with shared configurations.
+#
+# When to run this script?
+# - After updating files/dirs listed below in the `example/` project.
+#   This can happen when updating the autorepro plugin version (see
+#   go/autorepro#releasing-to-gmaven) or making other manual changes.
+# - After adding a new project template under `templates/` to ensure it receives
+#   the common files followed by validating the newly synced template.
+#
+# Files/dirs synced between `example/` and `templates/*/`:
+# - .gitignore
+# - .run/
+# - gradle/
+# - gradle.properties
+# - gradlew
+# - gradlew.bat
+# - settings.gradle.kts
+#
+# Updating the above files/dirs in example and syncing:
+# 1. Make and validate changes in the `example/` project. This may include:
+#    - Updating `settings.gradle.kts` (e.g., plugin versions).
+#    - Running a Gradle sync in Android Studio which may update wrapper files.
+#    - Modifying shared `.run/` configurations or `.gitignore`.
+# 2. Run this script to propagate the changes to all templates:
+#    ./sync-common.sh
+###############################################################################
+
+set -euo pipefail
+
+readonly SCRIPT_DIR=$(realpath "$(dirname "$0")")
+readonly SOURCE_DIR="${SCRIPT_DIR}/example"
+
+_ERROR_MESSAGE=""
+
+die() {
+  _ERROR_MESSAGE="${@:2}"
+  exit "$1"
+}
+
+on_exit() {
+  local exit_code=$?
+  if [[ ${exit_code} -eq 0 ]]; then
+    printf "\nSYNC COMPLETED SUCCESSFULLY.\n"
+    return
+  fi
+
+  # If an error message was set by die(), print it to stderr.
+  if [[ -n "${_ERROR_MESSAGE}" ]]; then
+    printf "\nERROR: %s\n" "${_ERROR_MESSAGE}" >&2
+  fi
+
+  # Instructions on a failed sync
+  cat <<EOF
+
+SYNC FAILED WITH EXIT CODE: ${exit_code}.
+The target directories may be in an inconsistent state.
+Please do not commit any of the resulting changes.
+EOF
+}
+
+trap on_exit EXIT
+
+main() {
+  declare -a target_dirs=()
+
+  # Add all templates/* folders in target_dirs
+  for d in "${SCRIPT_DIR}"/templates/*; do
+    if [[ -d "$d" ]]; then
+      target_dirs+=("$d")
+    fi
+  done
+
+  if [[ ${#target_dirs[@]} -eq 0 ]]; then
+    die 1 "No template directories found. Nothing to sync."
+  fi
+
+  # List all directories from target_dirs
+  printf "\n- Identified target directory: [%s]\n" "${target_dirs[@]}"
+
+  # Create array of files/dirs to sync
+  declare -a files_to_sync=(
+    "${SOURCE_DIR}/./.gitignore"
+    "${SOURCE_DIR}/./.run/"
+    "${SOURCE_DIR}/./gradle/"
+    "${SOURCE_DIR}/./gradle.properties"
+    "${SOURCE_DIR}/./gradlew"
+    "${SOURCE_DIR}/./gradlew.bat"
+    "${SOURCE_DIR}/./settings.gradle.kts"
+  )
+
+  # Start syncing
+  for target in "${target_dirs[@]}"; do
+    printf "\n- Syncing from [%s] to [%s]\n" "$SOURCE_DIR" "$target"
+    rsync -avR "${files_to_sync[@]}" "$target" \
+      || die "$?" "Failed to sync [${target}] (see previous errors)"
+  done
+}
+
+main "$@"
diff --git a/templates/same-app-id/gradle/wrapper/gradle-wrapper.properties b/templates/same-app-id/gradle/wrapper/gradle-wrapper.properties
index b350ef3..56a6388 100644
--- a/templates/same-app-id/gradle/wrapper/gradle-wrapper.properties
+++ b/templates/same-app-id/gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-#Wed Aug 07 16:22:12 UTC 2024
+#Fri Jul 11 10:56:54 UTC 2025
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
diff --git a/templates/same-app-id/settings.gradle.kts b/templates/same-app-id/settings.gradle.kts
index b549fe0..13a00ec 100644
--- a/templates/same-app-id/settings.gradle.kts
+++ b/templates/same-app-id/settings.gradle.kts
@@ -1,5 +1,5 @@
 /*
- * Copyright 2025 The Android Open Source Project
+ * Copyright 2024-2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -39,7 +39,7 @@
     id("com.android.security.autorepro.submission") version "1.0.1-alpha1" apply false
 }
 
-rootProject.name = "autorepro-example"
+rootProject.name = "autorepro-submission"
 
 // glob and include gradle projects
 fileTree(rootDir) {