Release Date: Unreleased
4.8.0 release of CodeIgniter4
- TBD
- The static
Boot::initializeConsole()method no longer handles the display of the console header. This is now handled withinConsole::run(). If you have overriddenBoot::initializeConsole(), you should remove any code related to displaying the console header, as this is now the responsibility of theConsoleclass. - Commands: The
-hoption toroutescommand which was mapped previously to the--sort-by-handleroption is now removed. Use--sort-by-handlerinstead to sort the routes by handler when running theroutescommand. - Commands: The
filter:checkcommand now requires the HTTP method argument to be uppercase (e.g.,spark filter:check GET /instead ofspark filter:check get /). - Commands: Several built-in commands have been migrated from
BaseCommandto the modernAbstractCommandstyle. Applications that extend a built-in command to override behaviour may need to re-implement against the modern API (configure()+execute()and the#[Command]attribute) once the class it extends is migrated, or, preferably, compose instead of extending. Invocations on the command line are unaffected. - Commands: The success and error messages from
debugbar:clear,cache:clear, andcache:infonow include the affected path or cache driver/handler so the user can see which resource was acted on (or rejected). Scripts asserting on the prior literal text will need to be updated. - Commands: Declining the
key:generateoverwrite prompt interactively now returnsEXIT_SUCCESSinstead ofEXIT_ERROR. Output messages were also reworded; CI/automation that branches on the exit code or greps the previous wording will need updating. - Commands: The
migrate:rollbackcommand no longer accepts the undocumented-g(database group) option. It never had any effect, sinceMigrationRunner::regress()ignores the group, and the modern command pipeline now rejects unknown options. Remove-gfrom anymigrate:rollbackinvocation. - Commands: The
logs:clearcommand now returnsEXIT_SUCCESS(previouslyEXIT_ERROR) when the user declines the interactive confirmation prompt, since user-initiated cancellation is not a failure. Output messages have also been reworded to distinguish cancellation (interactiven) from abort (non-interactive without--force), and the resolved log directory path is now included in the prompt, success, and failure messages. - Database: The Postgre driver's
$db->error()['code']previously always returned''. It now returns the 5-character SQLSTATE string for query and transaction failures (e.g.,'42P01'), or'08006'for connection-level failures. Code that relied on$db->error()['code'] === ''will need updating. - Filters: HTTP method matching for method-based filters is now case-sensitive. The keys in
Config\Filters::$methodsmust exactly match the request method (e.g.,GET,POST). Lowercase method names (e.g.,post) will no longer match. - Testing: Tests using the
FeatureTestTraitmust now use uppercase HTTP method names when performing a request when using thecall()method directly (e.g.,$this->call('GET', '/path')instead of$this->call('get', '/path')). Additionally, setting method-based routes usingwithRoutes()must also use uppercase method names (e.g.,$this->withRoutes([['GET', 'home', 'Home::index']])).
NOTE: If you've implemented your own classes that implement these interfaces from scratch, you will need to update your implementations to include the new methods or method changes to ensure compatibility.
- Cache:
CodeIgniter\Cache\CacheInterface::remember()now accepts a TTL callable. Custom implementations ofCacheInterfacemust update the$ttlparameter type frominttocallable|int. - Database:
CodeIgniter\Database\ConnectionInterfacenow requires theafterCommit(),afterRollback(),inTransaction(), andtransaction()methods. - Logging:
CodeIgniter\Log\Handlers\HandlerInterface::handle()now requires a third parameterarray $context = []. Any custom log handler that overrideshandle()- whether implementingHandlerInterfacedirectly or extending a built-in handler class - must add the parameter to itshandle()method signature. - Security: The
SecurityInterface'sverify()method now has a native return type ofstatic. - Validation:
CodeIgniter\Validation\ValidationInterfacenow requires thegetValidatedInput()method, which returns aCodeIgniter\Validation\ValidatedInputinstance.
- CLI: The
Console::run()method now accepts an optionalarray $tokensparameter. This allows you to pass an array of command tokens directly to the console runner, which is useful for testing or programmatically running commands. If not provided, it will default to using the global$argv. - CodeIgniter: The deprecated parameters in methods have been removed:
CodeIgniter\CodeIgniter::handleRequest()no longer accepts the deprecated$cacheConfigand$returnResponseparameters.$cacheConfigis no longer used and is now hard deprecated. A deprecation notice will be triggered if this is passed to the method.$returnResponseis now removed since already deprecated and unused.- The updated method signature is now
handleRequest(?RouteCollectionInterface $routes, ?Cache $cacheConfig = null).
CodeIgniter\CodeIgniter::gatherOutput()no longer accepts the deprecated$cacheConfigparameter. As this is the first parameter, custom uses of this method will need to be updated to remove the parameter.
- Config:
CodeIgniter\Config\Services::request()no longer accepts any parameter. - Database: The following methods have had their signatures updated to remove deprecated parameters:
CodeIgniter\Database\Forge::_createTable()no longer accepts the deprecated$ifNotExistsparameter. The method signature is now_createTable(string $table, array $attributes).
- HTTP: The following properties have changed their scope (visibility):
CodeIgniter\HTTP\RequestTrait::$ipAddressis now private (previously protected).
- HTTP: The following methods have changed their scope (visibility):
CodeIgniter\HTTP\URI::setUri()is now private (previously public).CodeIgniter\HTTP\URI::refreshPath()is now protected (previously public).CodeIgniter\HTTP\SiteURI::refreshPath()is now protected (previously public).
- Autoloader: Removed the following deprecated methods:
CodeIgniter\Autoloader\Autoloader::sanitizeFileName()CodeIgniter\Autoloader\Autoloader::discoverComposerNamespaces()
- Bootstrap: The deprecated system/bootstrap.php file has been removed.
- Cache: Removed the following deprecated methods and constant:
CodeIgniter\Cache\Handlers\BaseHandler::RESERVED_CHARACTERS(deprecated since v4.1.5)CodeIgniter\Cache\Handlers\FileHandler::writeFile()(deprecated since v4.6.0)CodeIgniter\Cache\Handlers\FileHandler::deleteFile()(deprecated since v4.6.0)CodeIgniter\Cache\Handlers\FileHandler::getDirFileInfo()(deprecated since v4.6.0)CodeIgniter\Cache\Handlers\FileHandler::getFileInfo()(deprecated since v4.6.0)
- CLI: Removed the following properties and methods deprecated:
CodeIgniter\CLI\BaseCommand::getPad()CodeIgniter\CLI\CLI::$readline_supportCodeIgniter\CLI\CLI::$wait_msgCodeIgniter\CLI\CLI::isWindows()CodeIgniter\CLI\GeneratorTrait::execute()
- CodeIgniter: Removed the following properties and methods deprecated:
CodeIgniter\CodeIgniter::$cacheTTLCodeIgniter\CodeIgniter::$returnResponseCodeIgniter\CodeIgniter::initializeKint()CodeIgniter\CodeIgniter::detectEnvironment()CodeIgniter\CodeIgniter::bootstrapEnvironment()CodeIgniter\CodeIgniter::forceSecureAccess()CodeIgniter\CodeIgniter::displayCache()CodeIgniter\CodeIgniter::cache()CodeIgniter\CodeIgniter::cachePage()CodeIgniter\CodeIgniter::generateCacheName()CodeIgniter\CodeIgniter::displayPerformanceMetrics()CodeIgniter\CodeIgniter::determinePath()CodeIgniter\CodeIgniter::callExit()CodeIgniter\Test\MockCodeIgniter::callExit()
- Config: Removed the following property deprecated:
CodeIgniter\Config\BaseService::$services(deprecated since v4.5.0)
- Database: Removed the following properties and methods deprecated:
CodeIgniter\Database\BaseBuilder::setInsertBatch()CodeIgniter\Database\BaseBuilder::setUpdateBatch()CodeIgniter\Database\BaseBuilder::cleanClone()CodeIgniter\Database\BaseConnection::$strictOnCodeIgniter\Database\Forge::$createTableIfStrCodeIgniter\Database\Seeder::$fakerCodeIgniter\Database\Seeder::faker()CodeIgniter\Database\OCI8\Forge::$createTableIfStrCodeIgniter\Database\OCI8\Forge::getError()CodeIgniter\Database\SQLSRV\Forge::$createTableIfStr
- Debug: Removed the following deprecated properties and methods:
CodeIgniter\Debug\Toolbar\Collectors\BaseCollector::cleanPath()(deprecated since v4.2.0)CodeIgniter\Debug\Exceptions::$ob_level(deprecated since v4.4.0)CodeIgniter\Debug\Exceptions::$viewPath(deprecated since v4.4.0)CodeIgniter\Debug\Exceptions::determineView()(deprecated since v4.4.0)CodeIgniter\Debug\Exceptions::render()(deprecated since v4.4.0)CodeIgniter\Debug\Exceptions::collectVars()(deprecated since v4.4.0)CodeIgniter\Debug\Exceptions::maskSensitiveData()(deprecated since v4.4.0)CodeIgniter\Debug\Exceptions::maskData()(deprecated since v4.4.0)CodeIgniter\Debug\Exceptions::cleanPath()(deprecated since v4.2.0)CodeIgniter\Debug\Exceptions::describeMemory()(deprecated since v4.4.0)CodeIgniter\Debug\Exceptions::highlightFile()(deprecated since v4.4.0)
- Exceptions: Removed the following static constructors of
FrameworkExceptionand its child classes: CodeIgniter\Exceptions\DownloadException::forCannotSetCache()CodeIgniter\Exceptions\FrameworkException::forMissingExtension()CodeIgniter\Honeypot\Exceptions\HoneypotException::forNoHiddenValue()CodeIgniter\HTTP\Exceptions\HTTPException::forInvalidSameSiteSetting()CodeIgniter\Security\Exceptions\SecurityException::forInvalidSameSite()CodeIgniter\Session\Exceptions\SessionException::forInvalidSameSiteSetting()
- Exceptions: Removed the following static constructors of
- Filters: Removed the following properties and methods deprecated:
CodeIgniter\Filters\Filters::$arguments(deprecated since v4.6.0)CodeIgniter\Filters\Filters::$argumentsClass(deprecated since v4.6.0)CodeIgniter\Filters\Filters::getArguments()(deprecated since v4.6.0)
- HTTP: Removed the following properties and methods deprecated:
CodeIgniter\HTTP\Message::getHeaders()(deprecated since v4.0.5)CodeIgniter\HTTP\Message::getHeader()(deprecated since v4.0.5)CodeIgniter\HTTP\RequestTrait::getEnv()(deprecated since v4.4.4)CodeIgniter\HTTP\URI::$uriString(deprecated since v4.4.0)CodeIgniter\HTTP\URI::$baseURL(deprecated since v4.4.0)CodeIgniter\HTTP\URI::setBaseURL()(deprecated since v4.4.0)CodeIgniter\HTTP\URI::getBaseURL()(deprecated since v4.4.0)CodeIgniter\HTTP\URI::setScheme()(deprecated since v4.4.0)CodeIgniter\HTTP\SiteURI::$segments(deprecated since v4.4.0)CodeIgniter\HTTP\SiteURI::setBaseURL()(deprecated since v4.4.0)CodeIgniter\HTTP\SiteURI::setURI()(deprecated since v4.4.0)
- Security: Removed the following properties and methods deprecated:
CodeIgniter\Security\SecurityInterface::sanitizeFilename()(deprecated since v4.6.2)CodeIgniter\Security\Security::sanitizeFilename()(deprecated since v4.6.2)CodeIgniter\Security\Security::$csrfProtection(deprecated since v4.4.0)CodeIgniter\Security\Security::$tokenRandomize(deprecated since v4.4.0)CodeIgniter\Security\Security::$tokenName(deprecated since v4.4.0)CodeIgniter\Security\Security::$headerName(deprecated since v4.4.0)CodeIgniter\Security\Security::$expires(deprecated since v4.4.0)CodeIgniter\Security\Security::$regenerate(deprecated since v4.4.0)CodeIgniter\Security\Security::$redirect(deprecated since v4.4.0)CodeIgniter\Security\Security::$sameSite(deprecated since v4.4.0)
- Added a new attribute-based command style built on :php:class:`AbstractCommand <CodeIgniter\\CLI\\AbstractCommand>` and the
#[Command]attribute, withconfigure()/isAvailable()/initialize()/interact()/execute()hooks and typedArgument/Optiondefinitions. The legacyBaseCommandstyle continues to work. See :doc:`../cli/cli_modern_commands`. - Every modern command now ships with a
--no-interaction/-Nflag that skips theinteract()hook, plus publicisInteractive()/setInteractive()methods onAbstractCommand.isInteractive()also auto-detects piped or CI environments by probing STDIN for a TTY, and the state cascades to sub-commands invoked via$this->call(...). See :ref:`non-interactive-mode`. spark help <command>now shows the default value of each option that accepts a value (e.g.,[default: "file"]), the same way argument defaults are already displayed. Boolean flags and negatable toggles, which have no meaningful default to show, are unaffected.- You can now retrieve the last executed command in the console using the new
Console::getCommand()method. This is useful for logging, debugging, or any situation where you need to know which command was run. CLInow supports the--separator to mean that what follows are arguments, not options. This allows you to have arguments that start with-without them being treated as options. For example:spark my:command -- --myargwill pass--myargas an argument instead of an option.CLInow supports options with values specified using an equals sign (e.g.,--option=value) in addition to the existing space-separated syntax (e.g.,--option value). This provides more flexibility in how you can pass options to commands.CLInow supports parsing array options written multiple times (e.g.,--option=value1 --option=value2) into an array of values. This allows you to easily pass multiple values for the same option without needing to use a comma-separated string. When used withCLI::getOption(), an array option will return its last value (for example, in this case,value2). To retrieve all values for an array option, useCLI::getRawOption().- Likewise, the
command()function now also supports the above enhancements for command-line option parsing when using the function to run commands from code. - Added
make:requestgenerator command to scaffold :ref:`Form Request <form-requests>` classes. - Added
key:rotatecommand to demote the currentencryption.keytoencryption.previousKeysin .env and generate a new key. See :ref:`spark-key-rotate`. - Added
AbstractCommand::callSilently()to invoke another command with its output discarded, restoring the prior IO afterwards. See :ref:`modern-commands-call-silently`. - The
migrate,migrate:rollback,migrate:refresh, andmigrate:statuscommands now accept long option names (--namespace,--group,--batch,--force) alongside their existing short forms (-n,-g,-b,-f). - Added :php:class:`NullInputOutput <CodeIgniter\\CLI\\NullInputOutput>`, an :php:class:`InputOutput <CodeIgniter\\CLI\\InputOutput>` sink that discards all writes and returns an empty string from
input(). - The
spark routescommand now resolves the Before/After Filters columns for routes that use custom placeholders registered via$routes->addPlaceholder(). Sample URIs for custom placeholders are derived from the placeholder regex when possible, and can be overridden through the new$placeholderSamplesproperty inConfig\Routing. See :ref:`placeholder-samples-for-spark-routes`.
- Added
afterCommit()andafterRollback()transaction callbacks to database connections. These callbacks run after the outermost transaction commits or rolls back. See :ref:`transactions-transaction-callbacks`. - Added
inTransaction()to database connections to check whether the connection is inside an active CodeIgniter-managed transaction. See :ref:`transactions-checking-transaction-state`. - Prepared query execution failures now throw or store typed database exceptions such as
UniqueConstraintViolationExceptionandRetryableTransactionExceptionwhen applicable, matching normal query failures. - Added
RetryableTransactionExceptionfor driver-specific retryable transaction failures such as deadlocks and serialization failures. See :ref:`transactions-retryable-exceptions`. - Added the
transaction()method to database connections to run a callback inside a transaction, with optional retry attempts for retryable transaction failures and scopedtransExceptionandresetTransStatusoptions. See :ref:`transactions-closure`. - Added
trustServerCertificateoption toSQLSRVdatabase connections inConfig\Database. Set it totrueto trust the server certificate without CA validation when using encrypted connections.
- Added
exists()anddoesntExist()to Query Builder to check whether the current Query Builder query would return at least one row. See :ref:`query-builder-exists`. - Added
explain()to Query Builder to run execution-plan queries for the currentSELECTquery. See :ref:`query-builder-explain`. - Added
havingBetween(),orHavingBetween(),havingNotBetween(), andorHavingNotBetween()to Query Builder. See :ref:`query-builder-having-between`. - Added
whereBetween(),orWhereBetween(),whereNotBetween(), andorWhereNotBetween()to Query Builder. See :ref:`query-builder-where-between`. - Added
whereColumn()andorWhereColumn()to compare one column to another column while protecting identifiers by default. See :ref:`query-builder-where-column`. - Added
whereExists(),orWhereExists(),whereNotExists(), andorWhereNotExists()to addEXISTSandNOT EXISTSsubquery conditions. See :ref:`query-builder-where-exists`. - Added new
incrementMany()anddecrementMany()methods toCodeIgniter\Database\BaseBuilderfor performing bulk increment/decrement operations. - Added
lockForUpdate()to add pessimistic write locks toSELECTqueries on supported drivers. See :ref:`query-builder-lock-for-update`.
- Added new
timezoneoption to connection array inConfig\Databaseconfig. This ensures consistent timestamps between model operations and database functions likeNOW(). Supported drivers: MySQLi, Postgre, and OCI8. See :ref:`database-config-timezone` for details. - Added :php:class:`UniqueConstraintViolationException <CodeIgniter\\Database\\Exceptions\\UniqueConstraintViolationException>` which extends
DatabaseExceptionand is thrown on duplicate key (unique constraint) violations across all database drivers. See :ref:`database-unique-constraint-violation`. - Added
$db->getLastException()which returns the typed exception even whenDBDebugisfalse. See :ref:`database-get-last-exception`. - Added
DatabaseException::getDatabaseCode()returning the native driver error code asint|string;getCode()is constrained tointby PHP'sThrowableinterface and cannot carry string SQLSTATE codes.
- Added a Copy Details button to detailed HTML exception pages.
- Added new
chunkRows()method toCodeIgniter\Modelfor processing large datasets in smaller chunks. - Added new
firstOrInsert()method toCodeIgniter\Modelthat finds the first row matching the given attributes or inserts a new one. See :ref:`model-first-or-insert`.
- Cache: Added support for TTL callables in the
remember()method of cache handlers. This allows you to specify a callable that returns a TTL value, which can be useful for dynamic TTL. - Context: This new feature allows you to easily set and retrieve normal or hidden contextual data for the current request. See :ref:`Context <context>` for details.
- Images:: Added support for the AVIF file format.
- Locks: Added :doc:`Atomic Locks </libraries/locks>` for owner-aware, cross-process mutual exclusion backed by supported cache handlers: File, Redis, Predis, and Memcached. Memcached support has driver-specific release limitations because Memcached has no atomic compare-and-delete command.
- Logging: Log handlers now receive the full context array as a third argument to
handle(). When$logGlobalContextis enabled, the CI global context is available under theHandlerInterface::GLOBAL_CONTEXT_KEYkey. Built-in handlers append it to the log output; custom handlers can use it for structured logging. - Logging: Added :ref:`per-call context logging <logging-per-call-context>` with three new
Config\Loggeroptions ($logContext,$logContextTrace,$logContextUsedKeys). Per PSR-3, aThrowablein theexceptioncontext key is automatically normalized to a meaningful array. All options default tofalse. - Security: Added :ref:`Fetch Metadata based CSRF protection <csrf-fetch-metadata>` with token fallback.
- :doc:`Array Helper </helpers/array_helper>` gained five new dot-path functions: :php:func:`dot_array_has()`, :php:func:`dot_array_set()`, :php:func:`dot_array_unset()`, :php:func:`dot_array_only()`, and :php:func:`dot_array_except()`.
- :doc:`Array Helper </helpers/array_helper>` dot-path read operations now support
object rows (including
Entity) in :php:func:`dot_array_search()` and :php:func:`array_group_by()`.
- Added the
retryoption toCURLRequestfor retrying failed responses with configurable delays, retryable status codes, optional transient cURL error retries, andRetry-Aftersupport. See :ref:`curlrequest-request-options-retry`. - Added :ref:`Form Requests <form-requests>` - a new
FormRequestbase class that encapsulates validation rules, custom error messages, and authorization logic for a single HTTP request. - Added
IncomingRequest::input()to read GET, POST, JSON, and raw request data throughInputData. - Added
SSEResponseclass for streaming Server-Sent Events (SSE) over HTTP. See :ref:`server-sent-events`. Responseand its child classes no longer requireConfig\Apppassed to their constructors. Consequently,CURLRequest's$configparameter is unused and will be removed in a future release.Responsenow lazily loads theContentSecurityPolicy,Cookie, andCookieStoreclasses only when used, instead of instantiating them on every request in the constructor. Requests that do not touch CSP or cookies no longer incur the cost of loading these classes.CLIRequestnow supports the--separator to mean that what follows are arguments, not options. This allows you to have arguments that start with-without them being treated as options. For example:php index.php command -- --myargwill pass--myargas an argument instead of an option.CLIRequestnow supports options with values specified using an equals sign (e.g.,--option=value) in addition to the existing space-separated syntax (e.g.,--option value). This provides more flexibility in how you can pass options to CLI requests.- Added
$enableStyleNonceand$enableScriptNonceoptions toConfig\Appto automatically add nonces to control whether to add nonces to style-* and script-* directives in the Content Security Policy (CSP) header when CSP is enabled. See :ref:`csp-control-nonce-generation` for details. - Added
URI::withQueryVar()andURI::withQueryVars()to return a cloned URI with query variables added or replaced. URInow accepts an optional boolean second parameter in the constructor, defaulting tofalse, to control how the query string is parsed in instantiation. This is the behavior of->useRawQueryString()brought into the constructor for convenience. Previously, you need to call$uri->useRawQueryString(true)->setURI($uri)to get this behavior. Now you can simply donew URI($uri, true).CLIRequestnow supports parsing array options written multiple times (e.g.,--option=value1 --option=value2) into an array of values. This allows you to easily pass multiple values for the same option without needing to use a comma-separated string. When used withCLIRequest::getOption(), an array option will return its last value (for example, in this case,value2). To retrieve all values for an array option, useCLIRequest::getRawOption().
- Custom rule methods that set an error via the
&$errorreference parameter now support the{field},{param}, and{value}placeholders, consistent with language-file andsetRule()/setRules()error messages. - Added
Validation::getValidatedInput()to access validated data through aValidatedInputobject.
- Float and Double Casting: Added support for precision and rounding mode when casting to float or double in entities.
- Added
CodeIgniter\Input\InputDataandInputDataFactoryfor reusable typed input data objects. - Float and Double casting now throws
CastException::forInvalidFloatRoundingMode()if an rounding mode other than up, down, even or odd is provided. - Environment: Added
CodeIgniter\EnvironmentDetectorclass and correspondingenvironmentservice as a mockable wrapper around theENVIRONMENTconstant. Framework internals that previously comparedENVIRONMENTdirectly now go through this service, making environment-specific branches reachable in tests viaServices::injectMock(). See :ref:`environment-detector-service`. - Time: Added
Time::between(),Time::min(), andTime::max()comparison helpers. See :ref:`between <time-comparing-two-times-between>`, :ref:`min <time-comparing-two-times-min>`, and :ref:`max <time-comparing-two-times-max>`.
- Added new language key:
Cache.unsupportedLockStore(CacheException::forUnsupportedLockStore())
- Removed deprecated language keys tied to removed exception constructors:
Core.missingExtension(FrameworkException::forMissingExtension())HTTP.cannotSetCache(DownloadException::forCannotSetCache())HTTP.disallowedActionHTTP.invalidSameSiteSetting(HTTPException::forInvalidSameSiteSetting())Security.invalidSameSite(SecurityException::forInvalidSameSite())Session.invalidSameSiteSetting(SessionException::forInvalidSameSiteSetting())
- Config: Added the
mdkey forConfig\Mimes::$mimesfor Markdown files.
- CLI: The
CLI::parseCommandLine()method is now deprecated and will be removed in a future release. TheCLIclass now uses the newCommandLineParserclass to handle command-line argument parsing. - CLI: Returning a non-integer exit code from a command is now deprecated and will trigger a deprecation notice. Command methods should return an integer exit code (e.g.,
0for success, non-zero for errors) to ensure proper behavior across all platforms. - CLI:
Commands::run()is now deprecated in favor ofCommands::runLegacy()for legacyBaseCommandcommands, andCommands::runCommand()for modernAbstractCommandcommands. - CLI: The
$commandsparameter ofCommands::verifyCommand()and the$collectionparameter ofCommands::getCommandAlternatives()are no longer used. Passing a non-empty array for either will trigger a deprecation notice. - HTTP: The
CLIRequest::parseCommand()method is now deprecated and will be removed in a future release. TheCLIRequestclass now uses the newCommandLineParserclass to handle command-line argument parsing. - HTTP:
URI::setSilent()is now hard deprecated. This method was only previously marked as deprecated. It will now trigger a deprecation notice when used.
See the repo's CHANGELOG.md for a complete list of bugs fixed.