A build scheduled while another one ran was queued, and the promise handed to its caller never settled: onBuildFinished started the queued build and dropped its result. A one-click deploy registered during another app's build therefore stayed at "Registering" for good, although the build ran. Pass the result to the queued promise instead.
be5d55d allowed a leading number in app names. A one-click deploy with
more than one service creates a project named after the app, so with the
old project rule such a name failed at "Creating project".
Fixes#2505
A one-click deploy with more than one service checked each app name only
when it registered that app. A later name that was too long or already
taken failed after the project and the earlier apps were created, and
those stayed behind. Check every name before the first step instead, and
say the length limit in the error.
Fixes#2504
Backup tar files currently use a filename that only encodes a
timestamp and the leader's IP, e.g.
caprover-backup-2026_04_10-19_30_00-1744312200000-ip-1_2_3_4.tar
When you run several CapRover instances behind a NAT or with
similar IPs, that filename is not enough to tell the backups apart
after downloading them.
This appends the swarm leader's hostname to the existing filename:
caprover-backup-...-ip-1_2_3_4-host-captain-prod.tar
The hostname is sanitized to a portable charset ([A-Za-z0-9._-]) so
it is safe in filesystems and HTTP Content-Disposition headers, and
the segment is omitted entirely when the leader has no hostname, so
existing single-node setups see no change beyond an additional
suffix when one is available.
The sanitization step is exposed as a small static helper
(`BackupManager.sanitizeHostnameForFilename`) so it can be unit
tested in isolation. Top-level cleanup hooks in the existing test
file are now gated on `process.env.CI`, matching how the
integration tests in the same file are gated, so the new pure
helper tests can run on a developer workstation.
Closes#1257