diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml index ac66407..1c9dcdd 100644 --- a/.github/workflows/build-and-deploy.yml +++ b/.github/workflows/build-and-deploy.yml @@ -14,84 +14,88 @@ jobs: group: build-${{ github.workflow }}-${{ matrix.os }}-${{ github.event.number || github.ref }} cancel-in-progress: true steps: - - name: Checkout - uses: DanySK/action-checkout@0.2.14 - - uses: DanySK/build-check-deploy-gradle-action@2.4.8 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - with: -# Dry-deployment - check-command: ./gradlew build --parallel - deploy-command: >- - ./gradlew - uploadKotlinOSSRHToMavenCentralNexus - uploadPluginMavenToMavenCentralNexus - uploadPluginMarkerMavenToMavenCentralNexus - close - drop - --parallel - should-run-codecov: ${{ runner.os == 'Linux' }} - should-deploy: >- - ${{ - runner.os == 'Linux' - && !github.event.repository.fork - && github.event_name != 'pull_request' - }} - maven-central-username: ${{ secrets.MAVEN_CENTRAL_USERNAME }} - maven-central-password: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} - signing-key: ${{ secrets.SIGNING_KEY }} - signing-password: ${{ secrets.SIGNING_PASSWORD }} - release: - permissions: - contents: write - packages: write - concurrency: - # Only one release job at a time. Strictly sequential. - group: release - needs: - - build - runs-on: ubuntu-22.04 - if: >- - !github.event.repository.fork - && github.event_name != 'pull_request' - steps: - - name: Checkout - uses: actions/checkout@v4.1.1 +# - name: Checkout +# uses: DanySK/action-checkout@0.2.14 + - name: install npm on windows + if: ${{ matrix.os == 'windows-2022' }} + shell: bash + run: | + ./gradlew build --parallel +# env: +# CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} # with: -# token: ${{ secrets.DEPLOYMENT_TOKEN }} - - name: Find the version of Node from package.json - id: node-version - run: echo "version=$(jq -r .engines.node package.json)" >> $GITHUB_OUTPUT - - name: Install Node - uses: actions/setup-node@v4.0.2 - with: - node-version: ${{ steps.node-version.outputs.version }} - - uses: DanySK/build-check-deploy-gradle-action@2.4.8 - with: - build-command: true - check-command: true - deploy-command: | - npm install - npx semantic-release - should-run-codecov: false - should-deploy: true - github-token: ${{ github.token }} - gradle-publish-secret: ${{ secrets.GRADLE_PUBLISH_SECRET }} - gradle-publish-key: ${{ secrets.GRADLE_PUBLISH_KEY }} - maven-central-username: ${{ secrets.MAVEN_CENTRAL_USERNAME }} - maven-central-password: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} - signing-key: ${{ secrets.SIGNING_KEY }} - signing-password: ${{ secrets.SIGNING_PASSWORD }} - success: - runs-on: ubuntu-22.04 - needs: - - release - - build - if: >- - always() && ( - contains(join(needs.*.result, ','), 'failure') - || !contains(join(needs.*.result, ','), 'cancelled') - ) - steps: - - name: Verify that there were no failures - run: ${{ !contains(join(needs.*.result, ','), 'failure') }} +## Dry-deployment +# check-command: ./gradlew build --parallel +# deploy-command: >- +# ./gradlew +# uploadKotlinOSSRHToMavenCentralNexus +# uploadPluginMavenToMavenCentralNexus +# uploadPluginMarkerMavenToMavenCentralNexus +# close +# drop +# --parallel +# should-run-codecov: ${{ runner.os == 'Linux' }} +# should-deploy: >- +# ${{ +# runner.os == 'Linux' +# && !github.event.repository.fork +# && github.event_name != 'pull_request' +# }} +# maven-central-username: ${{ secrets.MAVEN_CENTRAL_USERNAME }} +# maven-central-password: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} +# signing-key: ${{ secrets.SIGNING_KEY }} +# signing-password: ${{ secrets.SIGNING_PASSWORD }} +# release: +# permissions: +# contents: write +# packages: write +# concurrency: +# # Only one release job at a time. Strictly sequential. +# group: release +# needs: +# - build +# runs-on: ubuntu-22.04 +# if: >- +# !github.event.repository.fork +# && github.event_name != 'pull_request' +# steps: +# - name: Checkout +# uses: actions/checkout@v4.1.1 +## with: +## token: ${{ secrets.DEPLOYMENT_TOKEN }} +# - name: Find the version of Node from package.json +# id: node-version +# run: echo "version=$(jq -r .engines.node package.json)" >> $GITHUB_OUTPUT +# - name: Install Node +# uses: actions/setup-node@v4.0.2 +# with: +# node-version: ${{ steps.node-version.outputs.version }} +# - uses: DanySK/build-check-deploy-gradle-action@2.4.8 +# with: +# build-command: true +# check-command: true +# deploy-command: | +# npm install +# npx semantic-release +# should-run-codecov: false +# should-deploy: true +# github-token: ${{ github.token }} +# gradle-publish-secret: ${{ secrets.GRADLE_PUBLISH_SECRET }} +# gradle-publish-key: ${{ secrets.GRADLE_PUBLISH_KEY }} +# maven-central-username: ${{ secrets.MAVEN_CENTRAL_USERNAME }} +# maven-central-password: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} +# signing-key: ${{ secrets.SIGNING_KEY }} +# signing-password: ${{ secrets.SIGNING_PASSWORD }} +# success: +# runs-on: ubuntu-22.04 +# needs: +# - release +# - build +# if: >- +# always() && ( +# contains(join(needs.*.result, ','), 'failure') +# || !contains(join(needs.*.result, ','), 'cancelled') +# ) +# steps: +# - name: Verify that there were no failures +# run: ${{ !contains(join(needs.*.result, ','), 'failure') }} diff --git a/src/main/kotlin/io/github/zuccherosintattico/gradle/CheckNodeTask.kt b/src/main/kotlin/io/github/zuccherosintattico/gradle/CheckNodeTask.kt index da6182c..ede3ddc 100644 --- a/src/main/kotlin/io/github/zuccherosintattico/gradle/CheckNodeTask.kt +++ b/src/main/kotlin/io/github/zuccherosintattico/gradle/CheckNodeTask.kt @@ -1,5 +1,7 @@ package io.github.zuccherosintattico.gradle +import com.lordcodes.turtle.shellRun +import io.github.zuccherosintattico.utils.NodeCommandsExtension.nodeVersion import org.gradle.api.DefaultTask import org.gradle.api.tasks.TaskAction @@ -17,11 +19,8 @@ open class CheckNodeTask : DefaultTask() { */ @TaskAction fun checkNode() { - val res = Runtime.getRuntime().runCatching { exec("node --version").waitFor() } - if (res.isSuccess) { - logger.quiet("Node is installed") - } else { - logger.error("Node is not installed") - } + runCatching { shellRun { nodeVersion() } } + .onSuccess { logger.quiet("Node is installed at version $it") } + .onFailure { logger.error("Node is not installed") } } } diff --git a/src/main/kotlin/io/github/zuccherosintattico/gradle/NpmDependenciesTask.kt b/src/main/kotlin/io/github/zuccherosintattico/gradle/NpmDependenciesTask.kt new file mode 100644 index 0000000..e1c1e81 --- /dev/null +++ b/src/main/kotlin/io/github/zuccherosintattico/gradle/NpmDependenciesTask.kt @@ -0,0 +1,26 @@ +package io.github.zuccherosintattico.gradle + +import com.lordcodes.turtle.shellRun +import io.github.zuccherosintattico.utils.NpmCommandsExtension.npmInstall +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.TaskAction + +/** + * A task to install NPM dependencies. + */ +open class NpmDependenciesTask : DefaultTask() { + init { + group = "Node" + description = "Install NPM dependencies" + } + + /** + The action to install NPM dependencies. + */ + @TaskAction + fun installNpmDependencies() { + logger.quiet("Installing NPM dependencies") + val out = shellRun(project.projectDir) { npmInstall() } + logger.quiet(out) + } +} diff --git a/src/main/kotlin/io/github/zuccherosintattico/gradle/Typescript.kt b/src/main/kotlin/io/github/zuccherosintattico/gradle/Typescript.kt index 4d5bbf8..fad90e9 100644 --- a/src/main/kotlin/io/github/zuccherosintattico/gradle/Typescript.kt +++ b/src/main/kotlin/io/github/zuccherosintattico/gradle/Typescript.kt @@ -1,72 +1,30 @@ package io.github.zuccherosintattico.gradle -import org.gradle.api.DefaultTask import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.model.ObjectFactory -import org.gradle.api.provider.Property -import org.gradle.api.provider.Provider -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.Internal -import org.gradle.api.tasks.TaskAction +import org.gradle.api.Task import org.gradle.kotlin.dsl.create -import org.gradle.kotlin.dsl.property import org.gradle.kotlin.dsl.register -import java.io.Serializable /** - * Just a template. + * A plugin to compile TypeScript files. */ open class Typescript : Plugin { override fun apply(project: Project) { val extension = project.extensions.create("typescript") - - val checkNodeTask = project.tasks.register("checkNode") - - project.tasks.register("compileTypescript") { + val checkNodeTask = project.registerTask("checkNode") + val npmDependenciesTask = project.registerTask("npmDependencies") { dependsOn(checkNodeTask) - sourceSet.set(extension.sourceSet) + } + project.registerTask("compileTypescript") { + dependsOn(npmDependenciesTask) + entrypoint.set(extension.entrypoint) + buildDir.set(extension.outputDir) } } -} - -/** - * Just a template. - */ -open class TypescriptTask : DefaultTask() { - - /** - * Just a template. - */ - @Input - val sourceSet: Property = project.objects.property() - - /** - * Read-only property calculated from the greeting. - */ - @Internal - val message: Provider = sourceSet.map { "Hello from $it" } - - /** - * Just a template. - */ - @TaskAction - fun printMessage() { - logger.quiet(message.get()) - } -} - -/** - * Just a template. - */ -open class TypescriptExtension(objects: ObjectFactory) : Serializable { - - /** - * Just a template. - */ - val sourceSet: Property = objects.property().convention("src/main/typescript") companion object { - private const val serialVersionUID = 1L + private inline fun Project.registerTask(name: String, noinline action: T.() -> Unit = {}) = + tasks.register(name, action) } } diff --git a/src/main/kotlin/io/github/zuccherosintattico/gradle/TypescriptExtension.kt b/src/main/kotlin/io/github/zuccherosintattico/gradle/TypescriptExtension.kt new file mode 100644 index 0000000..94cb81f --- /dev/null +++ b/src/main/kotlin/io/github/zuccherosintattico/gradle/TypescriptExtension.kt @@ -0,0 +1,29 @@ +package io.github.zuccherosintattico.gradle + +import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.Property +import org.gradle.kotlin.dsl.property +import java.io.Serializable + +/** + * The extension for configuring TypeScript plugin. + */ +open class TypescriptExtension(objects: ObjectFactory) : Serializable { + + /** + * The path to the TypeScript source set. + */ + val entrypoint: Property = objects.propertyWithDefault("src/main/typescript/index.ts") + + /** + * The path to the TypeScript output directory. + */ + val outputDir: Property = objects.propertyWithDefault("build/dist") + + companion object { + private const val serialVersionUID = 1L + + private inline fun ObjectFactory.propertyWithDefault(value: T): Property = + property().convention(value) + } +} diff --git a/src/main/kotlin/io/github/zuccherosintattico/gradle/TypescriptTask.kt b/src/main/kotlin/io/github/zuccherosintattico/gradle/TypescriptTask.kt new file mode 100644 index 0000000..fd0669c --- /dev/null +++ b/src/main/kotlin/io/github/zuccherosintattico/gradle/TypescriptTask.kt @@ -0,0 +1,38 @@ +package io.github.zuccherosintattico.gradle + +import com.lordcodes.turtle.shellRun +import io.github.zuccherosintattico.utils.NpmCommandsExtension.npxCommand +import org.gradle.api.DefaultTask +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction + +/** + * Typescript task. + */ +abstract class TypescriptTask : DefaultTask() { + + /** + * The source set to compile. + */ + @get:Input + abstract val entrypoint: Property + + /** + * The build directory. + */ + @get:OutputFile + abstract val buildDir: Property + + /** + * The task action. + */ + @TaskAction + fun compileTypescript() { + logger.quiet("Compiling TypeScript files in ${entrypoint.get()}") + shellRun(project.projectDir) { + npxCommand("tsc", "--outDir", buildDir.get(), entrypoint.get()) + }.also { logger.quiet("Compiled: $it") } + } +} diff --git a/src/main/kotlin/io/github/zuccherosintattico/utils/NodeCommandsExtension.kt b/src/main/kotlin/io/github/zuccherosintattico/utils/NodeCommandsExtension.kt new file mode 100644 index 0000000..bea360c --- /dev/null +++ b/src/main/kotlin/io/github/zuccherosintattico/utils/NodeCommandsExtension.kt @@ -0,0 +1,16 @@ +package io.github.zuccherosintattico.utils + +import com.lordcodes.turtle.ShellScript + +/** + * The extension for Node commands for [ShellScript]. + */ +object NodeCommandsExtension { + + /** + * Get the version of installed Node. + */ + fun ShellScript.nodeVersion(): String = nodeCommand(listOf("--version")) + + private fun ShellScript.nodeCommand(arguments: List): String = command("node", arguments) +} diff --git a/src/main/kotlin/io/github/zuccherosintattico/utils/NpmCommandsExtension.kt b/src/main/kotlin/io/github/zuccherosintattico/utils/NpmCommandsExtension.kt new file mode 100644 index 0000000..524cf25 --- /dev/null +++ b/src/main/kotlin/io/github/zuccherosintattico/utils/NpmCommandsExtension.kt @@ -0,0 +1,24 @@ +package io.github.zuccherosintattico.utils + +import com.lordcodes.turtle.ShellScript + +/** + * The extension for NPM commands for [ShellScript]. + */ +object NpmCommandsExtension { + + /** + * Install the dependencies. + */ + fun ShellScript.npmInstall(): String = npmCommand("install") + + /** + * Run the NPM command. + */ + fun ShellScript.npmCommand(vararg arguments: String): String = command("npm", arguments.toList()) + + /** + * Run the NPX command. + */ + fun ShellScript.npxCommand(vararg arguments: String): String = command("npx", arguments.toList()) +} diff --git a/src/test/kotlin/io/github/zuccherosintattico/gradle/TypescriptPluginTest.kt b/src/test/kotlin/io/github/zuccherosintattico/gradle/TypescriptPluginTest.kt index 18a158d..f7a18d7 100644 --- a/src/test/kotlin/io/github/zuccherosintattico/gradle/TypescriptPluginTest.kt +++ b/src/test/kotlin/io/github/zuccherosintattico/gradle/TypescriptPluginTest.kt @@ -1,6 +1,7 @@ package io.github.zuccherosintattico.gradle import io.kotest.core.spec.style.AnnotationSpec +import io.kotest.matchers.collections.shouldContainAll import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.GradleRunner import java.io.File @@ -44,16 +45,19 @@ class TypescriptPluginTest : AnnotationSpec() { build() } + private fun Path.stringWalk(): List = toFile().walk().map { it.relativeTo(toFile()).toString() }.toList() + @Test - fun `test the plugin`() { + fun `test base configuration`() { val testFolder = getTempDirectoryWithResources() - val result = testFolder.executeGradleTask("compileTypescript", "--stacktrace") - result.output.lines().forEach { println(it) } - -// ProcessBuilder("npx", "tsc", "--outDir", "./build/bin", "src/main/typescript/*.ts") -// .directory(folder.toFile()) -// .inheritIO() -// .start() -// .waitFor() + testFolder.executeGradleTask("compileTypescript", "--stacktrace") + + testFolder.stringWalk() shouldContainAll listOf( + "build/dist", + "build/dist/index.js", + "build/dist/person.js", + "node_modules", + "package-lock.json", + ) } }