Dangerfile 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. ### Helper functions
  2. # Determine if any of the files were changed or deleted.
  3. # Taken from samdmarshall/danger
  4. def didModify(files_array)
  5. files_array.each do |file_name|
  6. if git.modified_files.include?(file_name) ||
  7. git.deleted_files.include?(file_name)
  8. return true
  9. end
  10. end
  11. return false
  12. end
  13. # Determine if there are changes in files matching any of the
  14. # path patterns provided.
  15. def hasChangesIn(paths)
  16. path_array = Array(paths)
  17. path_array.each do |dir|
  18. if !git.modified_files.grep(/#{dir}/).empty?
  19. return true
  20. end
  21. end
  22. return false
  23. end
  24. # Determine if any new files were added to paths matching any of the
  25. # path patterns provided.
  26. def hasAdditionsIn(paths)
  27. path_array = Array(paths)
  28. path_array.each do |dir|
  29. if !git.added_files.grep(/#{dir}/).empty?
  30. return true
  31. end
  32. end
  33. return false
  34. end
  35. # Adds the provided labels to the current PR.
  36. def addLabels(label_array)
  37. issue_number = github.pr_json["number"]
  38. repo_name = "firebase/firebase-ios-sdk"
  39. github.api.add_labels_to_an_issue(repo_name, issue_number, label_array)
  40. end
  41. # Returns a list of all labels for a given PR. PRs that touch
  42. # multiple directories may have multiple labels.
  43. def labelsForModifiedFiles()
  44. labels = []
  45. labels.push("api: analytics") if @has_analytics_changes
  46. labels.push("api: abtesting") if @has_abtesting_changes
  47. labels.push("api: appcheck") if @has_appcheck_changes
  48. labels.push("api: appdistribution") if @has_appdistribution_changes
  49. labels.push("api: auth") if @has_auth_changes
  50. labels.push("api: core") if @has_core_changes
  51. labels.push("api: crashlytics") if @has_crashlytics_changes
  52. labels.push("api: database") if @has_database_changes
  53. labels.push("api: firebaseai") if @has_firebaseai_changes
  54. labels.push("api: firestore") if @has_firestore_changes
  55. labels.push("api: functions") if @has_functions_changes
  56. labels.push("api: inappmessaging") if @has_inappmessaging_changes
  57. labels.push("api: installations") if @has_installations_changes
  58. labels.push("api: messaging") if @has_messaging_changes
  59. labels.push("api: performance") if @has_performance_changes
  60. labels.push("api: remoteconfig") if @has_remoteconfig_changes
  61. labels.push("api: storage") if @has_storage_changes
  62. labels.push("release-tooling") if @has_releasetooling_changes
  63. labels.push("public-api-change") if @has_api_changes
  64. return labels
  65. end
  66. ### Definitions
  67. # Label for any change that shouldn't have an accompanying CHANGELOG entry,
  68. # including all changes that do not affect the compiled binary (i.e. script
  69. # changes, test-only changes)
  70. declared_trivial = github.pr_body.include? "#no-changelog"
  71. # Whether or not there are pending changes to any changelog file.
  72. has_changelog_changes = hasChangesIn(["CHANGELOG"])
  73. # Whether or not the LICENSE file has been modified or deleted.
  74. has_license_changes = didModify(["LICENSE"])
  75. # A list of published Firebase products.
  76. @product_list = [
  77. "ABTesting",
  78. "AppCheck",
  79. "AppDistribution",
  80. "Analytics",
  81. "Authentication",
  82. "Core",
  83. "Crashlytics",
  84. "Database",
  85. "FirebaseAI",
  86. "Firestore",
  87. "Functions",
  88. "InAppMessaging",
  89. "Installations",
  90. "Messaging",
  91. "Performance",
  92. "RemoteConfig",
  93. "Storage"
  94. ]
  95. ## Product directories
  96. @has_analytics_changes = hasChangesIn([
  97. "FirebaseAnalyticsWrapper"
  98. ]) || didModify([
  99. "FirebaseAnalytics.podspec",
  100. "GoogleAppMeasurement.podspec"
  101. ])
  102. @has_abtesting_changes = hasChangesIn("FirebaseABTesting")
  103. @has_abtesting_api_changes = hasChangesIn("FirebaseABTesting/Sources/Public/")
  104. @has_appcheck_changes = hasChangesIn("FirebaseAppCheck")
  105. @has_appcheck_api_changes = hasChangesIn("FirebaseAppCheck/Sources/Public/")
  106. @has_appdistribution_changes = hasChangesIn("FirebaseAppDistribution")
  107. @has_appdistribution_api_changes = hasChangesIn("FirebaseAppDistribution/Sources/Public")
  108. @has_auth_changes = hasChangesIn("FirebaseAuth")
  109. @has_auth_api_changes = hasChangesIn("FirebaseAuth/Sources/Public/")
  110. @has_core_changes = hasChangesIn([
  111. "FirebaseCore",
  112. "CoreOnly/"])
  113. @has_core_api_changes = hasChangesIn("FirebaseCore/Sources/Public/")
  114. @has_crashlytics_changes = hasChangesIn("Crashlytics")
  115. @has_crashlytics_api_changes = hasChangesIn("Crashlytics/Crashlytics/Public/")
  116. @has_database_changes = hasChangesIn("FirebaseDatabase")
  117. @has_database_api_changes = hasChangesIn("FirebaseDatabase/Sources/Public/")
  118. @has_firebaseai_changes = hasChangesIn("FirebaseAI")
  119. @has_firestore_changes = hasChangesIn(["Firestore/", "FirebaseFirestore.podspec"])
  120. @has_firestore_api_changes = hasChangesIn("Firestore/Source/Public/")
  121. @has_functions_changes = hasChangesIn(["FirebaseFunctions"])
  122. @has_functions_api_changes = hasChangesIn("FirebaseFunctions/Sources/Public/")
  123. @has_inappmessaging_changes = hasChangesIn(["FirebaseInAppMessaging"])
  124. @has_inappmessaging_api_changes = hasChangesIn(["FirebaseInAppMessaging/Sources/Public/"])
  125. @has_installations_changes = hasChangesIn("FirebaseInstallations")
  126. @has_installations_api_changes = hasChangesIn("FirebaseInstallations/Source/Library/Public/")
  127. @has_messaging_changes = hasChangesIn("FirebaseMessaging")
  128. @has_messaging_api_changes = hasChangesIn("FirebaseMessaging/Sources/Public/")
  129. @has_performance_changes = hasChangesIn("FirebasePerformance")
  130. @has_performance_api_changes = hasChangesIn("FirebasePerformance/Sources/Public/")
  131. @has_remoteconfig_changes = hasChangesIn("FirebaseRemoteConfig")
  132. @has_remoteconfig_api_changes = hasChangesIn("FirebaseRemoteConfig/Sources/Public/")
  133. @has_storage_changes = hasChangesIn("FirebaseStorage")
  134. @has_releasetooling_changes = hasChangesIn("ReleaseTooling/")
  135. @has_public_additions = hasAdditionsIn("Public/")
  136. @has_umbrella_changes =
  137. @product_list.reduce(false) { |accum, product| accum || hasChangesIn("Firebase#{product}.h") }
  138. # Convenient flag for all API changes.
  139. @has_api_changes = @has_abtesting_api_changes ||
  140. @has_appcheck_api_changes ||
  141. @has_auth_api_changes ||
  142. @has_appdistribution_api_changes ||
  143. @has_core_api_changes ||
  144. @has_crashlytics_api_changes ||
  145. @has_database_api_changes ||
  146. @has_firestore_api_changes ||
  147. @has_functions_api_changes ||
  148. @has_inappmessaging_api_changes ||
  149. @has_installations_api_changes ||
  150. @has_messaging_api_changes ||
  151. @has_performance_api_changes ||
  152. @has_remoteconfig_api_changes ||
  153. @has_storage_api_changes ||
  154. @has_gdt_api_changes
  155. # A FileList containing ObjC, ObjC++ or C++ changes.
  156. sdk_changes = (git.modified_files +
  157. git.added_files +
  158. git.deleted_files).select do |line|
  159. line.end_with?(".h") ||
  160. line.end_with?(".m") ||
  161. line.end_with?(".mm") ||
  162. line.end_with?(".cc") ||
  163. line.end_with?(".swift")
  164. end
  165. # Whether or not the PR has modified SDK source files.
  166. has_sdk_changes = !sdk_changes.empty?
  167. ### Actions
  168. # Warn if a changelog is left out on a non-trivial PR that has modified
  169. # SDK source files (podspec, markdown, etc changes are excluded).
  170. if has_sdk_changes
  171. if !has_changelog_changes && !declared_trivial
  172. warning = "Did you forget to add a changelog entry? (Add #no-changelog"\
  173. " to the PR description to silence this warning.)"
  174. warn(warning)
  175. end
  176. end
  177. # Warn if a new public header file is added but no umbrella header changes
  178. # are detected. Prevents regression of #10301
  179. if @has_public_additions && !@has_umbrella_changes
  180. error = "New public headers were added, "\
  181. "did you remember to add them to the umbrella header?"
  182. warn(error)
  183. end
  184. # Error on license edits
  185. fail("LICENSE changes are explicitly disallowed.") if has_license_changes
  186. # Label PRs based on diff files
  187. suggested_labels = labelsForModifiedFiles()
  188. if !suggested_labels.empty?
  189. addLabels(suggested_labels)
  190. end