= 0; --$i) { $release = $releasesLog[$i]['release_name']; if (in_array($release, $ll, true)) { $releases[] = $release; } } return $releases; }); // Return release path. set('release_path', function () { $releaseExists = test('[ -h {{deploy_path}}/release ]'); if ($releaseExists) { $link = run("readlink {{deploy_path}}/release"); return substr($link, 0, 1) === '/' ? $link : get('deploy_path') . '/' . $link; } else { throw new Exception(parse('The "release_path" ({{deploy_path}}/release) does not exist.')); } }); // Current release revision. Usually a git hash. set('release_revision', function () { return run('cat {{release_path}}/REVISION'); }); // Return the release path during a deployment // but fallback to the current path otherwise. set('release_or_current_path', function () { $releaseExists = test('[ -h {{deploy_path}}/release ]'); return $releaseExists ? get('release_path') : get('current_path'); }); // Clean up unfinished releases and prepare next release desc('Prepares release'); task('deploy:release', function () { cd('{{deploy_path}}'); // Clean up if there is unfinished release. if (test('[ -h release ]')) { run('rm release'); // Delete symlink. } // We need to get releases_list at same point as release_name, // as standard release_name's implementation depends on it and, // if user overrides it, we need to get releases_list manually. $releasesList = get('releases_list'); $releaseName = get('release_name'); $releasePath = "releases/$releaseName"; // Check what there is no such release path. if (test("[ -d $releasePath ]")) { $freeReleaseName = '...'; // Check what $releaseName is integer. if (ctype_digit($releaseName)) { $freeReleaseName = intval($releaseName); // Find free release name. while (test("[ -d releases/$freeReleaseName ]")) { $freeReleaseName++; } } throw new Exception("Release name \"$releaseName\" already exists.\nRelease name can be overridden via:\n dep deploy -o release_name=$freeReleaseName"); } // Save release_name. if (is_numeric($releaseName) && is_integer(intval($releaseName))) { run("echo $releaseName > .dep/latest_release"); } // Metainfo. $timestamp = timestamp(); $metainfo = [ 'created_at' => $timestamp, 'release_name' => $releaseName, 'user' => get('user'), 'target' => get('target'), ]; // Save metainfo about release. $json = escapeshellarg(json_encode($metainfo)); run("echo $json >> .dep/releases_log"); // Make new release. run("mkdir -p $releasePath"); run("{{bin/symlink}} $releasePath {{deploy_path}}/release"); // Add to releases list. array_unshift($releasesList, $releaseName); set('releases_list', $releasesList); // Set previous_release. if (isset($releasesList[1])) { set('previous_release', "{{deploy_path}}/releases/{$releasesList[1]}"); } }); desc('Shows releases list'); /* * Example output: * ``` * +---------------------+------example.org ------------+--------+-----------+ * | Date (UTC) | Release | Author | Target | Commit | * +---------------------+-------------+----------------+--------+-----------+ * | 2021-11-06 20:51:45 | 1 | Anton Medvedev | HEAD | 34d24192e | * | 2021-11-06 21:00:50 | 2 (bad) | Anton Medvedev | HEAD | 392948a40 | * | 2021-11-06 23:19:20 | 3 | Anton Medvedev | HEAD | a4057a36c | * | 2021-11-06 23:24:30 | 4 (current) | Anton Medvedev | HEAD | s3wa45ca6 | * +---------------------+-------------+----------------+--------+-----------+ * ``` */ task('releases', function () { cd('{{deploy_path}}'); $releasesLog = get('releases_log'); $currentRelease = basename(run('readlink {{current_path}}')); $releasesList = get('releases_list'); $table = []; $tz = !empty(getenv('TIMEZONE')) ? getenv('TIMEZONE') : date_default_timezone_get(); foreach ($releasesLog as &$metainfo) { $date = \DateTime::createFromFormat(\DateTimeInterface::ISO8601, $metainfo['created_at']); $date->setTimezone(new \DateTimeZone($tz)); $status = $release = $metainfo['release_name']; if (in_array($release, $releasesList, true)) { if (test("[ -f releases/$release/BAD_RELEASE ]")) { $status = "$release (bad)"; } else if (test("[ -f releases/$release/DIRTY_RELEASE ]")) { $status = "$release (dirty)"; } else { $status = "$release"; } } if ($release === $currentRelease) { $status .= ' (current)'; } try { $revision = run("cat releases/$release/REVISION"); } catch (\Throwable $e) { $revision = 'unknown'; } $table[] = [ $date->format("Y-m-d H:i:s"), $status, $metainfo['user'], $metainfo['target'], $revision, ]; } (new Table(output())) ->setHeaderTitle(currentHost()->getAlias()) ->setHeaders(["Date ($tz)", 'Release', 'Author', 'Target', 'Commit']) ->setRows($table) ->render(); });