diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d58a109 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,38 @@ +name: CI + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + test: + name: Tests + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'zulu' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Run tests + run: ./gradlew :phosphor-core:jvmTest + + - name: Check formatting + run: ./gradlew :phosphor-core:ktlintCheck diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..781d522 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,75 @@ +name: Publish to Maven Central + +on: + push: + tags: + - 'v*' + workflow_dispatch: + inputs: + dry_run: + description: 'Dry run (skip actual publish)' + required: false + default: 'false' + type: boolean + +permissions: + contents: write + +jobs: + publish: + name: Publish to Maven Central + runs-on: macos-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Validate tag version + if: startsWith(github.ref, 'refs/tags/v') + run: | + TAG_VERSION="${GITHUB_REF#refs/tags/v}" + GRADLE_VERSION=$(grep '^phosphorVersion=' gradle.properties | cut -d'=' -f2) + if [ "$TAG_VERSION" != "$GRADLE_VERSION" ]; then + echo "Error: Tag version ($TAG_VERSION) does not match gradle.properties ($GRADLE_VERSION)" + exit 1 + fi + echo "Version validated: $TAG_VERSION" + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'zulu' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Run tests before publish + run: ./gradlew :phosphor-core:jvmTest + + - name: Publish to Maven Central + if: ${{ github.event.inputs.dry_run != 'true' }} + env: + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.OSSRH_USERNAME }} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.OSSRH_PASSWORD }} + ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.SIGNING_KEY_ID }} + ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_KEY }} + ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_PASSWORD }} + run: ./gradlew :phosphor-core:publishAllPublicationsToMavenCentral + + - name: Dry run publish + if: ${{ github.event.inputs.dry_run == 'true' }} + run: | + echo "Dry run mode - publishing to Maven Local only" + ./gradlew :phosphor-core:publishToMavenLocal + + - name: Create GitHub Release + if: startsWith(github.ref, 'refs/tags/v') && github.event.inputs.dry_run != 'true' + uses: softprops/action-gh-release@v2 + with: + generate_release_notes: true + draft: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/build.gradle.kts b/build.gradle.kts index 1ed0f3c..7c6d251 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,6 @@ plugins { kotlin("multiplatform").apply(false) id("org.jlleitschuh.gradle.ktlint").version("12.2.0").apply(false) + id("org.jetbrains.dokka").apply(false) + id("com.vanniktech.maven.publish").apply(false) } diff --git a/gradle.properties b/gradle.properties index 0921691..3336a77 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,5 +11,8 @@ kotlin.mpp.enableCInteropCommonization=true #Versions kotlin.version=2.1.20 +#Dokka +org.jetbrains.dokka.experimental.gradle.pluginMode=V2EnabledWithHelpers + #Phosphor phosphorVersion=0.1.0 diff --git a/phosphor-core/build.gradle.kts b/phosphor-core/build.gradle.kts index 9db6280..fb317a1 100644 --- a/phosphor-core/build.gradle.kts +++ b/phosphor-core/build.gradle.kts @@ -1,9 +1,15 @@ +import com.vanniktech.maven.publish.JavadocJar +import com.vanniktech.maven.publish.KotlinMultiplatform +import com.vanniktech.maven.publish.SonatypeHost import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework plugins { kotlin("multiplatform") id("org.jlleitschuh.gradle.ktlint") + id("org.jetbrains.dokka") + id("com.vanniktech.maven.publish") + id("signing") } val phosphorVersion: String by project @@ -54,3 +60,54 @@ kotlin { } } } + +signing { + useGpgCmd() +} + +mavenPublishing { + publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL) + signAllPublications() + + configure(KotlinMultiplatform(javadocJar = JavadocJar.Dokka("dokkaGeneratePublicationHtml"))) + + coordinates("link.socket", "phosphor-core", version.toString()) + + pom { + name.set("Phosphor") + description.set( + "Kotlin Multiplatform rendering library that translates cognitive state " + + "into visible light — ASCII luminance, color ramps, particle physics, " + + "and 3D waveform surfaces.", + ) + url.set("https://github.com/socket-link/phosphor") + inceptionYear.set("2025") + + licenses { + license { + name.set("The Apache Software License, Version 2.0") + url.set("https://www.apache.org/licenses/LICENSE-2.0.txt") + distribution.set("repo") + } + } + + developers { + developer { + id.set("socket-link") + name.set("Socket Link") + url.set("https://github.com/socket-link") + } + } + + scm { + connection.set("scm:git:git://github.com/socket-link/phosphor.git") + developerConnection.set("scm:git:ssh://git@github.com:socket-link/phosphor.git") + url.set("https://github.com/socket-link/phosphor") + } + + issueManagement { + system.set("GitHub Issues") + url.set("https://github.com/socket-link/phosphor/issues") + } + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index ec2bacc..2ad5d67 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -14,6 +14,8 @@ pluginManagement { kotlin("multiplatform").version(kotlinVersion) id("org.jlleitschuh.gradle.ktlint").version("12.2.0") + id("org.jetbrains.dokka").version("2.1.0") + id("com.vanniktech.maven.publish").version("0.30.0") } }