mise v2026.11.0(Published 2026-11-03T15:32:56Z,约北京时间 11 月 3 日 23:32)给任务加了 lock。多个终端或 agent 同时跑任务时,名字相同的锁会串行,谁先拿到谁先跑。本机从 2026.10.25 linux-x64 (2026-10-31) 升到 2026.11.0 linux-x64 (2026-11-03) 后,在最小 Spring Boot 3.4.5 工程里给 itest 加了 lock = "spring-boot-shared-fixture":第二路 mise run itest 先报 waiting,拿到锁后再起 Boot 测 /hello;--lock-timeout 2s 等不着就退出 1。

官方 Release 标题把这件事放在第一句:Task locks for shared resources。字符串锁名在整台机器上共享;lock = true 则按仓库(含其 worktree)共享。锁在依赖、skip_if、sources 和缓存检查之后、第一条命令之前才抢,被跳过的任务不会干等。嵌套的 mise run 继承父任务已持有的锁,不会自己把自己卡死。实现是 OS 文件锁(Linux 上是 flock),持有进程退出或被杀都会放掉。和 2026.10.25 的 tasks CLI / watch --once、2026.10.24 容器 daemon、2026.10.19 默认 generate 锁文件 一样,先把二进制踩准再谈行为。

self-update 仍可能卡在「最低发布年龄 24h」。这次直接装官方 linux-x64 包:

curl -fsSL -o mise.tar.gz \
  https://github.com/jdx/mise/releases/download/v2026.11.0/mise-v2026.11.0-linux-x64.tar.gz
tar -xzf mise.tar.gz
install -m 755 mise/bin/mise ~/.local/bin/mise
mise --version
# 2026.11.0 linux-x64 (2026-11-03)

演示工程仍是手写最小 Boot:pom.xml 父工程 spring-boot-starter-parent 3.4.5,DemoApplication 暴露 GET /hello 返回 HELLO-BOOT。测试类 SharedFixtureIT 用 RANDOM_PORT 起上下文,往 target/shared-fixture.lockhold 写一行 marker,睡 4 秒,再断言 /hello 仍是 HELLO-BOOT,并确认文件内容还是自己那一行。这是故意独占一份共享 fixture 的姿势,和官方举例里的「共享测试库」同一类冲突面。

根目录 mise.toml:

[tools]
java = "21"

[tasks.itest]
description = "Spring Boot IT holding shared fixture"
run = "mvn -q -Dtest=SharedFixtureIT test"
lock = "spring-boot-shared-fixture"

mise trust 之后,mise tasks info itest 会多出一行 Lock;--dry-run 只声明锁、不会真正占用:

Task: itest
Description: Spring Boot IT holding shared fixture
Source: /path/to/project/mise.toml
Lock: spring-boot-shared-fixture

Run:
  mvn -q -Dtest=SharedFixtureIT test
$ mise run --dry-run itest
[itest] lock: spring-boot-shared-fixture (not taken: dry run)
[itest] $ mvn -q -Dtest=SharedFixtureIT test

单路先跑通。日志里能看到 Boot 3.4.5 拉起、随机端口上的 /hello 返回 HELLO-BOOT,退出码 0。

主线是两路并发。终端 A 先 mise run itest,约 1.2 秒后终端 B 再跑同一条。B 先等到锁,A 跑完后才真正进 Maven:

# 终端 A
[itest] $ mvn -q -Dtest=SharedFixtureIT test
# ... Spring Boot 3.4.5 / SharedFixtureIT ...
# Tomcat started on port 33679 (http)
# /hello -> HELLO-BOOT
# 退出码 0

# 终端 B(约晚 1.2s 启动)
[itest] waiting for lock spring-boot-shared-fixture, held by itest in /path/to/project (pid 1525735, for 1.4s)
[itest] got lock spring-boot-shared-fixture after 7.5s
[itest] $ mvn -q -Dtest=SharedFixtureIT test
# ... 另一路 SharedFixtureIT,Tomcat started on port 37171 ...
# /hello -> HELLO-BOOT
# 退出码 0

两路都是 0。B 在拿到锁之前不会起第二份 Surefire,共享 fixture 文件也不会被并行截断改写。

等太久可以失败。另起一个持有同名锁的 sleep 任务后:

$ mise run --lock-timeout 2s itest
[itest] waiting for lock spring-boot-shared-fixture, held by hold in /path/to/project (pid 1526772, for 0.5s)
[itest] ERROR task itest: timed out after 2.0s waiting for lock spring-boot-shared-fixture, held by hold in /path/to/project (pid 1526772, for 3.0s)
[itest] ERROR task failed
# 退出码 1

超时文案会点出谁正握着锁。task.lock_timeout 设置和命令行 --lock-timeout 等价,单位写法可用 30s / 5m。

对 Spring Boot 日常最直接的咬合点:IT 或本地联调如果必须独占一份共享库、固定端口、或一份会被截断写入的 fixture,把锁名写进 mise.toml,多终端和 coding agent 就不会叠在同一资源上。同版本还有 opt-in 的 npm provenance、dotfile depends、mise bootstrap --update、skills 默认目录改到 .agents/skills,以及 --locked 要求 checksum 等 breaking;本次主线只实测 task lock。

参考:https://github.com/jdx/mise/releases/tag/v2026.11.0

— 感谢阅读 —
广告

一起交流

分享你的思考,让讨论更进一步。