TestBalloon 0.8.0-Beta1-K2.3.0 is ready and waitin...
# testballoon
o
TestBalloon 0.8.0-Beta1-K2.3.0 is ready and waiting to get out, but unfortunately, the publishing task breaks, and I'm not aware of any way to reproduce this locally. If you have any idea, I'm all ears. 🧡
Copy code
Stack trace
org.gradle.internal.execution.WorkValidationException: Some problems were found with the configuration of task ':testBalloon-gradle-plugin:signPluginMavenPublication' (type 'Sign').	
  - Gradle detected a problem with the following location: '/Users/runner/work/testBalloon/testBalloon/testBalloon-gradle-plugin/build/libs/testBalloon-gradle-plugin-0.8.0-Beta1-K2.3.0-sources.jar.asc'.	
    	
    Reason: Task ':testBalloon-gradle-plugin:publishMavenPublicationToMavenCentralRepository' uses this output of task ':testBalloon-gradle-plugin:signPluginMavenPublication' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed.	
    	
    Possible solutions:	
      1. Declare task ':testBalloon-gradle-plugin:signPluginMavenPublication' as an input of ':testBalloon-gradle-plugin:publishMavenPublicationToMavenCentralRepository'.	
      2. Declare an explicit dependency on ':testBalloon-gradle-plugin:signPluginMavenPublication' from ':testBalloon-gradle-plugin:publishMavenPublicationToMavenCentralRepository' using Task#dependsOn.	
      3. Declare an explicit dependency on ':testBalloon-gradle-plugin:signPluginMavenPublication' from ':testBalloon-gradle-plugin:publishMavenPublicationToMavenCentralRepository' using Task#mustRunAfter.	
    	
    For more information, please refer to <https://docs.gradle.org/9.2.1/userguide/validation_problems.html#implicit_dependency> in the Gradle documentation.	
  - Gradle detected a problem with the following location: '/Users/runner/work/testBalloon/testBalloon/testBalloon-gradle-plugin/build/libs/testBalloon-gradle-plugin-0.8.0-Beta1-K2.3.0.jar.asc'.	
    	
    Reason: Task ':testBalloon-gradle-plugin:publishMavenPublicationToMavenCentralRepository' uses this output of task ':testBalloon-gradle-plugin:signPluginMavenPublication' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed.	
    	
    Possible solutions:	
      1. Declare task ':testBalloon-gradle-plugin:signPluginMavenPublication' as an input of ':testBalloon-gradle-plugin:publishMavenPublicationToMavenCentralRepository'.	
      2. Declare an explicit dependency on ':testBalloon-gradle-plugin:signPluginMavenPublication' from ':testBalloon-gradle-plugin:publishMavenPublicationToMavenCentralRepository' using Task#dependsOn.	
      3. Declare an explicit dependency on ':testBalloon-gradle-plugin:signPluginMavenPublication' from ':testBalloon-gradle-plugin:publishMavenPublicationToMavenCentralRepository' using Task#mustRunAfter.	
    	
    For more information, please refer to <https://docs.gradle.org/9.2.1/userguide/validation_problems.html#implicit_dependency> in the Gradle documentation.	
	at org.gradle.internal.execution.WorkValidationException$BuilderWithSummary.build(WorkValidationException.java:137)	
	at org.gradle.internal.execution.WorkValidationException$BuilderWithSummary.get(WorkValidationException.java:119)	
	at org.gradle.internal.execution.impl.DefaultExecutionProblemHandler.throwValidationException(DefaultExecutionProblemHandler.java:96)	
	at org.gradle.internal.execution.impl.DefaultExecutionProblemHandler.handleReportedProblems(DefaultExecutionProblemHandler.java:81)	
	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:60)	
	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:40)	
	at org.gradle.internal.execution.steps.AbstractCaptureStateBeforeExecutionStep.execute(AbstractCaptureStateBeforeExecutionStep.java:76)	
	at org.gradle.internal.execution.steps.AbstractCaptureStateBeforeExecutionStep.execute(AbstractCaptureStateBeforeExecutionStep.java:45)	
	at org.gradle.internal.execution.steps.AbstractSkipEmptyWorkStep.executeWithNonEmptySources(AbstractSkipEmptyWorkStep.java:136)	
	at org.gradle.internal.execution.steps.AbstractSkipEmptyWorkStep.execute(AbstractSkipEmptyWorkStep.java:61)	
	at org.gradle.internal.execution.steps.AbstractSkipEmptyWorkStep.execute(AbstractSkipEmptyWorkStep.java:38)	
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)	
	at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:36)	
	at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:23)	
	at org.gradle.internal.execution.steps.HandleStaleOutputsStep.execute(HandleStaleOutputsStep.java:75)	
	at org.gradle.internal.execution.steps.HandleStaleOutputsStep.execute(HandleStaleOutputsStep.java:41)	
	at org.gradle.internal.execution.steps.AssignMutableWorkspaceStep.lambda$execute$0(AssignMutableWorkspaceStep.java:35)	
	at org.gradle.api.internal.tasks.execution.TaskExecution$4.withWorkspace(TaskExecution.java:297)	
	at org.gradle.internal.execution.steps.AssignMutableWorkspaceStep.execute(AssignMutableWorkspaceStep.java:31)	
	at org.gradle.internal.execution.steps.AssignMutableWorkspaceStep.execute(AssignMutableWorkspaceStep.java:22)	
	at org.gradle.internal.execution.steps.ChoosePipelineStep.execute(ChoosePipelineStep.java:40)	
	at org.gradle.internal.execution.steps.ChoosePipelineStep.execute(ChoosePipelineStep.java:23)	
	at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.lambda$execute$2(ExecuteWorkBuildOperationFiringStep.java:67)	
	at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.execute(ExecuteWorkBuildOperationFiringStep.java:67)	
	at org.gradle.internal.execution.steps.ExecuteWorkBuildOperationFiringStep.execute(ExecuteWorkBuildOperationFiringStep.java:39)	
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:46)	
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:34)	
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:44)	
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:31)	
	at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:64)	
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:132)	
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:121)	
	at org.gradle.api.internal.tasks.execution.ProblemsTaskPathTrackingTaskExecuter.execute(ProblemsTaskPathTrackingTaskExecuter.java:41)	
	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)	
	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)	
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)	
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:74)	
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)	
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)	
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)	
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)	
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)	
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)	
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)	
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)	
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)	
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)	
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)	
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)	
	at org.gradle.execution.plan.DefaultNodeExecutor.executeLocalTaskNode(DefaultNodeExecutor.java:55)	
	at org.gradle.execution.plan.DefaultNodeExecutor.execute(DefaultNodeExecutor.java:34)	
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:355)	
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:343)	
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.lambda$execute$0(DefaultTaskExecutionGraph.java:339)	
	at org.gradle.internal.operations.CurrentBuildOperationRef.with(CurrentBuildOperationRef.java:84)	
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:339)	
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:328)	
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:459)	
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:376)	
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)	
	at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
