1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 import org.yaml.snakeyaml.Yaml
8 if (!gradle.hasProperty("mozconfig")){
9 apply from: file('./gradle/mozconfig.gradle')
13 gradle.mozconfig.substs.GRADLE_MAVEN_REPOSITORIES.each { repository ->
16 if (gradle.mozconfig.substs.ALLOW_INSECURE_GRADLE_REPOSITORIES) {
17 allowInsecureProtocol = true
24 classpath 'org.yaml:snakeyaml:2.2'
28 if (!gradle.hasProperty("mozconfig")){
29 apply from: file('./gradle/mozconfig.gradle')
32 // Synchronized library configuration for all modules
33 // This "componentsVersion" number is defined in "version.txt" and should follow
34 // semantic versioning (MAJOR.MINOR.PATCH). See https://semver.org/
37 public final String componentsVersion
38 public final String componentsGroupId
39 public final Integer jvmTargetCompatibility
40 public final Integer compileSdkVersion
41 public final Integer minSdkVersion
42 public final Integer targetSdkVersion
45 String componentsVersion,
46 String componentsGroupId,
47 Integer jvmTargetCompatibility,
48 Integer compileSdkVersion,
49 Integer minSdkVersion,
50 Integer targetSdkVersion
52 this.componentsVersion = componentsVersion
53 this.componentsGroupId = componentsGroupId
54 this.jvmTargetCompatibility = jvmTargetCompatibility
55 this.compileSdkVersion = compileSdkVersion
56 this.minSdkVersion = minSdkVersion
57 this.targetSdkVersion = targetSdkVersion
61 def setupProject(name, path, description) {
62 settings.include(":$name")
64 def projectPath = "/mobile/android/android-components/${path}"
65 if (rootDir.toString().endsWith("android-components") ||
66 rootDir.toString().endsWith("focus-android") ||
67 rootDir.toString().endsWith("fenix")
69 projectPath = "../android-components/${path}"
72 project(":$name").projectDir = new File(rootDir, projectPath)
74 // project(...) gives us a skeleton project that we can't set ext.* on
75 gradle.beforeProject { project ->
76 // However, the "afterProject" listener iterates over every project and gives us the actual project
77 // So, once we filter for the project we care about, we can set whatever we want
78 if (project.name == name) {
79 project.ext.description = description
84 // Return a manifest version string that respects the Firefox version format,
85 // see: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/version#version_format
86 def getManifestVersionString(componentsVersion) {
87 // We assume that the `version.txt` file will always contain a version
88 // string with at least two parts separated with a dot. Below, we extract
89 // each part, and we make sure that there is no letter, e.g. `"0a2"` would
91 String[] parts = componentsVersion.split("\\.").collect {
92 part -> part.split("a|b")[0]
94 // Note the single `H` to avoid leading zeros, which are not allowed.
95 String dateAndTime = new Date().format("YYYYMMdd.Hmmss");
97 return "${parts[0]}.${parts[1]}.${dateAndTime}";
100 def buildConfigPath = '/mobile/android/android-components/.buildconfig.yml'
101 if (rootDir.toString().endsWith("android-components") ||
102 rootDir.toString().endsWith("focus-android") ||
103 rootDir.toString().endsWith("fenix")
105 buildConfigPath = '../android-components/.buildconfig.yml'
108 def yaml = new Yaml()
109 def buildconfig = yaml.load(new File(rootDir, buildConfigPath).newInputStream())
111 buildconfig.projects.each { project ->
112 // If we're building A-C, set up all projects, otherwise exclude samples e.g., if we're building Fenix or Focus.
113 // The samples are not relevant for the Fenix and Focus builds.
114 if (rootDir.toString().contains("android-components") || !project.key.startsWith("samples")) {
115 setupProject(project.key, project.value.path, project.value.description)
119 gradle.projectsLoaded { ->
120 def versionPath = '/mobile/android/version.txt'
121 def configPath = '/mobile/android/android-components/.config.yml'
123 if (rootDir.toString().endsWith("android-components") ||
124 rootDir.toString().endsWith("focus-android") ||
125 rootDir.toString().endsWith("fenix")
127 versionPath = '../version.txt'
128 configPath = '../android-components/.config.yml'
131 def componentsVersion = new File(rootDir, versionPath).text.stripTrailing()
132 def configData = yaml.load(new File(rootDir, configPath).newInputStream())
133 String version = componentsVersion
135 if (gradle.rootProject.hasProperty("nightlyVersion")) {
136 version = gradle.rootProject.nightlyVersion
137 } else if (gradle.rootProject.hasProperty("local")) {
138 // To support local auto-publication workflow, we use a version prefix we wouldn't normally encounter.
140 } else if (gradle.hasProperty("localProperties.branchBuild.android-components.version")) {
141 version = gradle.getProperty("localProperties.branchBuild.android-components.version")
144 // Wait until root project is "loaded" before we set "config"
145 // Note that since this is set on "rootProject.ext", it will be "in scope" during the evaluation of all projects'
146 // gradle files. This means that they can just access "config.<value>", and it'll function properly
147 gradle.rootProject.ext.config = new Config(
149 configData.componentsGroupId,
150 configData.jvmTargetCompatibility,
151 configData.compileSdkVersion,
152 configData.minSdkVersion,
153 configData.targetSdkVersion
156 gradle.rootProject.ext.buildConfig = buildconfig
158 // Define a reusable task for updating the version in manifest.json for modules that package
159 // a web extension. We automate this to make sure we never forget to update the version, either
160 // in local development or for releases. In both cases, we want to make sure the latest version
161 // of all extensions (including their latest changes) are installed on first start-up.
162 gradle.rootProject.allprojects {
163 ext.updateExtensionVersion = { task, extDir ->
166 include 'manifest.template.json'
167 rename { 'manifest.json' }
170 def values = ['version': getManifestVersionString(rootProject.ext.config.componentsVersion)]
171 inputs.properties(values)