Skip to content

Commit 6021b75

Browse files
authored
dataconnect: .github/workflows/dataconnect_demo_app.yml added (#6568)
1 parent 033ab2d commit 6021b75

File tree

4 files changed

+264
-45
lines changed

4 files changed

+264
-45
lines changed
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
name: Data Connect Demo App
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
nodeVersion:
7+
firebaseToolsVersion:
8+
javaVersion:
9+
gradleInfoLog:
10+
type: boolean
11+
pull_request:
12+
paths:
13+
- firebase-dataconnect/demo/**
14+
- .github/workflows/dataconnect_demo_app.yml
15+
schedule:
16+
- cron: '0 11 * * *' # Run nightly at 11am UTC (3am Pacific, 6am Eastern)
17+
18+
env:
19+
FDC_NODE_VERSION: ${{ inputs.nodeVersion || '20' }}
20+
FDC_FIREBASE_TOOLS_VERSION: ${{ inputs.firebaseToolsVersion || '13.25.0' }}
21+
FDC_JAVA_VERSION: ${{ inputs.javaVersion || '17' }}
22+
FDC_FIREBASE_TOOLS_DIR: ${{ github.workspace }}/firebase-tools
23+
FDC_FIREBASE_COMMAND: ${{ github.workspace }}/firebase-tools/node_modules/.bin/firebase
24+
25+
defaults:
26+
run:
27+
shell: bash
28+
working-directory: firebase-dataconnect/demo
29+
30+
concurrency:
31+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
32+
cancel-in-progress: true
33+
34+
jobs:
35+
test:
36+
continue-on-error: false
37+
runs-on: ubuntu-latest
38+
steps:
39+
- uses: actions/checkout@v3
40+
with:
41+
sparse-checkout: firebase-dataconnect/demo
42+
43+
- name: Create Cache Key Files
44+
run: |
45+
echo "gmagjr2b9d" >github_actions_demo_test_cache_key.txt
46+
echo "${{ env.FDC_FIREBASE_TOOLS_VERSION }}" >github_actions_demo_assemble_firebase_tools_version.txt
47+
48+
- uses: actions/setup-node@v3
49+
with:
50+
node-version: ${{ env.FDC_NODE_VERSION }}
51+
cache: 'npm'
52+
cache-dependency-path: |
53+
firebase-dataconnect/demo/github_actions_demo_test_cache_key.txt
54+
firebase-dataconnect/demo/github_actions_demo_assemble_firebase_tools_version.txt
55+
56+
- name: cache package-lock.json
57+
id: package_json_lock
58+
uses: actions/cache@v4
59+
with:
60+
path: ${{ env.FDC_FIREBASE_TOOLS_DIR }}/package*.json
61+
key: firebase_tools_package_json-${{ env.FDC_FIREBASE_TOOLS_VERSION }}
62+
63+
- name: install firebase-tools from scratch
64+
if: steps.package_json_lock.outputs.cache-hit != 'true'
65+
run: |
66+
set -v
67+
mkdir -p ${{ env.FDC_FIREBASE_TOOLS_DIR }}
68+
cd ${{ env.FDC_FIREBASE_TOOLS_DIR }}
69+
echo '{}' > package.json
70+
npm install --fund=false --audit=false --save --save-exact firebase-tools@${{ env.FDC_FIREBASE_TOOLS_VERSION }}
71+
72+
- name: install firebase-tools from package-lock.json
73+
if: steps.package_json_lock.outputs.cache-hit == 'true'
74+
run: |
75+
cd ${{ env.FDC_FIREBASE_TOOLS_DIR }}
76+
npm ci --fund=false --audit=false
77+
78+
- uses: actions/setup-java@v4
79+
with:
80+
java-version: ${{ env.FDC_JAVA_VERSION }}
81+
distribution: temurin
82+
cache: gradle
83+
cache-dependency-path: |
84+
firebase-dataconnect/demo/build.gradle.kts
85+
firebase-dataconnect/demo/gradle.properties
86+
firebase-dataconnect/demo/gradle/wrapper/gradle-wrapper.properties
87+
firebase-dataconnect/demo/github_actions_demo_test_cache_key.txt
88+
89+
- name: tool versions
90+
continue-on-error: true
91+
run: |
92+
set +e -v
93+
which java
94+
java -version
95+
which javac
96+
javac -version
97+
which node
98+
node --version
99+
${{ env.FDC_FIREBASE_COMMAND }} --version
100+
./gradlew --version
101+
102+
- name: ./gradlew assemble test
103+
run: |
104+
set -x
105+
./gradlew \
106+
--no-daemon \
107+
${{ (inputs.gradleInfoLog && '--info') || '' }} \
108+
--profile \
109+
-PdataConnect.minimalApp.firebaseCommand=${{ env.FDC_FIREBASE_COMMAND }} \
110+
assemble test
111+
112+
- uses: actions/upload-artifact@v4
113+
with:
114+
name: apks
115+
path: firebase-dataconnect/demo/build/**/*.apk
116+
if-no-files-found: warn
117+
compression-level: 0
118+
119+
- uses: actions/upload-artifact@v4
120+
with:
121+
name: gradle_build_reports
122+
path: firebase-dataconnect/demo/build/reports/
123+
if-no-files-found: warn
124+
compression-level: 9
125+
126+
spotlessCheck:
127+
continue-on-error: false
128+
runs-on: ubuntu-latest
129+
steps:
130+
- uses: actions/checkout@v3
131+
with:
132+
sparse-checkout: firebase-dataconnect/demo
133+
134+
- name: Create Cache Key Files
135+
run: echo "h99ee4egfd" >github_actions_demo_spotless_cache_key.txt
136+
137+
- uses: actions/setup-java@v4
138+
with:
139+
java-version: ${{ env.FDC_JAVA_VERSION }}
140+
distribution: temurin
141+
cache: gradle
142+
cache-dependency-path: |
143+
firebase-dataconnect/demo/build.gradle.kts
144+
firebase-dataconnect/demo/gradle.properties
145+
firebase-dataconnect/demo/gradle/wrapper/gradle-wrapper.properties
146+
firebase-dataconnect/demo/github_actions_demo_spotless_cache_key.txt
147+
148+
- name: tool versions
149+
continue-on-error: true
150+
run: |
151+
set +e -v
152+
which java
153+
java -version
154+
which javac
155+
javac -version
156+
./gradlew --version
157+
158+
- name: ./gradlew spotlessCheck
159+
run: |
160+
set -x
161+
./gradlew \
162+
--no-daemon \
163+
${{ (inputs.gradleInfoLog && '--info') || '' }} \
164+
spotlessCheck

firebase-dataconnect/demo/.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,3 @@ local.properties
2121

2222
*.log
2323
*.hprof
24-
/dataConnectGeneratedSources/

firebase-dataconnect/demo/build.gradle.kts

Lines changed: 99 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,18 @@ spotless {
108108
}
109109
}
110110

