diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/BuildOptions.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/BuildOptions.kt index cf3330d9ac11..2d51ce9d4a8b 100644 --- a/platform/build-scripts/src/org/jetbrains/intellij/build/BuildOptions.kt +++ b/platform/build-scripts/src/org/jetbrains/intellij/build/BuildOptions.kt @@ -480,7 +480,7 @@ data class BuildOptions( var resolveDependenciesMaxAttempts: Int = System.getProperty(RESOLVE_DEPENDENCIES_MAX_ATTEMPTS_PROPERTY)?.toInt() ?: 2 var resolveDependenciesDelayMs: Long = System.getProperty(RESOLVE_DEPENDENCIES_DELAY_MS_PROPERTY)?.toLong() ?: 1_000 - var randomSeedNumber: Long = 0 + var randomSeedNumber: Long = System.getProperty("intellij.build.randomSeed")?.takeIf { it.isNotBlank() }?.toLong() ?: Random.nextLong() /** * Use [BuildContext.isNightlyBuild] to get the actual nightly flag in build scripts. @@ -523,8 +523,6 @@ data class BuildOptions( val targetArchProperty = System.getProperty(TARGET_ARCH_PROPERTY)?.takeIf { it.isNotBlank() } targetArch = if (targetArchProperty == ARCH_CURRENT) JvmArchitecture.currentJvmArch else targetArchProperty?.let(JvmArchitecture::valueOf) - val randomSeedString = System.getProperty("intellij.build.randomSeed") - randomSeedNumber = if (randomSeedString.isNullOrBlank()) Random.nextLong() else randomSeedString.toLong() } } diff --git a/platform/build-scripts/testFramework/src/com/intellij/platform/buildScripts/testFramework/binaryReproducibility/BuildArtifactsReproducibilityTest.kt b/platform/build-scripts/testFramework/src/com/intellij/platform/buildScripts/testFramework/binaryReproducibility/BuildArtifactsReproducibilityTest.kt index 86fd779590ea..a3facd9b77fc 100644 --- a/platform/build-scripts/testFramework/src/com/intellij/platform/buildScripts/testFramework/binaryReproducibility/BuildArtifactsReproducibilityTest.kt +++ b/platform/build-scripts/testFramework/src/com/intellij/platform/buildScripts/testFramework/binaryReproducibility/BuildArtifactsReproducibilityTest.kt @@ -2,13 +2,14 @@ package com.intellij.platform.buildScripts.testFramework.binaryReproducibility import com.intellij.openapi.util.io.NioFiles +import com.intellij.platform.buildScripts.testFramework.binaryReproducibility.BuildArtifactsReproducibilityTest.Companion.isEnabled import kotlinx.coroutines.channels.Channel import org.jetbrains.intellij.build.BuildContext import org.jetbrains.intellij.build.BuildOptions import org.jetbrains.intellij.reproducibleBuilds.diffTool.FileTreeContentComparison import java.nio.file.Files import java.nio.file.Path -import java.util.* +import java.util.Random import kotlin.io.path.extension import kotlin.io.path.name import kotlin.io.path.writeText @@ -16,7 +17,8 @@ import kotlin.io.path.writeText internal class BuildArtifactsReproducibilityTest { private val randomSeedNumber = Random().nextLong() private val iterationChannel = Channel() - val iterations: Int = if (isEnabled) 2 else 1 + val iterations: Int + get() = if (isEnabled) 2 else 1 companion object { val isEnabled: Boolean = System.getProperty("intellij.build.test.artifacts.reproducibility") == "true" @@ -34,8 +36,11 @@ internal class BuildArtifactsReproducibilityTest { } suspend fun iterationFinished(iterationNumber: Int, build: BuildContext) { - if (!isEnabled) return - build.cleanBuildOutput() + if (!isEnabled) { + return + } + + cleanBuildOutput(build) if (iterationNumber == 1) { iterationChannel.send(build) /** @@ -49,64 +54,64 @@ internal class BuildArtifactsReproducibilityTest { iterationChannel.send(build) } } +} - private fun compare(build1: BuildContext, build2: BuildContext) { - assert(isEnabled) - val buildId = System.getProperty("teamcity.build.id") - val diffDirectory = when { - /** - * diff cannot be published if [org.jetbrains.intellij.build.BuildPaths.tempDir] is used - * since it's cleaned up at the end of each test - */ - buildId != null -> Files.createTempDirectory(build1.productProperties::class.java.simpleName + - this::class.java.simpleName + - buildId) - else -> build1.paths.projectHome - }.resolve(".diff") - val test = FileTreeContentComparison(diffDirectory, build1.paths.tempDir) - val result = test.assertTheSameDirectoryContent( - build1.paths.artifactDir, - build2.paths.artifactDir, - deleteBothAfterwards = true - ) - if (result.error != null) { - build1.messages.artifactBuilt("$diffDirectory") - } - report(result, diffDirectory, build1) +private fun compare(build1: BuildContext, build2: BuildContext) { + assert(isEnabled) + val buildId = System.getProperty("teamcity.build.id") + val diffDirectory = when { + /** + * diff cannot be published if [org.jetbrains.intellij.build.BuildPaths.tempDir] is used + * since it's cleaned up at the end of each test + */ + buildId != null -> Files.createTempDirectory(build1.productProperties::class.java.simpleName + + BuildArtifactsReproducibilityTest::class.java.simpleName + + buildId) + else -> build1.paths.projectHome + }.resolve(".diff") + val test = FileTreeContentComparison(diffDirectory, build1.paths.tempDir) + val result = test.assertTheSameDirectoryContent( + build1.paths.artifactDir, + build2.paths.artifactDir, + deleteBothAfterwards = true + ) + if (result.error != null) { + build1.messages.artifactBuilt("$diffDirectory") } + report(result, diffDirectory, build1) +} - private fun report(result: FileTreeContentComparison.ComparisonResult, reportDirectory: Path, context: BuildContext) { - val report = context.applicationInfo.fullProductName - .replace(" ", "-") - .plus("-compared-files.txt") - .let(reportDirectory::resolve) - Files.createDirectories(report.parent) - val reportText = result.comparedFiles - .sortedBy { it.extension } - .joinToString(separator = "\n") - report.writeText(reportText) - context.messages.artifactBuilt("$report") - context.messages.info("Compared:\n$reportText") - if (result.error != null) { - throw Exception("Build is not reproducible").apply { - addSuppressed(result.error) - } - } - require(result.comparedFiles.isNotEmpty()) { - "Nothing was compared" +private fun report(result: FileTreeContentComparison.ComparisonResult, reportDirectory: Path, context: BuildContext) { + val report = context.applicationInfo.fullProductName + .replace(" ", "-") + .plus("-compared-files.txt") + .let(reportDirectory::resolve) + Files.createDirectories(report.parent) + val reportText = result.comparedFiles + .sortedBy { it.extension } + .joinToString(separator = "\n") + report.writeText(reportText) + context.messages.artifactBuilt("$report") + context.messages.info("Compared:\n$reportText") + if (result.error != null) { + throw Exception("Build is not reproducible").apply { + addSuppressed(result.error) } } + require(result.comparedFiles.isNotEmpty()) { + "Nothing was compared" + } +} - private fun BuildContext.cleanBuildOutput() { - Files.newDirectoryStream(paths.buildOutputDir).use { content -> - content.filter { - it != paths.artifactDir && it != paths.logDir - }.forEach(NioFiles::deleteRecursively) - } - Files.newDirectoryStream(paths.artifactDir).use { content -> - content.filter { - it.name == "unscrambled" || it.name == "scramble-logs" - }.forEach(NioFiles::deleteRecursively) - } +private fun cleanBuildOutput(context: BuildContext) { + Files.newDirectoryStream(context.paths.buildOutputDir).use { content -> + content.filter { + it != context.paths.artifactDir && it != context.paths.logDir + }.forEach(NioFiles::deleteRecursively) + } + Files.newDirectoryStream(context.paths.artifactDir).use { content -> + content.filter { + it.name == "unscrambled" || it.name == "scramble-logs" + }.forEach(NioFiles::deleteRecursively) } } diff --git a/platform/build-scripts/testFramework/src/com/intellij/platform/buildScripts/testFramework/buildScriptTestUtils.kt b/platform/build-scripts/testFramework/src/com/intellij/platform/buildScripts/testFramework/buildScriptTestUtils.kt index ba8a461953fd..65445975ee85 100644 --- a/platform/build-scripts/testFramework/src/com/intellij/platform/buildScripts/testFramework/buildScriptTestUtils.kt +++ b/platform/build-scripts/testFramework/src/com/intellij/platform/buildScripts/testFramework/buildScriptTestUtils.kt @@ -309,7 +309,7 @@ private suspend fun doRunTestBuild( } } -private suspend fun checkKeymapPluginsAreBundledWithFrontend( +private fun checkKeymapPluginsAreBundledWithFrontend( jetBrainsClientMainModule: String, context: BuildContext, softly: SoftAssertions, diff --git a/python/build/src/org/jetbrains/intellij/build/pycharm/PyCharmBuildUtils.kt b/python/build/src/org/jetbrains/intellij/build/pycharm/PyCharmBuildUtils.kt index c2cd6be8ca59..771c47195ef3 100644 --- a/python/build/src/org/jetbrains/intellij/build/pycharm/PyCharmBuildUtils.kt +++ b/python/build/src/org/jetbrains/intellij/build/pycharm/PyCharmBuildUtils.kt @@ -12,11 +12,9 @@ import java.nio.file.Files import java.nio.file.Path import kotlin.io.path.div - object PyCharmBuildUtils { - const val SKELETONS_COPY_STEP = "skeletons_copy" + internal const val SKELETONS_COPY_STEP = "skeletons_copy" - @JvmStatic suspend fun copySkeletons(context: BuildContext, targetDirectory: Path, mask: String) { context.executeStep(TraceManager.spanBuilder("copying skeletons"), SKELETONS_COPY_STEP) { val skeletonsDir = context.paths.projectHome.resolve("skeletons")