Commit Graph
18328 Commits
Author SHA1 Message Date
kenji yoshida ef2b58a358 [2.x] deps: Update scala-xml and scala-parser-combinators (#9777) 2026-09-16 12:54:11 -04:00
Albert MeltzerandClaude Opus 5 37b3cc59b1 [2.x] ProjectMatrix: validate axes against autoScalaLibrary (#9771)
The flag and the axes both say whether a row is built for Scala, and
where they disagree the flag wins: a row given versions and
autoScalaLibrary = false is built for none of them, and the versions
are dropped. Nothing said so.

ProjectMatrix: validate axes against autoScalaLibrary

---------

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
2026-09-16 12:52:48 -04:00
Anatolii Kmetiuk a20dfa9495 [2.x] fix: Name taskValue in its compile-time diagnostic (#9779)
Problem: taskValue outside a task or setting macro reports an error naming value.

Solution: use a dedicated taskValue marker, preserve macro processing, and add diagnostic and behavioral regression tests.
2026-09-16 12:48:11 -04:00
eugene yokota 31779bf38d [2.x] fix: Update to Gigahorse 0.9.6 for preauth (#9775)
**Problem**
With HTTP/2, Apache HttpClient can begin the authenticated replay while the rejected stream is still consuming the same repeatable file producer.
The overlapping consumption can send corrupted artifacts, according to mkurz.

**Solution**
This hopefully fixes the issue by updateing to Gigahorse 0.9.6, which fixes the preauth support.
2026-09-16 12:16:10 -04:00
Albert MeltzerandClaude Opus 5 7563b7790b [2.x] Allow adding rows and configuring them separately, and through any method (#9765)
* [2.x] test: Pin what a platform axis alone does

**Problem**
`jsPlatform` enables the Scala.js plugin; the axis does not. A row
built by `customRow` with `VirtualAxis.js` is a Scala.js row by every
name it carries and a JVM row by what runs.

**Solution**
Assert what such a row reports as its platform.

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* [2.x] feat: Enable JS/Native plugins if the axis is used

Only jsPlatform and nativePlatform enabled the plugin their platform
needs, so using customRow directly would skip it.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

* [2.x] feat: Configure the rows a matrix builds

A build could reach every row with configure, or one row with the call
that made it, and nothing in between, so settings for the rows of one
platform travelled with every call that creates them. Now
configureRows takes a function of a row's axes and answers with what
to apply, and a row is given it as it is built, so a row declared
after the call is covered too.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
2026-09-16 21:53:11 +09:00
Anatolii Kmetiuk 152c66a34c [2.x] fix: Warn on output declarations in uncached tasks (#9770) 2026-09-15 23:30:59 -04:00
Albert Meltzer 3460089ec7 [2.x] fix: Do not duplicate platform axes on a row (#9757)
* test: Pin the axes of a row that carries no Scala version

`jvmPlatform(autoScalaLibrary = false)` passes `VirtualAxis.jvm` to
`customRow`, which appends it again, so the row holds the platform axis
twice and its generated directories are named `scalajvm-jvm` and
`javajvm-jvm`. Nothing covered that path.

* fix: Keep one platform axis on a row that names its own

`jvmPlatform(autoScalaLibrary = false)` hands `customRow` the platform
axis, and `customRow` appended a second one, so the row's generated
directories were named `scalajvm-jvm` and `javajvm-jvm` and a cell
whose sources sat in the usual places compiled nothing. Now the axis is
appended only when the caller named no platform.
2026-09-15 14:10:22 +09:00
kenji yoshida 70e0a550a7 Update ModuleIDExtra.exclude deprecated annotation (#9758) 2026-09-15 10:21:21 +09:00
kenji yoshida 21fe27f62c [2.x] ci: Fix warnings (#9768) 2026-09-14 19:28:07 -04:00
kenji yoshida 0fc907cf85 [2.x] ci: Update mima setting (#9760) 2026-09-14 17:21:38 -04:00
eugene yokota e0666adb7b [2.x] Use sbt 2.1.0-M1 (#9767) 2026-09-14 17:20:36 -04:00
Stas Shevchenko c623288a9a [2.x] fix: Fixes Windows runner handling of sbt bsp (#9766)
* fix: forward bsp argument to sbt on Windows
* test: exercise sbt script bsp command directly
2026-09-14 14:34:04 -04:00
eugene yokota 14148450e2 [2.x] Update sbtn to 2.1.0-M1 (#9755) v2.1.0-M1 2026-09-13 03:25:25 -04:00
eugene yokota 801280dc61 [2.x] fix: clean task (#9752)
**Problem**
The clean task no longer works as intended on sbt 2.x due to the disk cache.

**Solution**
This implements an in-memory state of invalidation for subproject and
configuration axes. So clean task would mark subprojects to be
invalidated regardless of the disk cache state.
The invalidation state would be lifted once any cached task executes,
so it's not technically same as sbt 1.x, but the UX should be similar.
2026-09-12 23:18:11 -04:00
Stas Shevchenko 4eba898c9e [2.x] fix: let one client at a time restart the server (#9708)
Two invocations that both find different -D options could interleave, the second
one connecting to the server the first had just started and shutting that down
mid-build. The restart now holds the connection file and reads it again once it
has it, so a replacement that already carries the right options is left alone.
2026-09-12 18:56:21 -04:00
eugene yokota 7d1878bd1f [2.x] fix: Fixes test setup/cleanup interleaving (#9727)
**Problem**
Tags are enforced per task node.
This means that a chain like setup-test-cleanup
would release the tags midway, and allow interleaving
executions even for exclusive tests.

**Solution**
This implements a special Span tag, which lets us
keep the tags across the task chains.
Since this requires the flatMapped tasks to not carry their
own tags to prevent a deadlock, the feature needs to be opt-in /
internal implementation.
2026-09-12 17:42:54 -04:00
Alexander 81cb1cdd19 [2.x] fix: Fix sbt runner script not starting on openSUSE (#9753)
**Problem**
sbt fails to start on openSUSE, since OSTYPE=linux, not linux-gnu.
The startup script tries to add .ZIP extension, and fails to untar native client.

**Solution**
Modified startup script only check that OSTYPE starts with linux, instead of linux-gnu.
2026-09-12 15:09:58 -04:00
Stas Shevchenko ea673bf06f [2.x] fix: include compileOrder and pipelining in compile cache key (#9749)
compileOrder and usePipelining were missing from CompileInputs2, so two builds differing only in those settings shared one cache entry and replayed each other's results. Adds both to the key, with a unit test on the hash and a scripted test that fails without the change.
2026-09-12 02:20:06 -04:00
Albert Meltzer 9532b51190 ci: Upgrade MiMa to 1.2.0 (#9750)
* build: Upgrade MiMa to 1.2.0
* build: Filter every sbt.internal problem at once
2026-09-11 19:28:12 -04:00
eugene yokotaandkenji yoshida ae0898fb4b Revert "[2.x] Delete bootDirectory in cleanFull (#9060)" (#9747)
This reverts commit 7408fc93c7.

Co-authored-by: kenji yoshida <[email protected]>
2026-09-11 14:52:15 -04:00
eugene yokota 8e5e01e6ba [2.x] Update release note, more (#9742) 2026-09-11 00:24:42 -04:00
Stas Shevchenko e1ccd99927 [2.x] feat: Add LoggerContext.removeAppender for single appender removal (#9740)
LogExchange.unbindLoggerAppenders calls clearAppenders, which drops and closes every appender on the logger. So if you bind an appender to the global logger and then unbind it, sbt's own console and backing appenders go with it and nothing prints for the rest of the session.

LoggerContext now has removeAppender(loggerName, appender), which removes that one instance by identity and closes it. LogExchange gets an unbindLoggerAppenders(name, appenders) overload on top of it, so unbinding mirrors binding. The existing single-arg version behaves as before, it just says in the scaladoc what it does now.
2026-09-10 23:57:48 -04:00
Jozef Koval 4b88cdd959 [2.x] fix: Diagnose task-local dependency references (#9728)
Task-local filters used in sources.all(filter).value currently produce generic Scala macro scope errors. Report one actionable diagnostic at the offending reference, explaining how to move the definition outside the task or use Def.taskDyn.
2026-09-10 23:50:35 -04:00
eugene yokota 1b7c8b87f2 [2.x] docs: Update release notes (#9741) 2026-09-10 16:41:48 -04:00
eugene yokota fe56804cd7 Merge pull request #9737 from eed3si9n/wip/style-scalafmt
[2.x] refactor: Update scalafmt.conf
2026-09-10 15:47:49 -04:00
Eugene Yokota 040d4bd200 ci: Ignore Scalafmt commit 2026-09-10 15:18:28 -04:00
Eugene Yokota f9688c1464 Apply Scalafmt format (Scala 3 syntax) 2026-09-10 14:16:27 -04:00
Eugene Yokota ace09d39e3 [2.x] Update scalafmt.conf 2026-09-10 13:36:15 -04:00
eugene yokota 9f2d783d97 [2.x] doc: Update the style guide (#9736) 2026-09-10 13:13:11 -04:00
Jozef Koval 2626c40c82 [2.x] fix: Resolve the project axis to the current project in runAggregated (#9722)
**Problem**
When a key does not say which project it belongs to, Extracted.runAggregated filled in the global scope instead of the current project.

**Solution**
Fill in the current project instead, the way runInputTask always has. The only difference between the two scopes is the project, so a key that already names a project behaves exactly as before.
2026-09-10 12:58:39 -04:00
Albert MeltzerandClaude Opus 5 dbeeb199aa [2.x] fix: Stop a displaced server (#9713)
**Problem**
If a client cannot reach the server, it deletes the portfile. Then it
starts a second server. The first server is displaced: its socket path
now belongs to the second server.

A displaced server keeps running. A dropIfIdle notification cannot
reach it, because the proc file it registered names the socket that
the second server now owns.

**Solution**
The portfile holds the serverId of whichever server wrote it. Watch
that file, and exit when the id is not this server's. Leave the
portfile to the server that owns it.

---------

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
2026-09-10 12:55:11 -04:00
Stas Shevchenko ce7bb28f05 [2.x] fix: Fixes cross command parsing (#9726)
+cleanFull failed with Not a valid key: Full. The cross command re-parses its argument with the key parser, and clean is an accepting prefix, so the rest was taken as task args. Args now have to be preceded by whitespace.
2026-09-10 12:54:21 -04:00
eugene yokota 5966b2b35d Merge pull request #9733 from eed3si9n/wip/bump-zinc
[2.x] Update Zinc to 2.1.0-M2
2026-09-10 12:22:37 -04:00
Eugene Yokota 746fdcc077 test: Make the test more robust 2026-09-10 11:49:51 -04:00
eugene yokota 2238e405b8 [2.x] fix: Fail the build on bad resource generator (#9735)
**Problem**
Currently bad resources are silently dropped.

**Solution**
1. Fix a bad resource generator in the build.
2. Fail the build when bad resources are found.
2026-09-10 01:22:34 -04:00
Eugene Yokota c0f788a460 [2.x] Update Zinc to 2.1.0-M2 2026-09-10 01:15:24 -04:00
Anatolii Kmetiuk 56ee42565c [2.x] fix: Remove Ivy API usage from build publishing plugins (#9723) 2026-09-10 10:30:39 +09:00
eugene yokota 40bfe14274 [2.x] IO 1.13.2 (#9731) 2026-09-09 15:48:32 -04:00
Albert Meltzer f6033270e5 [2.x] fix: Add a row when customRow gets no versions (#9717)
The overload that takes axisValues and settings passes an empty
scalaVersions into the fold that builds the rows, so a call with
autoScalaLibrary = true returns the matrix unchanged. The assertion
records that, so the fix can move it.

Now the call adds one row from the axes it was given, so a build can name a partial or a full version instead.
2026-09-09 15:48:12 -04:00
eugene yokota 83224cd051 [2.x] Update release notes (#9730) 2026-09-09 15:29:27 -04:00
eugene yokota 01198f5407 [2.x] feat: workerMaxInstances + testTopology (#9665)
* [2.x] feat: testForkedWorker setting

**Problem**
A major bottleneck of the default setting is that concurrentRestriction
allows exactly one forked test in flight at a time,
and partly due to the restriction all test suites from a subproject runs
within the forked process.

**Solution**
This adds a new setting called testForkedWorker, which lets the build users
tune the number of concurrent worker process in flight.
I've set the default to CPU count / 3.
Within a single worker, the default parallelism is reduced to 2.

The default test grouping now splits the test suites into
testForkedWorker count.

* Use Global scope for overall worker count

Subproject scoping can be used for single vs split

* Adds math.max(..., 1)

* Avoid running setup/cleanup on an empty selection

* Fix the tag application order

* Rename key to workerMaxInstances

* Implement TestTopology

* fix: Fixes exclusive test

Note due to the limitation of the tag system, setup-clean/cleanup
may overlap.

* Check that workerMaxInstances >= 1
2026-09-09 14:13:13 +09:00
eugene yokota 91e32af8a0 Merge pull request #9691 from kitbellew/server-keeps-accepting
[2.x] fix: Keep accepting after a client fails
2026-09-08 14:01:23 -04:00
Albert MeltzerandClaude Opus 5 db4d22cc18 [2.x] fix: Keep accepting after a client fails
**Problem**
The accept loop did not catch an exception from onIncomingSocket, so
its thread ended. Nothing closed the server socket, so the path stayed
bound: the server took no further client, and the process kept running.
The socket of the client that failed stayed open too.

**Solution**
Log that client, close its socket, and take the next one. An exception
from accept itself keeps the handling it had, so a socket that is
really broken still ends the loop.

The callback now takes a holder rather than the socket, and calls
AtomicCloseable.release to keep it. The loop closes whatever the
callback left behind.

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
2026-09-08 10:14:23 -07:00
Albert MeltzerandClaude Opus 5 b2544cfa02 [2.x] test: Pin a client the server cannot serve
**Problem**
Nothing covers what the accept loop does when it cannot serve a client.
The next commit changes it.

**Solution**
Assert what the server does now. An exception from onIncomingSocket
ends the accept loop, and the server serves no client after that.

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
2026-09-08 06:49:28 -07:00
Stas Shevchenkoandeugene yokota f389e676cd fix: restart the sbt server when -D options change (#9685)
* fix: restart the sbt server when -D options change

* fix: don't restart on completions, wait for the socket

* fix: only trust -D options recorded for this build

* fix: confirm the server left before reporting it gone

* Update protocol/src/main/contraband/portfile.contra

Co-authored-by: eugene yokota <[email protected]>

* fix: record the server -D options as a list

* fix: record the -D options without their values

The connection file keeps the name of each option and a salted digest of it
rather than the option itself, and the comparison follows the JVM in taking the
last definition of a name. A client that is not allowed to restart the server
says which options it cannot pick up instead of staying quiet about them.

* fix: compare the -D options given before a command

A trailing -D option used to switch the whole comparison off, which dropped the
options written before it, and a shutdown request that never reached the server
waited the full timeout before saying so.

* fix: leave a server no client started alone

The connection file says whether its recorded options are the whole story, so a
server an editor keeps is warned about instead of shut down, while one the client
started with no options is still replaced. A restart that cannot reach the server
warns and carries on rather than failing the invocation.

* build: filter NetworkClient clinit in MiMa

---------

Co-authored-by: eugene yokota <[email protected]>
2026-09-08 11:46:36 +09:00
Albert MeltzerandClaude Opus 5 40e8ebf917 [2.x] refactor: Name the expressions that repeat (#9712)
CommandExchange asked twice whether an exec came from the closing
channel, and cancelled an exec in two places. Each has a name now, as
does the read of shuttingDown and the Try whose failure is ignored.

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
2026-09-07 20:33:53 -04:00
Stas Shevchenko 976d7f3765 [2.x] fix: keep macro subprojects off the pipelined classpath (#9719) 2026-09-07 20:32:53 -04:00
Christian Harrington 8c62e437fb [2.x] fix: virtualize semanticdbTargetRoot in the compile cache key (#9711)
Problem
-------
SemanticdbPlugin.compileIncAndCacheSemanticdbTargetRootTask is a cached task
that reads semanticdbTargetRoot as a bare File, so its absolute path is hashed
into the action cache key:

  ((true,${OUT}/.../classes,${OUT}/.../classes.sbtdir.zip),/tmp/repro/target/out/.../meta)

Every other component of that key is virtualized. This one names one checkout
on one machine, so the entry can never be served to a second checkout, to a
colleague, or to CI. A monorepo we measured had 118 such keys, none of them
reachable across machines.

Fixes #9709

Solution
--------
Read the target root through semanticdbTargetRootVF, following the convention
sourcesVF and resourcesVF already set: an uncached task holding the virtualized
form of a File-typed key, so that a cached task hashes ${OUT}/.../meta rather
than the path behind it. A cached helper would key on the same bare File and
reintroduce the problem one level up.

The scripted test asserts the property the bug breaks: relocating
rootOutputDirectory must leave every key alone, so the second compile is a pure
cache hit. It pins Compile / semanticdbOptions, because -semanticdb-target
carries an absolute path into scalacOptions as well, which is a separate issue
and would otherwise mask this one.

Generated-by: Claude Opus 5
2026-09-07 20:30:45 -04:00
Stas Shevchenko d4507648a5 fix: keep every output line the runner test reads (#9687) 2026-09-04 16:56:35 +09:00
Albert MeltzerandClaude Opus 5 9a858d15d1 [2.x] fix: Write the server's files by rename (#9689)
* [2.x] test: Pin how a server writes its files

**Problem**
Nothing covers how the server writes the portfile and the token file.
The next commit changes both.

**Solution**
Assert what the server does now. The tests read the token file only.
The server rewrites it on every authentication, so a test can read it
while the server writes. The server writes the portfile once, as it
starts.

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* [2.x] fix: Write the portfile and zip by rename

**Problem**
A client reads the portfile as soon as it appears. The server wrote it
with IO.write, in place, so a client could read part of one and fail to
parse it. ActionCache staged and renamed its zip by hand.

**Solution**
The portfile calls IO.writeFileAtomically, and the cache zip calls
IO.copyFile, which stages and renames on its own. The token file needs
its staging file kept to the owner, which neither can do yet, so it
still writes its own way.

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

* [2.x] sbt-io: upgrade to v1.13.1

* [2.x] fix: Write the token file by rename

**Problem**
writeTokenfile would first remove the existing token file, and then go
through a non-atomic sequence of steps to write a new one. If a client
attempts to read the file during that process, it is likely to find it
either missing or half-written.

**Solution**
Use newly released IO.writeFileAtomically with ownerOnly flag set.

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
2026-09-04 12:07:13 +09:00