From 617226ca0176a3ca922b32f638f50f03b8dd81ef Mon Sep 17 00:00:00 2001 From: Caleb White Date: Mon, 10 Aug 2026 19:02:44 -0500 Subject: [PATCH] fix: fail missing snapshots in CI (#1842) Prevent snapshot assertions from silently creating missing snapshots during CI runs unless --update-snapshots is enabled. --- src/Mixins/Expectation.php | 6 ++++ src/Plugins/Snapshot.php | 45 +++++++++++++++++++++++++ src/Repositories/SnapshotRepository.php | 7 +++- 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/Mixins/Expectation.php b/src/Mixins/Expectation.php index 127f599e..762328e6 100644 --- a/src/Mixins/Expectation.php +++ b/src/Mixins/Expectation.php @@ -734,6 +734,12 @@ final class Expectation }; if (! $snapshots->has()) { + if (! Snapshot::shouldCreateMissingSnapshots()) { + $filename = $snapshots->filename(); + + Assert::fail($message === '' ? "Snapshot is missing at [$filename]. Run Pest with --update-snapshots to create it." : $message); + } + $filename = $snapshots->save($string); TestSuite::getInstance()->registerSnapshotChange("Snapshot created at [$filename]"); diff --git a/src/Plugins/Snapshot.php b/src/Plugins/Snapshot.php index 98ec275f..bd082100 100644 --- a/src/Plugins/Snapshot.php +++ b/src/Plugins/Snapshot.php @@ -16,6 +16,36 @@ final class Snapshot implements HandlesArguments public static bool $updateSnapshots = false; + /** + * @var list + */ + private const array CI_ENVIRONMENT_VARIABLES = [ + 'CI', + 'GITHUB_ACTIONS', + 'GITLAB_CI', + 'CIRCLECI', + 'TRAVIS', + 'APPVEYOR', + 'BITBUCKET_BUILD_NUMBER', + 'BUILDKITE', + 'TEAMCITY_VERSION', + 'JENKINS_URL', + 'SYSTEM_COLLECTIONURI', + 'CI_NAME', + 'TASKCLUSTER_ROOT_URL', + 'DRONE', + 'WERCKER', + 'NEVERCODE', + 'SEMAPHORE', + 'NETLIFY', + 'NOW_BUILDER', + ]; + + public static function shouldCreateMissingSnapshots(): bool + { + return self::$updateSnapshots || ! self::runningOnCI(); + } + /** * {@inheritDoc} */ @@ -119,4 +149,19 @@ final class Snapshot implements HandlesArguments return true; } + + private static function runningOnCI(): bool + { + if (Environment::name() === Environment::CI) { + return true; + } + + foreach (self::CI_ENVIRONMENT_VARIABLES as $environmentVariable) { + if (getenv($environmentVariable) !== false) { + return true; + } + } + + return false; + } } diff --git a/src/Repositories/SnapshotRepository.php b/src/Repositories/SnapshotRepository.php index ce3088ae..969ca6d6 100644 --- a/src/Repositories/SnapshotRepository.php +++ b/src/Repositories/SnapshotRepository.php @@ -56,7 +56,12 @@ final class SnapshotRepository file_put_contents($snapshotFilename, $snapshot); - return str_replace(dirname($this->testsPath).'/', '', $snapshotFilename); + return $this->filename(); + } + + public function filename(): string + { + return str_replace(dirname($this->testsPath).'/', '', $this->getSnapshotFilename()); } public function flush(): void