111+
@DisableCachingByDefault(because = "Code generation is very fast and not worth caching")
111112
abstract class DataConnectGenerateSourcesTask : DefaultTask() {
112113

113-
@get:InputDirectory abstract val inputDirectory: DirectoryProperty
114+
@get:InputDirectory abstract val inputDirectory: Property<DirectoryTree>
114115

115-
@get:OutputDirectory abstract val outputDirectory: DirectoryProperty
116+
@get:Input abstract val firebaseToolsVersion: Property<String>
117+
118+
@get:Input abstract val firebaseCommand: Property<String>
116119

117-
@get:Internal abstract val nodeExecutableDirectory: DirectoryProperty
120+
@get:Input @get:Optional abstract val nodeExecutableDirectory: Property<String>
118121

119-
@get:Internal abstract val firebaseCommand: Property<String>
122+
@get:OutputDirectory abstract val outputDirectory: DirectoryProperty
120123

121124
@get:Internal abstract val workDirectory: DirectoryProperty
122125

@@ -127,40 +130,26 @@ abstract class DataConnectGenerateSourcesTask : DefaultTask() {
127130
@get:Inject protected abstract val fileSystemOperations: FileSystemOperations
128131

129132
@TaskAction
130-
fun run(inputChanges: InputChanges) {
131-
if (inputChanges.isIncremental) {
132-
val onlyLogFilesChanged =
133-
inputChanges.getFileChanges(inputDirectory).all { it.file.name.endsWith(".log") }
134-
if (onlyLogFilesChanged) {
135-
didWork = false
136-
return
137-
}
138-
}
139-
140-
val inputDirectory: File = inputDirectory.get().asFile
133+
fun run() {
134+
val inputDirectory: File = inputDirectory.get().dir
135+
val firebaseToolsVersion: String = firebaseToolsVersion.get()
136+
val firebaseCommand: String = firebaseCommand.get()
137+
val nodeExecutableDirectory: String? = nodeExecutableDirectory.orNull
141138
val outputDirectory: File = outputDirectory.get().asFile
142-
val nodeExecutableDirectory: File? = nodeExecutableDirectory.orNull?.asFile
143-
val firebaseCommand: String? = firebaseCommand.orNull
144139
val workDirectory: File = workDirectory.get().asFile
145140

141+
logger.info("inputDirectory: {}", inputDirectory.absolutePath)
142+
logger.info("firebaseToolsVersion: {}", firebaseToolsVersion)
143+
logger.info("firebaseCommand: {}", firebaseCommand)
144+
logger.info("nodeExecutableDirectory: {}", nodeExecutableDirectory)
145+
logger.info("outputDirectory: {}", outputDirectory.absolutePath)
146+
logger.info("workDirectory: {}", workDirectory.absolutePath)
147+
146148
outputDirectory.deleteRecursively()
147149
outputDirectory.mkdirs()
148150
workDirectory.deleteRecursively()
149151
workDirectory.mkdirs()
150152

151-
val newPath: String? =
152-
if (nodeExecutableDirectory === null) {
153-
null
154-
} else {
155-
val nodeExecutableDirectoryAbsolutePath = nodeExecutableDirectory.absolutePath
156-
val oldPath = providerFactory.environmentVariable("PATH").orNull
157-
if (oldPath === null) {
158-
nodeExecutableDirectoryAbsolutePath
159-
} else {
160-
nodeExecutableDirectoryAbsolutePath + File.pathSeparator + oldPath
161-
}
162-
}
163-
164153
val logFile =
165154
if (logger.isInfoEnabled) {
166155
null
@@ -172,12 +161,15 @@ abstract class DataConnectGenerateSourcesTask : DefaultTask() {
172161
logFile?.outputStream().use { logStream ->
173162
execOperations.runCatching {
174163
exec {
175-
commandLine(firebaseCommand ?: "firebase", "--debug", "dataconnect:sdk:generate")
164+
configureFirebaseCommand(
165+
this,
166+
firebaseCommand = firebaseCommand,
167+
nodeExecutableDirectory = nodeExecutableDirectory,
168+
path = providerFactory.environmentVariable("PATH").orNull,
169+
)
170+
args("--debug", "dataconnect:sdk:generate")
176171
workingDir(inputDirectory)
177172
isIgnoreExitValue = false
178-
if (newPath !== null) {
179-
environment("PATH", newPath)
180-
}
181173
if (logStream !== null) {
182174
standardOutput = logStream
183175
errorOutput = logStream
@@ -193,29 +185,59 @@ abstract class DataConnectGenerateSourcesTask : DefaultTask() {
193185
throw exception
194186
}
195187
}
188+
189+
companion object {
190+
191+
fun configureFirebaseCommand(
192+
execSpec: ExecSpec,
193+
firebaseCommand: String,
194+
nodeExecutableDirectory: String?,
195+
path: String?,
196+
) {
197+
execSpec.setCommandLine(firebaseCommand)
198+
199+
val newPath: String? =
200+
if (nodeExecutableDirectory === null) {
201+
null
202+
} else {
203+
if (path === null) {
204+
nodeExecutableDirectory
205+
} else {
206+
nodeExecutableDirectory + File.pathSeparator + path
207+
}
208+
}
209+
210+
if (newPath !== null) {
211+
execSpec.environment("PATH", newPath)
212+
}
213+
}
214+
}
196215
}
197216

217+
@DisableCachingByDefault(
218+
because = "Copying files is not worth caching, just like org.gradle.api.tasks.Copy"
219+
)
198220
abstract class CopyDirectoryTask : DefaultTask() {
199221

200-
@get:InputDirectory abstract val srcDirectory: DirectoryProperty
222+
@get:InputDirectory abstract val srcDirectory: Property<DirectoryTree>
201223

202224
@get:OutputDirectory abstract val destDirectory: DirectoryProperty
203225

204226
@get:Inject protected abstract val fileSystemOperations: FileSystemOperations
205227

206228
@TaskAction
207229
fun run() {
208-
val srcDirectory: File = srcDirectory.get().asFile
230+
val srcDirectoryTree: DirectoryTree = srcDirectory.get()
209231
val destDirectory: File = destDirectory.get().asFile
210232

211-
logger.info("srcDirectory: {}", srcDirectory.absolutePath)
233+
logger.info("srcDirectory: {}", srcDirectoryTree.dir.absolutePath)
212234
logger.info("destDirectory: {}", destDirectory.absolutePath)
213235

214236
destDirectory.deleteRecursively()
215237
destDirectory.mkdirs()
216238

217239
fileSystemOperations.copy {
218-
from(srcDirectory)
240+
from(srcDirectoryTree)
219241
into(destDirectory)
220242
}
221243
}
@@ -231,14 +253,39 @@ run {
231253
description =
232254
"Run firebase dataconnect:sdk:generate to generate the Data Connect Kotlin SDK sources"
233255

234-
inputDirectory = projectDirectory.dir("firebase")
235-
outputDirectory = projectDirectory.dir("dataConnectGeneratedSources")
256+
inputDirectory =
257+
fileTree(layout.projectDirectory.dir("firebase")).apply { exclude("**/*.log") }
258+
259+
outputDirectory = layout.buildDirectory.dir("dataConnect/generatedSources")
260+
261+
firebaseCommand =
262+
project.providers
263+
.gradleProperty("dataConnect.minimalApp.firebaseCommand")
264+
.orElse("firebase")
236265

237266
nodeExecutableDirectory =
238267
project.providers.gradleProperty("dataConnect.minimalApp.nodeExecutableDirectory").map {
239-
projectDirectory.dir(it)
268+
projectDirectory.dir(it).asFile.absolutePath
269+
}
270+
271+
val path = providers.environmentVariable("PATH")
272+
firebaseToolsVersion =
273+
providers.provider {
274+
providers
275+
.exec {
276+
DataConnectGenerateSourcesTask.configureFirebaseCommand(
277+
this,
278+
firebaseCommand = firebaseCommand.get(),
279+
nodeExecutableDirectory = nodeExecutableDirectory.orNull,
280+
path = path.orNull,
281+
)
282+
args("--version")
283+
}
284+
.standardOutput
285+
.asText
286+
.get()
287+
.trim()
240288
}
241-
firebaseCommand = project.providers.gradleProperty("dataConnect.minimalApp.firebaseCommand")
242289

243290
workDirectory = layout.buildDirectory.dir(name)
244291
}
@@ -247,13 +294,22 @@ run {
247294
androidComponents.onVariants { variant ->
248295
val variantNameTitleCase = variant.name[0].uppercase() + variant.name.substring(1)
249296
val copyTaskName = "dataConnectCopy${variantNameTitleCase}GeneratedSources"
297+
val objectFactory = objects
250298
val copyTask =
251299
tasks.register<CopyDirectoryTask>(copyTaskName) {
252300
group = dataConnectTaskGroupName
253301
description =
254302
"Copy the generated Data Connect Kotlin SDK sources into the " +
255303
"generated code directory for the \"${variant.name}\" variant."
256-
srcDirectory = generateSourcesTask.flatMap { it.outputDirectory }
304+
srcDirectory =
305+
generateSourcesTask.flatMap {
306+
it.outputDirectory.map { outputDirectory ->
307+
objectFactory.fileTree().apply {
308+
setDir(outputDirectory)
309+
exclude("**/*.log")
310+
}
311+
}
312+
}
257313
}
258314

259315
variant.sources.java!!.addGeneratedSourceDirectory(copyTask, CopyDirectoryTask::destDirectory)

0 commit comments

Comments
 (0)