From c00ddb19842abbaf53729ef2659a3db1ea64ecec Mon Sep 17 00:00:00 2001 From: Sebastiano Poggi Date: Tue, 13 Feb 2024 16:37:29 +0100 Subject: [PATCH 1/7] Add tagRelease task to root (#299) This task automates a series of checks and is used to prepare a release. It checks if the release branches have been merged into, and creates all the necessary tags. Main is tagged as requested, and release branches get an appended "-xxx" which is their IJP version number. --- build.gradle.kts | 111 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index f12d5bc14..9a5eabaab 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,5 @@ +import java.io.ByteArrayOutputStream + plugins { alias(libs.plugins.composeDesktop) apply false `jewel-linting` @@ -23,4 +25,113 @@ tasks { } register("check") { dependsOn(mergeSarifReports) } + + register("tagRelease") { + dependsOn("check") + + description = "Tags main branch and releases branches with provided tag name" + group = "release" + + doFirst { + val tagName = (project.property("tagName") as String?) + ?.takeIf { it.isNotBlank() } + ?: throw GradleException("Please provide a tag name using -PtagName=[value]") + + val stdOut = ByteArrayOutputStream() + + // Check we're on the main branch + logger.info("Checking current branch is main...") + exec { + commandLine = listOf("git", "rev-parse", "--abbrev-ref", "HEAD") + standardOutput = stdOut + }.assertNormalExitValue() + + val currentBranch = stdOut.use { it.toString() }.trim() + if (currentBranch != "main") { + throw GradleException("This task must only be run on the main branch") + } + + // Check tag doesn't already exist + logger.info("Checking current branch is main...") + exec { + commandLine = listOf("git", "tag") + standardOutput = stdOut + }.assertNormalExitValue() + + if (stdOut.toString().trim().lines().any { it == tagName }) { + throw GradleException("The tag $tagName already exists!") + } + + // Get the current HEAD hash + logger.info("Getting HEAD hash...") + stdOut.reset() + exec { + commandLine = listOf("git", "rev-parse", "HEAD") + standardOutput = stdOut + }.assertNormalExitValue() + + val currentHead = stdOut.use { it.toString() }.trim() + + // Enumerate the release branches + logger.info("Enumerating release branches...") + stdOut.reset() + exec { + commandLine = listOf("git", "branch") + standardOutput = stdOut + }.assertNormalExitValue() + + val releaseBranches = stdOut.use { it.toString() } + .lines() + .filter { it.trim().startsWith("releases/") } + .map { it.trim().removePrefix("releases/") } + + logger.lifecycle("Release branches: ${releaseBranches.joinToString { "releases/$it" }}") + + // Check all release branches have gotten the latest from main + logger.info("Validating release branches...") + for (branch in releaseBranches) { + stdOut.reset() + exec { + commandLine = listOf("git", "merge-base", "main", "releases/$branch") + standardOutput = stdOut + }.assertNormalExitValue() + + val mergeBase = stdOut.use { it.toString() }.trim() + if (mergeBase != currentHead) { + throw GradleException("Branch releases/$branch is not up-to-date with main!") + } + } + + // Tag main branch + logger.lifecycle("Tagging head of main branch as $tagName...") + exec { + commandLine = listOf("git", "tag", tagName) + }.assertNormalExitValue() + + // Tag release branches + for (branch in releaseBranches) { + val branchTagName = "$tagName-$branch" + logger.lifecycle("Tagging head of branch releases/$branch as $branchTagName...") + stdOut.reset() + + logger.info("Getting branch head commit...") + exec { + commandLine = listOf("git", "rev-parse", "releases/$branch") + standardOutput = stdOut + }.assertNormalExitValue() + + val branchHead = stdOut.use { it.toString() }.trim() + logger.info("HEAD of releases/$branch is $branchHead") + + logger.info("Tagging commit ${branchHead.take(7)} as $branchTagName") + stdOut.reset() + exec { + commandLine = listOf("git", "tag", branchTagName, branchHead) + standardOutput = stdOut + }.assertNormalExitValue() + } + + logger.info("All done!") + } + } } From dbf726adf83b4422f3d93a43a99c735202fb7785 Mon Sep 17 00:00:00 2001 From: Sebastiano Poggi Date: Wed, 14 Feb 2024 11:01:58 +0100 Subject: [PATCH 2/7] Fix publishing of Markdown artefacts --- buildSrc/src/main/kotlin/PublishConfiguration.kt | 8 +++++++- buildSrc/src/main/kotlin/jewel-publish.gradle.kts | 2 +- markdown/core/build.gradle.kts | 4 ++++ markdown/extension-gfm-alerts/build.gradle.kts | 4 ++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/kotlin/PublishConfiguration.kt b/buildSrc/src/main/kotlin/PublishConfiguration.kt index 0a57d3887..6a31d6565 100644 --- a/buildSrc/src/main/kotlin/PublishConfiguration.kt +++ b/buildSrc/src/main/kotlin/PublishConfiguration.kt @@ -1,11 +1,13 @@ @file:Suppress("UnstableApiUsage", "UnusedImports") +import org.gradle.api.Project import org.gradle.api.publish.PublishingExtension import org.gradle.api.publish.maven.MavenPom import org.gradle.kotlin.dsl.assign import org.gradle.kotlin.dsl.maven +import java.io.File -internal fun PublishingExtension.configureJewelRepositories() { +internal fun PublishingExtension.configureJewelRepositories(project: Project) { repositories { maven("https://packages.jetbrains.team/maven/p/kpm/public") { name = "Space" @@ -14,6 +16,10 @@ internal fun PublishingExtension.configureJewelRepositories() { password = System.getenv("MAVEN_SPACE_PASSWORD") } } + + maven(project.rootProject.layout.buildDirectory.dir("maven-test")) { + name = "LocalTest" + } } } diff --git a/buildSrc/src/main/kotlin/jewel-publish.gradle.kts b/buildSrc/src/main/kotlin/jewel-publish.gradle.kts index af41e53d4..16160db1d 100644 --- a/buildSrc/src/main/kotlin/jewel-publish.gradle.kts +++ b/buildSrc/src/main/kotlin/jewel-publish.gradle.kts @@ -19,7 +19,7 @@ val javadocJar by tasks.registering(Jar::class) { } publishing { - configureJewelRepositories() + configureJewelRepositories(project) publications { register("main") { diff --git a/markdown/core/build.gradle.kts b/markdown/core/build.gradle.kts index 17fe051e3..814394294 100644 --- a/markdown/core/build.gradle.kts +++ b/markdown/core/build.gradle.kts @@ -17,3 +17,7 @@ publicApiValidation { // We don't foresee changes to the data models for now excludedClassRegexes = setOf("org.jetbrains.jewel.markdown.MarkdownBlock.*") } + +publishing.publications.named("main") { + artifactId = "jewel-markdown-${project.name}" +} diff --git a/markdown/extension-gfm-alerts/build.gradle.kts b/markdown/extension-gfm-alerts/build.gradle.kts index bd624c946..94de60c21 100644 --- a/markdown/extension-gfm-alerts/build.gradle.kts +++ b/markdown/extension-gfm-alerts/build.gradle.kts @@ -17,3 +17,7 @@ publicApiValidation { // We don't foresee changes to the data models for now excludedClassRegexes = setOf("org.jetbrains.jewel.markdown.extensions.github.alerts.Alert\\$.*") } + +publishing.publications.named("main") { + artifactId = "jewel-markdown-${project.name}" +} From ed4a4c7d5fa165c9056f647041b951d0524489ac Mon Sep 17 00:00:00 2001 From: Sebastiano Poggi Date: Wed, 14 Feb 2024 11:26:50 +0100 Subject: [PATCH 3/7] Don't allow tagging if there are no release branches locally --- build.gradle.kts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 9a5eabaab..386c83045 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -85,6 +85,10 @@ tasks { .filter { it.trim().startsWith("releases/") } .map { it.trim().removePrefix("releases/") } + if (releaseBranches.isEmpty()) { + throw GradleException("No local release branches found, make sure they exist locally") + } + logger.lifecycle("Release branches: ${releaseBranches.joinToString { "releases/$it" }}") // Check all release branches have gotten the latest from main From 233e56b292fd2ce9c654079b3a743c88621dacd8 Mon Sep 17 00:00:00 2001 From: Sebastiano Poggi Date: Wed, 14 Feb 2024 11:53:00 +0100 Subject: [PATCH 4/7] Store version name in gradle.properties --- build.gradle.kts | 29 ++++++++++++++----- .../src/main/kotlin/jewel-publish.gradle.kts | 2 +- gradle.properties | 1 + 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 386c83045..05dcd4b57 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -33,9 +33,11 @@ tasks { group = "release" doFirst { - val tagName = (project.property("tagName") as String?) + val rawReleaseVersion = ((project.property("jewel.release.version") as String?) ?.takeIf { it.isNotBlank() } - ?: throw GradleException("Please provide a tag name using -PtagName=[value]") + ?: throw GradleException("Please provide a jewel.release.version in gradle.properties")) + + val releaseName = "v$rawReleaseVersion" val stdOut = ByteArrayOutputStream() @@ -53,13 +55,26 @@ tasks { // Check tag doesn't already exist logger.info("Checking current branch is main...") + stdOut.reset() exec { commandLine = listOf("git", "tag") standardOutput = stdOut }.assertNormalExitValue() - if (stdOut.toString().trim().lines().any { it == tagName }) { - throw GradleException("The tag $tagName already exists!") + if (stdOut.toString().trim().lines().any { it == releaseName }) { + throw GradleException("The tag $releaseName already exists!") + } + + // Check there are no uncommitted changes + logger.info("Checking all changes have been committed...") + stdOut.reset() + exec { + commandLine = listOf("git", "status", "--porcelain") + standardOutput = stdOut + }.assertNormalExitValue() + + if (stdOut.toString().isNotBlank()) { + throw GradleException("Please commit all changes before tagging a release") } // Get the current HEAD hash @@ -107,14 +122,14 @@ tasks { } // Tag main branch - logger.lifecycle("Tagging head of main branch as $tagName...") + logger.lifecycle("Tagging head of main branch as $releaseName...") exec { - commandLine = listOf("git", "tag", tagName) + commandLine = listOf("git", "tag", releaseName) }.assertNormalExitValue() // Tag release branches for (branch in releaseBranches) { - val branchTagName = "$tagName-$branch" + val branchTagName = "$releaseName-$branch" logger.lifecycle("Tagging head of branch releases/$branch as $branchTagName...") stdOut.reset() diff --git a/buildSrc/src/main/kotlin/jewel-publish.gradle.kts b/buildSrc/src/main/kotlin/jewel-publish.gradle.kts index 16160db1d..bd5b40ded 100644 --- a/buildSrc/src/main/kotlin/jewel-publish.gradle.kts +++ b/buildSrc/src/main/kotlin/jewel-publish.gradle.kts @@ -26,7 +26,7 @@ publishing { from(components["kotlin"]) artifact(javadocJar) artifact(sourcesJar) - version = project.version.toString() + version = project.properties["jewel.release.version"] as String artifactId = "jewel-${project.name}" pom { configureJewelPom() } } diff --git a/gradle.properties b/gradle.properties index 2ce2eecdc..9f76170c3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,3 +7,4 @@ kotlin.stdlib.default.dependency=false kotlin.incremental.useClasspathSnapshot=false bridge.ijp.target=241 +jewel.release.version=0.14.0 From 90f5f3435b29bc5ef2c9dca6b9d8bdc6dc892ccf Mon Sep 17 00:00:00 2001 From: Sebastiano Poggi Date: Wed, 14 Feb 2024 15:07:03 +0100 Subject: [PATCH 5/7] Make the markdown deps have a compileOnly dependency on Jewel-UI This is necessary since we have ui-xxx artefacts as well we may need to use depending if we're in the bridge or not, and which IJP version. --- markdown/core/build.gradle.kts | 2 +- markdown/extension-gfm-alerts/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/markdown/core/build.gradle.kts b/markdown/core/build.gradle.kts index 814394294..88a56b0fe 100644 --- a/markdown/core/build.gradle.kts +++ b/markdown/core/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } dependencies { - api(projects.ui) + compileOnly(projects.ui) implementation(libs.commonmark.core) diff --git a/markdown/extension-gfm-alerts/build.gradle.kts b/markdown/extension-gfm-alerts/build.gradle.kts index 94de60c21..fb5ef4bdd 100644 --- a/markdown/extension-gfm-alerts/build.gradle.kts +++ b/markdown/extension-gfm-alerts/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } dependencies { - api(projects.markdown.core) + compileOnly(projects.markdown.core) implementation(libs.commonmark.core) From 056b1a92267cc80646a7515262a9adddca2a36d8 Mon Sep 17 00:00:00 2001 From: Sebastiano Poggi Date: Wed, 14 Feb 2024 15:37:18 +0100 Subject: [PATCH 6/7] Improve Markdown readme sample --- markdown/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/markdown/README.md b/markdown/README.md index a6add7cf1..4f5b3800f 100644 --- a/markdown/README.md +++ b/markdown/README.md @@ -65,17 +65,18 @@ The second pass is done in the composition, and essentially renders a series of @Composable fun Markdown(blocks: List) { val isDark = JewelTheme.isDark + val markdownStyling = + remember(isDark) { if (isDark) MarkdownStyling.dark() else MarkdownStyling.light() } val blockRenderer = remember(markdownStyling, isDark) { if (isDark) MarkdownBlockRenderer.dark() else MarkdownBlockRenderer.light() } - val scrollState = rememberScrollState() SelectionContainer(Modifier.fillMaxSize()) { Column( - state = scrollState, + modifier = Modifier.verticalScroll(rememberScrollState()), verticalArrangement = Arrangement.spacedBy(markdownStyling.blockVerticalSpacing), ) { - items(markdownBlocks) { blockRenderer.render(it) } + blockRenderer.render(blocks) } } } From 1d845183fd9cc8e8e9e4818ed076ce8274a043ce Mon Sep 17 00:00:00 2001 From: Sebastiano Poggi Date: Wed, 14 Feb 2024 15:37:37 +0100 Subject: [PATCH 7/7] Don't fail fast IJP version checks --- .github/workflows/check-ide-version.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/check-ide-version.yml b/.github/workflows/check-ide-version.yml index 0b29b6780..fd2863636 100644 --- a/.github/workflows/check-ide-version.yml +++ b/.github/workflows/check-ide-version.yml @@ -11,6 +11,7 @@ jobs: runs-on: ubuntu-latest strategy: + fail-fast: false matrix: branch-name: - releases/232