diff --git a/contrib/tideways.php b/contrib/tideways.php
new file mode 100644
index 000000000..52194d5aa
--- /dev/null
+++ b/contrib/tideways.php
@@ -0,0 +1,139 @@
+ 'your-api-key',
+ 'version' => '',
+ 'environment' => 'production',
+ 'service' => 'web',
+ 'compare_after_minutes' => 90,
+]);
+
+ */
+
+namespace Deployer;
+
+use Deployer\Utility\Httpie;
+
+desc('Notifies Tideways of deployment');
+task('deploy:tideways', static function () {
+ $defaultConfig = [
+ 'version' => getReleaseGitRef(),
+ 'environment' => 'production',
+ 'service' => 'web',
+ 'compare_after_minutes' => 90,
+ 'project' => null,
+ 'description' => null,
+ 'tideways_server' => 'https://app.tideways.io',
+ ];
+
+ $config = array_merge($defaultConfig, (array)get('tideways'));
+ array_walk(
+ $config,
+ static function (&$value) use ($config) {
+ if (is_callable($value)) {
+ $value = $value($config);
+ }
+ },
+ );
+
+ if (!isset($config['api_key']) || empty($config['api_key'])) {
+ writeln('Skipping Tideways release creation: api_key not set');
+
+ return;
+ }
+
+ if (!isset($config['version']) || empty($config['version'])) {
+ throw new \RuntimeException(
+ << 'your-api-key',
+ 'version' => '1.0.0',
+ ]
+ );
+ EXAMPLE,
+ );
+ }
+
+ $payload = [
+ 'apiKey' => $config['api_key'],
+ 'name' => $config['version'],
+ 'type' => 'release',
+ 'environment' => $config['environment'],
+ 'service' => $config['service'],
+ 'compareAfterMinutes' => (int)$config['compare_after_minutes'],
+ ];
+
+ // Add description if provided or generate from project
+ if (!empty($config['description'])) {
+ $payload['description'] = $config['description'];
+ } elseif (!empty($config['project'])) {
+ $payload['description'] = "Release {$config['version']} for project {$config['project']}";
+ }
+
+ $eventsApiUrl = $config['tideways_server'] . '/api/events';
+
+ try {
+ Httpie::post($eventsApiUrl)
+ ->setopt(CURLOPT_TIMEOUT, 10)
+ ->header('Content-Type', 'application/json')
+ ->body(json_encode($payload))
+ ->send();
+
+ writeln(
+ sprintf(
+ 'Tideways: Release %s ' .
+ 'for environment %s and service %s created successfully.',
+ $config['version'],
+ $config['environment'],
+ $config['service'],
+ ),
+ );
+ } catch (\Throwable $e) {
+ writeln('Failed to create Tideways release: ' . $e->getMessage() . '');
+ throw $e;
+ }
+});
+
+function getReleaseGitRef(): \Closure
+{
+ return static function ($config = []): string {
+ if (get('update_code_strategy') === 'archive') {
+ if (isset($config['git_version_command'])) {
+ cd('{{deploy_path}}/.dep/repo');
+
+ return trim(run($config['git_version_command']));
+ }
+
+ return run('cat {{current_path}}/REVISION');
+ }
+
+ cd('{{release_path}}');
+
+ if (isset($config['git_version_command'])) {
+ return trim(run($config['git_version_command']));
+ }
+
+ return trim(run('git log -n 1 --format="%h"'));
+ };
+}
+
+after('deploy:success', 'deploy:tideways');
diff --git a/docs/contrib/README.md b/docs/contrib/README.md
index c75174196..94830a2b0 100644
--- a/docs/contrib/README.md
+++ b/docs/contrib/README.md
@@ -29,6 +29,7 @@
* [Slack Recipe](/docs/contrib/slack.md)
* [Supervisord-monitor Recipe](/docs/contrib/supervisord-monitor.md)
* [Telegram Recipe](/docs/contrib/telegram.md)
+* [Tideways Recipe](/docs/contrib/tideways.md)
* [Webpack_encore Recipe](/docs/contrib/webpack_encore.md)
* [Workplace Recipe](/docs/contrib/workplace.md)
* [Yammer Recipe](/docs/contrib/yammer.md)
diff --git a/docs/contrib/tideways.md b/docs/contrib/tideways.md
new file mode 100644
index 000000000..f1b86f782
--- /dev/null
+++ b/docs/contrib/tideways.md
@@ -0,0 +1,43 @@
+
+
+
+
+# Tideways Recipe
+
+```php
+require 'contrib/tideways.php';
+```
+
+[Source](/contrib/tideways.php)
+
+
+
+### Configuration options
+- **api_key** *(required)*: Tideways API key for authentication.
+- **version** *(required)*: A version identifier for this release. Can be a version number, a commit hash etc. (Default is set to git log -n 1 --format="%h".)
+- **environment** *(optional)*: The environment you're deploying to. Defaults to 'production'.
+- **service** *(optional)*: The service name for the release. Defaults to 'web'.
+- **compare_after_minutes** *(optional)*: Time in minutes to compare performance before/after release. Defaults to 90.
+- **project** *(optional)*: Project name/path for the description field.
+- **description** *(optional)*: Custom description for the release.
+- **tideways_server** *(optional)*: Tideways server URL. Defaults to 'https://app.tideways.io'.
+- **git_version_command** *(optional)*: The command that retrieves the git version information. Defaults to 'git log -n 1 --format="%h"'.
+```php
+deploy.php
+set('tideways', [
+ 'api_key' => 'your-api-key',
+ 'version' => '',
+ 'environment' => 'production',
+ 'service' => 'web',
+ 'compare_after_minutes' => 90,
+]);
+```
+### Suggested Usage
+Since you should only notify Tideways of a successful deployment, the deploy:tideways task should be executed right at the end.
+```php
+deploy.php
+after('deploy:success', 'deploy:tideways');
+```
+
+
+