From 285f79c867cc759fe8a268c170868b5a61442cc2 Mon Sep 17 00:00:00 2001 From: turegjorup Date: Wed, 7 Oct 2026 11:12:39 +0200 Subject: [PATCH 1/3] fix: write .env.local in place so app:apikeys:add works on bind mounts --- src/Command/ApiKeysAddCommand.php | 17 +++++++++++------ tests/Command/ApiKeysAddCommandTest.php | 4 ++++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Command/ApiKeysAddCommand.php b/src/Command/ApiKeysAddCommand.php index 8016cff..e9f5766 100644 --- a/src/Command/ApiKeysAddCommand.php +++ b/src/Command/ApiKeysAddCommand.php @@ -137,7 +137,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int } $hasBackup = file_exists($envFile); - if ($hasBackup && !(chmod($tempFile, fileperms($envFile) & 0777) && copy($envFile, $backupFile))) { + if ($hasBackup && !copy($envFile, $backupFile)) { @unlink($tempFile); @unlink($backupFile); $io->error(sprintf('Failed to back up %s, the file is unchanged.', $envFile)); @@ -145,11 +145,16 @@ protected function execute(InputInterface $input, OutputInterface $output): int return Command::FAILURE; } - // Atomic replace, .env.local never goes missing. - if (!rename($tempFile, $envFile)) { - @unlink($tempFile); - @unlink($backupFile); - $io->error(sprintf('Failed to replace %s, the file is unchanged.', $envFile)); + // Write in place instead of rename(): on prod .env.local is a single-file + // bind mount, which rename() cannot replace (EBUSY). Keeps owner and mode too. + $replaced = @copy($tempFile, $envFile) && file_get_contents($envFile) === $contents; + unlink($tempFile); + + if (!$replaced) { + $restored = $hasBackup ? @copy($backupFile, $envFile) : @unlink($envFile); + $io->error($restored + ? sprintf('Failed to write %s, the change has been reverted.', $envFile) + : sprintf('Failed to write %s and could not restore it. The original is in %s.', $envFile, $backupFile)); return Command::FAILURE; } diff --git a/tests/Command/ApiKeysAddCommandTest.php b/tests/Command/ApiKeysAddCommandTest.php index d4137e2..cfee200 100644 --- a/tests/Command/ApiKeysAddCommandTest.php +++ b/tests/Command/ApiKeysAddCommandTest.php @@ -50,9 +50,13 @@ public function testReplacesMultiLineValueAndKeepsOtherLines(): void OTHER=value ENV); chmod($this->dir.'/.env.local', 0600); + // Same inode afterwards means .env.local was written in place, not renamed over, + // which is required when it is a single-file bind mount (prod). + $inode = fileinode($this->dir.'/.env.local'); self::assertSame(Command::SUCCESS, $this->runCommand("o'brien")->getStatusCode()); self::assertSame(0600, fileperms($this->dir.'/.env.local') & 0777); + self::assertSame($inode, fileinode($this->dir.'/.env.local')); self::assertFileDoesNotExist($this->dir.'/.env.local.backup'); self::assertFileDoesNotExist($this->dir.'/.env.local.temp'); From 7d55a30b8939de2322510beda4c33c9cd26e32d4 Mon Sep 17 00:00:00 2001 From: turegjorup Date: Wed, 7 Oct 2026 11:12:56 +0200 Subject: [PATCH 2/3] docs: update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3d19e2..d645e1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ See [keep a changelog] for information about writing changes to this log. ## [Unreleased] +- [PR-67](https://github.com/itk-dev/event-database-api/pull/67) + Fix `app:apikeys:add` failing when `.env.local` is a bind-mounted file + ## [1.2.4] - 2026-10-07 - [PR-64](https://github.com/itk-dev/event-database-api/pull/64) From 3ef6b335cc421e1b55c0332ce570e71d26af4a79 Mon Sep 17 00:00:00 2001 From: turegjorup Date: Wed, 7 Oct 2026 11:16:14 +0200 Subject: [PATCH 3/3] docs: changelog for 1.2.5 --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d645e1a..32106bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ See [keep a changelog] for information about writing changes to this log. ## [Unreleased] +## [1.2.5] - 2026-10-07 + - [PR-67](https://github.com/itk-dev/event-database-api/pull/67) Fix `app:apikeys:add` failing when `.env.local` is a bind-mounted file @@ -97,7 +99,8 @@ See [keep a changelog] for information about writing changes to this log. - Added multi-value filtering for Lactions and Organizations [keep a changelog]: https://keepachangelog.com/en/1.1.0/ -[Unreleased]: https://github.com/itk-dev/event-database-api/compare/1.2.4...HEAD +[Unreleased]: https://github.com/itk-dev/event-database-api/compare/1.2.5...HEAD +[1.2.5]: https://github.com/itk-dev/event-database-api/compare/1.2.4...1.2.5 [1.2.4]: https://github.com/itk-dev/event-database-api/compare/1.2.3...1.2.4 [1.2.3]: https://github.com/itk-dev/event-database-api/compare/1.2.2...1.2.3 [1.2.2]: https://github.com/itk-dev/event-database-api/compare/1.2.1...1.2.2