Steup CI (#1)
Test Workflow / Lint and test library (push) Has been cancelled Details

Setup Github actions CI to test and publish the library.

Reviewed-on: #1
This commit is contained in:
Gleb Koval 2023-12-20 15:34:40 +00:00
parent f9ab02c68d
commit 71d98e540b
7 changed files with 197 additions and 37 deletions

View File

@ -10,4 +10,7 @@ max_line_length = 120
tab_width = 4 tab_width = 4
[{*.yaml,*.yml}] [{*.yaml,*.yml}]
indent_size = 2 indent_size = 2
[{*.kt,*.kts}]
ij_kotlin_packages_to_use_import_on_demand = org.junit.jupiter.api

40
.github/workflows/publish.yaml vendored Normal file
View File

@ -0,0 +1,40 @@
name: Publish Workflow
on:
push:
tags:
- v*
jobs:
publish:
name: Publish library
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v3
with:
distribution: adopt
java-version: 17
- name: Verify Gradle wrapper
uses: gradle/wrapper-validation-action@v1
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: Run checks
run: ./gradlew check
- name: Parse parameters
id: parse
run: |
export VERSION="$(echo ${{ github.ref_name }} | cut -c2-)"
echo "Parsed version: '$VERSION'"
echo "tinyvm_version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Publish to Gitea package repository
env:
TINYVM_VERSION: ${{ steps.parse.outputs.tinyvm_version }}
GITEA_USERNAME: ${{ github.repository_owner }}
GITEA_TOKEN: ${{ secrets.deploy_token }}
run: ./gradlew publishAllPublicationsToGiteaRepository

29
.github/workflows/test.yaml vendored Normal file
View File

@ -0,0 +1,29 @@
name: Test Workflow
on:
pull_request:
branches:
- main
push:
branches:
- main
jobs:
lint-and-test:
name: Lint and test library
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v3
with:
distribution: adopt
java-version: 17
- name: Verify Gradle wrapper
uses: gradle/wrapper-validation-action@v1
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
- name: Run checks
run: ./gradlew check

View File

@ -1,9 +1,12 @@
plugins { plugins {
kotlin("jvm") version "1.9.21" kotlin("jvm") version "1.9.21"
id("org.jmailen.kotlinter") version "4.1.0"
id("org.jetbrains.dokka") version "1.9.10"
`maven-publish`
} }
group = "net.koval" group = "net.koval.teamcity-build-step-extension-test-task"
version = "1.0-SNAPSHOT" version = System.getenv("FILESYSTEM_VERSION")
repositories { repositories {
mavenCentral() mavenCentral()
@ -19,4 +22,47 @@ tasks.test {
kotlin { kotlin {
jvmToolchain(11) jvmToolchain(11)
} }
val dokkaHtml by tasks.getting(org.jetbrains.dokka.gradle.DokkaTask::class)
val javadocJar: TaskProvider<Jar> by tasks.registering(Jar::class) {
dependsOn(dokkaHtml)
archiveClassifier.set("javadoc")
from(dokkaHtml.outputDirectory)
}
publishing {
publications.register<MavenPublication>("gpr") {
artifactId = "filesystem"
from(components["java"])
artifact(javadocJar)
pom {
name.set("TeamCity Kotlin Script build step extension library - Test Task - test filesystem")
description.set("This is a small project to make a very basic filesystem library in Kotlin and was" +
"created using the instructions below as part of my application to the JetBrains internship project" +
"\"TeamCity Kotlin Script build step extension library\".")
url.set("https://git.koval.net/cyclane/teamcity-build-step-extension-test-task")
developers {
developer {
id.set("cyclane")
name.set("Gleb Koval")
email.set("gleb@koval.net")
}
}
scm {
url.set("https://git.koval.net/cyclane/teamcity-build-step-extension-test-task")
}
}
}
repositories {
maven {
name = "Gitea"
url = uri("https://git.koval.net/api/packages/cyclane/maven")
credentials {
username = System.getenv("GITEA_USERNAME")
password = System.getenv("GITEA_TOKEN")
}
}
}
}

View File

@ -8,7 +8,10 @@ import java.nio.file.Path
class FSCreator { class FSCreator {
// Create entry, leaving existing folders' contents, but overwriting existing files. // Create entry, leaving existing folders' contents, but overwriting existing files.
@Throws(FileSystemException::class) @Throws(FileSystemException::class)
fun create(entryToCreate: FSEntry, destination: String) { fun create(
entryToCreate: FSEntry,
destination: String,
) {
val queue = ArrayDeque<Pair<FSEntry, Path>>() val queue = ArrayDeque<Pair<FSEntry, Path>>()
queue.add(entryToCreate to Path.of(destination)) queue.add(entryToCreate to Path.of(destination))
@ -20,7 +23,8 @@ class FSCreator {
is FSFile -> Files.createFile(path) is FSFile -> Files.createFile(path)
is FSFolder -> Files.createDirectory(path) is FSFolder -> Files.createDirectory(path)
} }
} catch (_: FileAlreadyExistsException) {} // Allow files/folders to already exist. } catch (_: FileAlreadyExistsException) {
} // Allow files/folders to already exist.
when (entry) { when (entry) {
is FSFile -> Files.write(path, entry.content.toByteArray()) is FSFile -> Files.write(path, entry.content.toByteArray())
is FSFolder -> queue.addAll(entry.entries.map { it to path }) is FSFolder -> queue.addAll(entry.entries.map { it to path })

View File

@ -4,6 +4,6 @@ package filesystem
// (as we expect), and it also makes the class abstract as required. // (as we expect), and it also makes the class abstract as required.
sealed class FSEntry(val name: String) sealed class FSEntry(val name: String)
class FSFile(name: String, val content: String): FSEntry(name) class FSFile(name: String, val content: String) : FSEntry(name)
class FSFolder(name: String, val entries: List<FSEntry>): FSEntry(name) class FSFolder(name: String, val entries: List<FSEntry>) : FSEntry(name)

View File

@ -29,19 +29,36 @@ class FSCreatorTest {
fun `create entries`() { fun `create entries`() {
val readme = FSFile("README", "Hello World!") val readme = FSFile("README", "Hello World!")
val gomod = FSFile("go.mod", "module example.com/hello-world\n\ngo1.21.5") val gomod = FSFile("go.mod", "module example.com/hello-world\n\ngo1.21.5")
val maingo = FSFile("main.go", "package main\n\nimport \"example.com/hello-world/utils\"\n\n" + val maingo =
"func main() {\n\tprintln(\"Hello World!\")\n}") FSFile(
val helloworldgo = FSFile("hello-world.go", "package utils\n\nfunc PrintHelloWorld() {\n" + "main.go",
"\tprintln(\"Hello World!\")\n}") "package main\n\nimport \"example.com/hello-world/utils\"\n\n" +
"func main() {\n\tprintln(\"Hello World!\")\n}",
)
val helloworldgo =
FSFile(
"hello-world.go",
"package utils\n\nfunc PrintHelloWorld() {\n" +
"\tprintln(\"Hello World!\")\n}",
)
assertDoesNotThrow("should create entries") { assertDoesNotThrow("should create entries") {
creator.create(FSFolder("folder", listOf( creator.create(
readme, FSFolder(
gomod, "folder",
maingo, listOf(
FSFolder("utils", listOf( readme,
helloworldgo gomod,
)) maingo,
)), "_tmp") FSFolder(
"utils",
listOf(
helloworldgo,
),
),
),
),
"_tmp",
)
} }
// If objects don't exist, these functions will throw anyway, so don't explicitly check for existence. // If objects don't exist, these functions will throw anyway, so don't explicitly check for existence.
// Similarly, don't explicitly check if an object is a directory. // Similarly, don't explicitly check if an object is a directory.
@ -54,25 +71,46 @@ class FSCreatorTest {
@Test @Test
fun `create existing entries`() { fun `create existing entries`() {
assertDoesNotThrow("creation one") { assertDoesNotThrow("creation one") {
creator.create(FSFolder("folder", listOf( creator.create(
FSFolder("sub-folder", listOf( FSFolder(
FSFile("hi", "hi") "folder",
)), listOf(
FSFolder("another-folder", listOf()), FSFolder(
FSFile("1.txt", "One!"), "sub-folder",
FSFile("2.txt", "Two!") listOf(
)), "_tmp") FSFile("hi", "hi"),
),
),
FSFolder("another-folder", listOf()),
FSFile("1.txt", "One!"),
FSFile("2.txt", "Two!"),
),
),
"_tmp",
)
} }
assertDoesNotThrow("creation two") { assertDoesNotThrow("creation two") {
creator.create(FSFolder("folder", listOf( creator.create(
FSFolder("another-folder", listOf( FSFolder(
FSFolder("secrets", listOf( "folder",
FSFile("secret", "P4ssW0rd") listOf(
)) FSFolder(
)), "another-folder",
FSFile("1.txt", "One is a good number"), listOf(
FSFile("3.txt", "Three!") FSFolder(
)), "_tmp") "secrets",
listOf(
FSFile("secret", "P4ssW0rd"),
),
),
),
),
FSFile("1.txt", "One is a good number"),
FSFile("3.txt", "Three!"),
),
),
"_tmp",
)
} }
assertEquals("hi", Files.readString(Path.of("_tmp/folder/sub-folder/hi"))) assertEquals("hi", Files.readString(Path.of("_tmp/folder/sub-folder/hi")))
assertEquals("P4ssW0rd", Files.readString(Path.of("_tmp/folder/another-folder/secrets/secret"))) assertEquals("P4ssW0rd", Files.readString(Path.of("_tmp/folder/another-folder/secrets/secret")))