m
You can always add the dependency explicitely:
Copy code
tasks.withType(AbstractPublishToMaven).configureEach {
  it.dependsOn(tasks.named("signPluginMavenPublication")
}
Or something like this, rest of the owl not included ^^
Copy code
tasks.withType(AbstractPublishToMaven::class.java).configureEach {
  try {
    it.dependsOn(tasks.named("signPluginMavenPublication")
  } catch(_: Exception) {}
}
Probably worth catching the exception if the task doesn't exist
o
That was one of my myriad attempts to solve it. I even had to use
afterEvaluate
as the task was not even there.
m
Yea, it's not fun
Move to nmcp πŸ˜› . There might be the same problem but I would feel obligated to fix it πŸ™ƒ
o
I would instantly, but
Nmcp does not create publications or apply the
maven-publish
plugin. This must be done using other means.
I have no idea about how to draw the owl.
m
πŸ˜„
Yea, that's a pretty big owl
And there's nothing in the vanniktech issues?
o
There is an older one, but the OP got away by manually adding the task dependency and then closed it. After that, no one seemed to care.
o
Thanks a lot. I'll try that one!
Seems to work for me. At least I can reach the "invalid-token" error
Probably you only need the first part
o
I'll try to find out. I'm just wondering what happened that this comes up now and did not with the release before. It seems that not that much has changed.
m
It depends the timing of how Gradle schedules your tasks
I'm not sure the order is specified
o
So it was pure luck before. πŸ‘»
m
Yea
o
Would it hurt if I use both parts?
m
I don't think so
You waste a few nanoseconds πŸ˜„
o
So then let's go for it. I wonder how many "new release" pings people get with that mess.
m
Do you have to create a release to test it out?
I usually create the tag manually
And then the CI runs on the tag
You can create the release after the fact, once the tag is built and uploaded to maven central
o
Yes, maybe I should change my CI configuration. This is not going to be the last time shit hits the fan.
m
After some back and forth, I landed on a scheme where the version is always
-SNAPSHOT
and when the CI has a special env variable that drops it when doing a release. I kind of like it because it means only one commit to bump a version.
o
I'll look into that. Get some food first, then work on it. Thanks a ton! But I remember that exchange with (Aurimas?) that
-SNAPSHOT
has the disadvantage of also changing the caching. There is always some footgun waiting to fire...
πŸ˜„ 1
m
Never a dull moment!
Bon appetit πŸ˜‹
o
Merci! ❀️
That was it, the publishing job failed in the end but only because
Deployment validation timed out after 900s. Last known state: PUBLISHING
Again, thank you so much! It's a shame for Gradle to be violating their own rules in their own foundational plugin and then leave this unfixed since 2023. And I'm changing to tags as a publication trigger, that's way better given the state of affairs.
πŸš€ 1
kodee loving 1
plus one 1
m
> Deployment validation timed out after 900s. Last known state: PUBLISHING
This is fine πŸ™‚ πŸ˜„
o
The interesting thing is: The vanniktech docs mention a timeout of 60 minutes (and the code looks like that from what I could scan in the browser), but Google AI claims 15 minutes. And magically, the latter is correct. πŸ™ƒ
m
Interesting ^^
There are usually 3 timeouts: β€’ The upload one β€’ The validation one β€’ The publishing one
So probably some confusion in there
I've never seen the publication fail once it reaches the PUBLISHING state
o
That's what I have now in `gradle.properties`:
Copy code
SONATYPE_CLOSE_TIMEOUT_SECONDS=3600
And the publication was fine. Takes at least 10 minutes, often more.
m
"CLOSE" is the old vocabulary. It's weird if they kept the same name for the new API
There's no "staging repo" to "close" in the new API
So maybe it maps to one of the three timeouts above
Or maybe it's not doing anything, not sure
o
Yeah, I didn't want to invest more time, so I'm just trying and we'll see what happens with the next publication. The timeout can irritate but not more. The publication will proceed anyway. So all good! πŸ™‚
πŸ™Œ 1
While we're at it: Is there something you'd be missing in TestBalloon?
m
I don't think so but I'd still have to try it out in a large scale projet
o
What would you expect to be different at scale?
m
There are always corner cases in larger projects
I can't really tell you what, which is the point
Some things you (or at least I) can't really anticipate
This is why it's so good to have a large app to test your libs with
o
So I guess that's larger in the sense of "more variation". Tons of modules doing the same thing is probably not that interesting.
m
Yea, more variation, different environments, windows machines, different use cases, uber fat Gradle classpaths, etc...
βœ”οΈ 1
o
And yes, I'd probably give the same kind of "it depends" answer. We can't know what we don't know.
But it's interesting. More and more folks even inside JetBrains seem to like it. And it feels like the project gets some active support.
testballoon 1
m
Saw that in the AMA, congrats!
o
Same with Roboelectric. One maintainer likes TestBalloon, so maybe less work for me.
I have moved your fix to
build-logic/src/main/kotlin/BuildLogicPublishingBasePlugin.kt
, in order to apply it to KMP modules as well, not just JVM modules. Does that make sense?
m
Yup!
πŸ‘ 1