Skip to content

Commit a2978c2

Browse files
committed
chore: app,doc,coverage publishing using Github actions.
1 parent 35da0d2 commit a2978c2

File tree

14 files changed

+281
-32
lines changed

14 files changed

+281
-32
lines changed

.github/config/configuration.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
"labels": [
3737
"deps",
3838
"dependencies",
39-
"chore(deps)"
39+
"chore(deps)",
40+
"build(deps)"
4041
]
4142
},
4243
{

.github/release.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ changelog:
3434
- deps
3535
- dependencies
3636
- chore(deps)
37+
- build(deps)
3738
- title: Other Changes 🖇️
3839
labels:
3940
- "*"

.github/workflows/build.yml

Lines changed: 74 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ jobs:
4646
runs-on: ${{ matrix.os }}
4747
continue-on-error: false
4848

49+
outputs:
50+
name: ${{ steps.gradle-build.outputs.name }}
51+
group: ${{ steps.gradle-build.outputs.group }}
52+
version: ${{ steps.gradle-build.outputs.version }}
53+
4954
steps:
5055
- name: 🛎️ Check out the source code
5156
uses: actions/checkout@v3
@@ -74,7 +79,7 @@ jobs:
7479
- name: 🏗️ Gradle Build & Run
7580
id: gradle-build
7681
run: |
77-
./gradlew build
82+
./gradlew ciBuild
7883
env:
7984
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8085
JOB_CONTEXT: ${{ toJSON(job) }}
@@ -84,32 +89,42 @@ jobs:
8489
STRATEGY_CONTEXT: ${{ toJSON(strategy) }}
8590
MATRIX_CONTEXT: ${{ toJSON(matrix) }}
8691

87-
- name: 📤 Uploading ${{ matrix.os }} executable jar
88-
if: steps.gradle-build.outcome == 'success' && runner.os == 'XLinux'
92+
- name: 📤 Uploading ${{ matrix.os }} build artifacts
93+
if: steps.gradle-build.outcome == 'success' && runner.os == 'Linux'
8994
uses: actions/upload-artifact@v3
9095
with:
91-
name: ${{ steps.gradle-build.outputs.appjar_name }}
96+
name: ${{ steps.gradle-build.outputs.dist_name }}.zip
9297
path: |
93-
${{ steps.gradle-build.outputs.appjar_path }}
98+
backend/build/distributions/backend-*.zip
9499
if-no-files-found: error
95100

96-
- name: 🚀 Deploy html docs to 🕸️website
97-
if: startsWith(github.ref, 'refs/tags/') && runner.os == 'XLinux'
101+
- name: 🕸Deploy the webapp to Github Pages
102+
if: steps.gradle-build.outcome == 'success' && runner.os == 'Linux'
103+
uses: JamesIves/[email protected]
104+
with:
105+
branch: gh-pages
106+
folder: web/build/dist/js/productionExecutable
107+
target-folder: app
108+
clean: true
109+
commit-message: 'web: Deployed web app'
110+
111+
- name: 🏖️ Publish documentation to Github Pages
112+
if: startsWith(github.ref, 'refs/tags/') && runner.os == 'Linux'
98113
uses: JamesIves/[email protected]
99114
with:
100-
branch: main
101-
folder: build/dokka
102-
target-folder: docs/apidoc/
115+
branch: gh-pages
116+
folder: build/dokka/htmlMultiModule
117+
target-folder: docs
103118
clean: true
104-
commit-message: 'doc: Deployed dokka website'
119+
commit-message: 'doc: Deployed dokka html documentation'
105120

106-
- name: 🏖️ Deploy coverage report to website
107-
if: startsWith(github.ref, 'refs/tags/') && runner.os == 'XLinux'
121+
- name: 🏖️ Publish coverage report to Github Pages
122+
if: startsWith(github.ref, 'refs/tags/') && runner.os == 'Linux'
108123
uses: JamesIves/[email protected]
109124
with:
110-
branch: main
111-
folder: build/reports
112-
target-folder: docs/reports/
125+
branch: gh-pages
126+
folder: build/reports/kover/html
127+
target-folder: reports
113128
clean: true
114129
commit-message: 'doc: Deployed coverage report'
115130

@@ -130,4 +145,46 @@ jobs:
130145
git commit --message "doc: Update generated.txt"
131146
git push
132147
# git push origin HEAD:${{ github.event.repository.default_branch }}
133-
fi
148+
fi
149+
150+
151+
# GitHub Release Action on tag push
152+
release:
153+
name: 🚰 Release new version.
154+
needs: [ build ]
155+
if: startsWith(github.ref, 'refs/tags/') && needs.build.result == 'success'
156+
runs-on: ubuntu-latest
157+
158+
steps:
159+
- name: 🛎️Check out the source code
160+
uses: actions/checkout@v3
161+
with:
162+
fetch-depth: 0
163+
submodules: recursive
164+
165+
- name: ⚙️Build Changelog
166+
id: github_release
167+
uses: mikepenz/release-changelog-builder-action@v4
168+
with:
169+
configuration: ".github/config/configuration.json"
170+
commitMode: true
171+
ignorePreReleases: ${{ !contains(github.ref, '-') }}
172+
env:
173+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
174+
175+
- name: ⏬Download all the build artifacts
176+
uses: actions/download-artifact@v3
177+
with:
178+
path: release-artifacts
179+
180+
- name: ✨Github Release (version = ${{ needs.build.outputs.version }})
181+
uses: softprops/action-gh-release@v1
182+
with:
183+
# body_path: ${{ github.workspace }}-CHANGELOG.txt
184+
body: ${{ steps.github_release.outputs.changelog }}
185+
files: |
186+
${{ github.workspace }}/release-artifacts/**
187+
generate_release_notes: true
188+
fail_on_unmatched_files: true
189+
env:
190+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

build.gradle.kts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1+
import common.commonProjectName
2+
13
plugins {
24
plugins.common
35
plugins.misc
46
kotlin("multiplatform") apply false
57
}
8+
9+
// Multi module single coverage report
10+
dependencies {
11+
kover(project(":$commonProjectName"))
12+
kover(project("backend"))
13+
kover(project("web"))
14+
}

gradle/build-logic/common-plugins/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ gradlePlugin {
5454

5555
// Uncomment the id to change plugin id for this pre-compiled plugin
5656
named("plugins.common") {
57-
// id = "dev.suresh.gradle.plugins.common"
57+
// id = "build.plugins.common"
5858
displayName = "Common build-logic plugin"
5959
description = "Common pre-compiled script plugin"
6060
tags = listOf("Common Plugin", "build-logic")

gradle/build-logic/common-plugins/src/main/kotlin/common/CommonExtns.kt

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,28 @@
11
package common
22

33
import java.io.File
4+
import java.nio.file.FileSystems
5+
import java.nio.file.Files
6+
import java.nio.file.Path
47
import java.text.DecimalFormat
8+
import java.text.NumberFormat
59
import kotlin.math.ln
610
import kotlin.math.pow
11+
import kotlin.properties.ReadOnlyProperty
12+
import kotlin.reflect.full.isSubtypeOf
13+
import kotlin.reflect.typeOf
14+
15+
internal val DEC_FORMAT = DecimalFormat("#.##")
716

817
/** OS temp location */
918
val tmp: String = "${System.getProperty("java.io.tmpdir")}${File.separator}"
1019

11-
internal val DEC_FORMAT = DecimalFormat("#.##")
20+
/** Returns the file size in a human-readable format. */
21+
val File.displaySize
22+
get() = length().byteDisplaySize()
23+
24+
val Long.compactFmt: String
25+
get() = NumberFormat.getCompactNumberInstance().format(this)
1226

1327
/**
1428
* Returns a human-readable version of the Byte size, where the input represents a specific number
@@ -31,3 +45,51 @@ fun Long.byteDisplaySize(si: Boolean = true): String {
3145
}
3246
}
3347
}
48+
49+
/** Find the file ends with given [format] under the directory. */
50+
fun File.findPkg(format: String?) =
51+
when (format != null) {
52+
true -> walk().firstOrNull { it.isFile && it.name.endsWith(format, ignoreCase = true) }
53+
else -> null
54+
}
55+
56+
/** List files based on the glob [pattern] */
57+
fun Path.glob(pattern: String): List<Path> {
58+
val matcher = FileSystems.getDefault().getPathMatcher("glob:$pattern")
59+
return Files.walk(this).filter(matcher::matches).toList()
60+
}
61+
62+
/** An extension function to join a multiline string for JVM arguments. */
63+
fun String.joinToConfigString(separator: CharSequence = "") =
64+
trimMargin().lines().joinToString(separator) { it.trim() }
65+
66+
/** System property delegate */
67+
@Suppress("IMPLICIT_CAST_TO_ANY")
68+
inline fun <reified T> sysProp(): ReadOnlyProperty<Any?, T> = ReadOnlyProperty { _, property ->
69+
val propVal = System.getProperty(property.name, "")
70+
val propVals = propVal.split(",", " ").filter { it.isNotBlank() }
71+
val kType = typeOf<T>()
72+
73+
when {
74+
// Handle enum values
75+
kType.isSubtypeOf(typeOf<Enum<*>?>()) ->
76+
T::class.java.enumConstants.filterIsInstance<Enum<*>>().singleOrNull { it.name == propVal }
77+
78+
// Handle primitive and collection types
79+
else ->
80+
when (kType) {
81+
typeOf<String>() -> propVal
82+
typeOf<Int>() -> propVal.toInt()
83+
typeOf<Boolean>() -> propVal.toBoolean()
84+
typeOf<Long>() -> propVal.toLong()
85+
typeOf<Double>() -> propVal.toDouble()
86+
typeOf<List<String>>() -> propVals
87+
typeOf<List<Int>>() -> propVals.map { it.toInt() }
88+
typeOf<List<Long>>() -> propVals.map { it.toLong() }
89+
typeOf<List<Double>>() -> propVals.map { it.toDouble() }
90+
typeOf<List<Boolean>>() -> propVals.map { it.toBoolean() }
91+
else -> error("'${property.name}' system property type ($kType) is not supported!")
92+
}
93+
}
94+
as T
95+
}

gradle/build-logic/common-plugins/src/main/kotlin/common/KotlinExtns.kt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package common
22

33
import org.gradle.api.JavaVersion
44
import org.gradle.api.Project
5+
import org.gradle.api.artifacts.ExternalDependency
56
import org.gradle.api.attributes.Attribute
67
import org.gradle.api.tasks.compile.JavaCompile
78
import org.gradle.api.tasks.testing.Test
@@ -12,6 +13,7 @@ import org.jetbrains.kotlin.gradle.dsl.*
1213
import org.jetbrains.kotlin.gradle.plugin.LanguageSettingsBuilder
1314
import org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinNpmInstallTask
1415
import org.jetbrains.kotlin.gradle.targets.jvm.tasks.KotlinJvmTest
16+
import java.nio.file.Path
1517

1618
/** Java version properties. */
1719
val Project.javaVersion
@@ -195,3 +197,35 @@ context(Project)
195197
fun KotlinNpmInstallTask.configureKotlinNpm() {
196198
//args.add("--ignore-engines")
197199
}
200+
201+
/** Returns the path of the dependency jar in runtime classpath. */
202+
context(Project)
203+
val ExternalDependency.dependencyPath get() = configurations
204+
.named("runtimeClasspath")
205+
.get()
206+
.resolvedConfiguration
207+
.resolvedArtifacts
208+
.find { it.moduleVersion.id.module == module }
209+
?.file
210+
?.path
211+
?: error("Could not find $name in runtime classpath")
212+
213+
/** Returns the application `run` command. */
214+
context(Project)
215+
fun Path.appRunCmd(args: List<String>): String {
216+
val path = layout.projectDirectory.asFile.toPath().relativize(this)
217+
val newLine = System.lineSeparator()
218+
val lineCont = """\""" // Bash line continuation
219+
val indent = "\t"
220+
return args.joinToString(
221+
prefix = """
222+
|To Run the app,
223+
|${'$'} java -jar $lineCont $newLine
224+
""".trimMargin(),
225+
postfix = "$newLine$indent$path",
226+
separator = newLine,
227+
) {
228+
// Escape the globstar
229+
"$indent$it $lineCont".replace("*", """\*""")
230+
}
231+
}

gradle/build-logic/common-plugins/src/main/kotlin/common/ProjectExtns.kt

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package common
22

3+
import java.io.ByteArrayOutputStream
34
import java.nio.file.Path
45
import org.gradle.accessors.dm.LibrariesForLibs
56
import org.gradle.api.Project
@@ -85,3 +86,48 @@ inline fun <reified T : Task> TaskContainer.maybeRegister(
8586
in names -> named(taskName, T::class)
8687
else -> register(taskName, T::class)
8788
}.also { it.configure(configAction) }
89+
90+
/** Return incubator modules of the tool chain JDK */
91+
val Project.incubatorModules
92+
get(): String {
93+
val javaCmd = project.javaToolchainPath.resolve("bin").resolve("java")
94+
val bos = ByteArrayOutputStream()
95+
val execResult = exec {
96+
workingDir = layout.buildDirectory.get().asFile
97+
commandLine = listOf(javaCmd.toString())
98+
args = listOf("--list-modules")
99+
standardOutput = bos
100+
errorOutput = bos
101+
}
102+
execResult.assertNormalExitValue()
103+
return bos.toString(Charsets.UTF_8)
104+
.lines()
105+
.filter { it.startsWith("jdk.incubator") }
106+
.joinToString(",") { it.substringBefore("@").trim() }
107+
}
108+
109+
/**
110+
* Print all the catalog version strings and it's values.
111+
*
112+
* [VersionCatalogsExtension](https://docs.gradle.org/current/userguide/platforms.html#sub:type-unsafe-access-to-catalog)
113+
*/
114+
fun Project.printVersionCatalog() {
115+
if (debugEnabled) {
116+
catalogs.catalogNames.map { cat ->
117+
println("=== Catalog $cat ===")
118+
val catalog = catalogs.named(cat)
119+
catalog.versionAliases.forEach { alias ->
120+
println("${alias.padEnd(30, '-')}-> ${catalog.findVersion(alias).get()}")
121+
}
122+
}
123+
}
124+
}
125+
126+
/** Print all the tasks */
127+
fun Project.printTaskGraph() {
128+
if (debugEnabled) {
129+
gradle.taskGraph.whenReady {
130+
allTasks.forEachIndexed { index, task -> println("${index + 1}. ${task.name}") }
131+
}
132+
}
133+
}

0 commit comments

Comments
 (0)