blob: 30d30309273ca396b6eb50fe99461967302882dd [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import com.pswidersk.gradle.terraform.TerraformTask
import java.io.ByteArrayOutputStream
import java.util.regex.Pattern
plugins {
id("com.pswidersk.terraform-plugin") version "1.0.0"
}
terraformPlugin {
terraformVersion.set("1.4.2")
}
/* init Infrastructure for migrate */
tasks.register<TerraformTask>("terraformInit") {
dependsOn("indexcreate")
args(
"init", "-migrate-state",
"-backend-config=./state.tfbackend"
)
}
/* refresh Infrastructure for remote state */
tasks.register<TerraformTask>("terraformRef") {
args(
"refresh",
"-lock=false",
"-var-file=./common.tfvars"
)
}
tasks.register<TerraformTask>("terraformApplyBackend") {
group = "backend-deploy"
val pg_router_host = if (project.extensions.extraProperties.has("pg_router_host")) {
project.extensions.extraProperties["pg_router_host"] as String
} else {
"unknown"
}
args(
"apply",
"-auto-approve",
"-lock=false",
"-parallelism=3",
"-var=pg_router_host=$pg_router_host",
"-var=project_id=$(gcloud config get-value project)",
"-var-file=./common.tfvars"
)
tasks.getByName("uploadLearningMaterials").mustRunAfter(this)
}
tasks.register<TerraformTask>("terraformDestroy") {
dependsOn("getRouterHost")
val pg_router_host = if (project.extensions.extraProperties.has("pg_router_host")) {
project.extensions.extraProperties["pg_router_host"] as String
} else {
"unknown"
}
args(
"destroy",
"-auto-approve",
"-lock=false",
"-var=pg_router_host=$pg_router_host",
"-var=project_id=$(gcloud config get-value project)",
"-var-file=./common.tfvars"
)
}
tasks.register("getRouterHost") {
group = "backend-deploy"
doLast {
val result = ByteArrayOutputStream()
exec {
commandLine(
"kubectl",
"get",
"svc",
"-l",
"app=backend-router-grpc",
"-o",
"jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}:{.items[0].spec.ports[0].port}'"
)
standardOutput = result
}
val pgRouterHost = result.toString().trim().replace("'", "")
project.extensions.extraProperties["pg_router_host"] = pgRouterHost
}
}
tasks.register("indexcreate") {
group = "backend-deploy"
dependsOn("getRouterHost")
doLast {
val indexpath = "../backend/internal/storage/index.yaml"
exec {
executable("gcloud")
args("datastore", "indexes", "create", indexpath)
}
}
}
tasks.register("firebaseProjectCreate") {
group = "frontend-deploy"
dependsOn("prepareFirebasercConfig")
doLast {
val result = ByteArrayOutputStream()
val projectId = project.property("project_id") as String
exec {
executable("firebase")
args("projects:list")
standardOutput = result
}
val output = result.toString().trim()
if (output.contains(projectId)) {
println("Firebase is already added to project $projectId.")
} else {
exec {
executable("firebase")
args("projects:addfirebase", projectId)
}.assertNormalExitValue()
println("Firebase has been added to project $projectId.")
}
}
}
tasks.register("firebaseHostingCreate") {
group = "frontend-deploy"
dependsOn("firebaseWebAppCreate")
doLast {
val projectId = project.property("project_id") as String
val webapp_id = project.property("webapp_id") as String
val listSitesResult = ByteArrayOutputStream()
exec {
executable("firebase")
args("hosting:sites:list", "--project", projectId)
workingDir("../frontend")
standardOutput = listSitesResult
}
println(listSitesResult)
val output = listSitesResult.toString()
val regex = "\\b$webapp_id\\b".toRegex()
if (regex.containsMatchIn(output)) {
println("Firebase is already added to project $projectId.")
} else {
exec {
executable("firebase")
args("hosting:sites:create", webapp_id)
workingDir("../frontend")
}.assertNormalExitValue()
println("Firebase hosting site has been added to project $projectId.")
}
exec {
executable("firebase")
args("target:apply", "hosting", webapp_id , webapp_id)
workingDir("../frontend")
}.assertNormalExitValue()
val file = project.file("../frontend/firebase.json")
val content = file.readText()
val oldContent = """"public": "build/web","""
val newContent = """"public": "build/web",
"target": "$webapp_id","""
val updatedContent = content.replace(oldContent, newContent)
file.writeText(updatedContent)
}
}
tasks.register("firebaseWebAppCreate") {
group = "frontend-deploy"
dependsOn("firebaseProjectCreate")
doLast {
val result = ByteArrayOutputStream()
val projectId = project.property("project_id") as String
val webappId = project.property("webapp_id") as String
exec {
executable("firebase")
args("apps:list", "--project", projectId)
standardOutput = result
}
println(result)
val output = result.toString()
if (output.contains(webappId)) {
println("Webapp id $webappId is already created on the project: $projectId.")
val regex = Regex("""$webappId[\W]+([\d:a-zA-Z]+)[\W]+WEB""")
val firebaseAppId = regex.find(output)?.groupValues?.get(1)?.trim()
println("Firebase app ID for existing Firebase Web App: $firebaseAppId")
project.extensions.extraProperties["firebaseAppId"] = firebaseAppId
} else {
val result2 = ByteArrayOutputStream()
exec {
executable("firebase")
args("apps:create", "WEB", webappId, "--project", projectId)
standardOutput = result2
}.assertNormalExitValue()
val firebaseAppId =
result2.toString().lines().find { it.startsWith(" - App ID:") }?.substringAfter(":")?.trim()
project.extensions.extraProperties["firebaseAppId"] = firebaseAppId
println("Firebase app ID for newly created Firebase Web App: $firebaseAppId")
}
}
}
// firebase apps:sdkconfig WEB AppId
tasks.register("getSdkConfigWebApp") {
group = "frontend-deploy"
dependsOn("firebaseHostingCreate")
doLast {
val firebaseAppId = project.extensions.extraProperties["firebaseAppId"] as String
val result = ByteArrayOutputStream()
exec {
executable("firebase")
args("apps:sdkconfig", "WEB", firebaseAppId)
standardOutput = result
}
val output = result.toString().trim()
val pattern = Pattern.compile("\\{[^{]*\"locationId\":\\s*\".*?\"[^}]*\\}", Pattern.DOTALL)
val matcher = pattern.matcher(output)
if (matcher.find()) {
val firebaseConfigData = matcher.group().replace("{", "")
.replace("}", "")
.replace("\"locationId\":\\s*\".*?\",?".toRegex(), "")
.replace("\"(\\w+)\":".toRegex(), "$1:")
.replace(":\\s*\"(.*?)\"".toRegex(), ":\"$1\"")
project.extensions.extraProperties["firebaseConfigData"] = firebaseConfigData.trim()
println("Firebase config data: $firebaseConfigData")
}
}
}
tasks.register("prepareFirebaseOptionsDart") {
group = "frontend-deploy"
dependsOn("getSdkConfigWebApp")
doLast {
val firebaseConfigData = project.extensions.extraProperties["firebaseConfigData"] as String
val file = project.file("../frontend/lib/firebase_options.dart")
val content = file.readText()
val updatedContent = content.replace(
Regex("""static const FirebaseOptions web = FirebaseOptions\(([^)]+)\);"""),
"static const FirebaseOptions web = FirebaseOptions(${firebaseConfigData});"
)
file.writeText(updatedContent)
}
}
tasks.register("flutterPubGetPG") {
dependsOn("prepareFirebaseOptionsDart")
doLast {
exec {
executable("flutter")
args("pub", "get")
workingDir("../../../playground/frontend/playground_components")
}
}
}
tasks.register("flutterPubRunPG") {
dependsOn("flutterPubGetPG")
doLast {
exec {
executable("flutter")
args("pub", "run", "build_runner", "build", "--delete-conflicting-outputs")
workingDir("../../../playground/frontend/playground_components")
}
}
}
tasks.register("flutterPubGetTob") {
dependsOn("flutterPubRunPG")
dependsOn("getSdkConfigWebApp")
doLast {
exec {
executable("flutter")
args("pub", "get")
workingDir("../frontend")
}
}
}
tasks.register("flutterPubRunTob") {
dependsOn("flutterPubGetTob")
doLast {
exec {
executable("flutter")
args("pub", "run", "build_runner", "build", "--delete-conflicting-outputs")
workingDir("../frontend")
}
}
}
tasks.register("flutterBuildWeb") {
dependsOn("flutterPubRunTob")
doLast {
exec {
executable("flutter")
args("build", "web", "-v", "--release")
workingDir("../frontend")
}
}
}
tasks.register("firebaseDeploy") {
dependsOn("flutterBuildWeb")
doLast {
val projectId = project.property("project_id") as String
val webapp_id = project.property("webapp_id") as String
exec {
commandLine("firebase", "deploy", "--only", "hosting:$webapp_id", "--project", projectId)
workingDir("../frontend")
}
}
}
tasks.register("prepareConfig") {
group = "frontend-deploy"
doLast {
val region = project.property("region") as String
val projectId = project.property("project_id") as String
val environment = project.property("project_environment") as String
val dnsName = project.property("dns-name") as String
val configFileName = "config.dart"
val modulePath = project(":learning:tour-of-beam:frontend").projectDir.absolutePath
val file = File("$modulePath/lib/$configFileName")
file.writeText(
"""
const _cloudFunctionsProjectRegion = '$region';
const _cloudFunctionsProjectId = '$projectId';
const cloudFunctionsBaseUrl = 'https://'
'$region-$projectId'
'.cloudfunctions.net/${environment}_';
"""
)
}
}
tasks.register("prepareFirebasercConfig") {
group = "frontend-deploy"
dependsOn("prepareConfig")
doLast {
val projectId = project.property("project_id") as String
val configFileName = ".firebaserc"
val modulePath = project(":learning:tour-of-beam:frontend").projectDir.absolutePath
val file = File("$modulePath/$configFileName")
file.writeText(
"""
{
"projects": {
"default": "$projectId"
}
}
"""
)
}
}
tasks.register("uploadLearningMaterials") {
group = "backend-deploy"
dependsOn("terraformApplyBackend")
doLast {
val projectId = project.property("project_id") as String
exec {
commandLine("go", "run", "cmd/ci_cd/ci_cd.go")
environment("DATASTORE_PROJECT_ID", projectId)
environment("GOOGLE_PROJECT_ID", projectId)
environment("TOB_LEARNING_ROOT", "../learning-content/")
workingDir("../backend")
}
}
}
/* Tour of Beam backend init */
tasks.register("InitBackend") {
group = "backend-deploy"
dependsOn("getRouterHost")
dependsOn("indexcreate")
dependsOn("terraformInit")
dependsOn("terraformApplyBackend")
dependsOn("uploadLearningMaterials")
}
tasks.register("DestroyBackend") {
group = "backend-destroy"
dependsOn("getRouterHost")
dependsOn("terraformDestroy")
}
tasks.register("InitFrontend") {
group = "frontend-deploy"
dependsOn("prepareConfig")
dependsOn("prepareFirebasercConfig")
dependsOn("firebaseProjectCreate")
dependsOn("firebaseWebAppCreate")
dependsOn("firebaseHostingCreate")
dependsOn("getSdkConfigWebApp")
dependsOn("prepareFirebaseOptionsDart")
dependsOn("flutterPubGetPG")
dependsOn("flutterPubRunPG")
dependsOn("flutterPubGetTob")
dependsOn("flutterPubRunTob")
dependsOn("flutterBuildWeb")
dependsOn("firebaseDeploy")
}