1 | <?php |
||
2 | namespace Deployer; |
||
3 | |||
4 | use Deployer\Exception\Exception; |
||
5 | use Deployer\Support\Csv; |
||
6 | |||
7 | /** |
||
8 | * Name of folder in releases. |
||
9 | */ |
||
10 | set('release_name', function () { |
||
11 | $list = get('releases_list'); |
||
12 | |||
13 | // Filter out anything that does not look like a release. |
||
14 | $list = array_filter($list, function ($release) { |
||
15 | return preg_match('/^[\d\.]+$/', $release); |
||
16 | }); |
||
17 | 4 | ||
18 | $nextReleaseNumber = 1; |
||
19 | if (count($list) > 0) { |
||
20 | $nextReleaseNumber = (int)max($list) + 1; |
||
21 | 3 | } |
|
22 | 4 | ||
23 | return (string)$nextReleaseNumber; |
||
24 | 4 | }); |
|
25 | 4 | ||
26 | 3 | /** |
|
27 | * Return list of releases on host. |
||
28 | */ |
||
29 | 4 | set('releases_list', function () { |
|
30 | 8 | cd('{{deploy_path}}'); |
|
31 | |||
32 | // If there is no releases return empty list. |
||
33 | if (!test('[ -d releases ] && [ "$(ls -A releases)" ]')) { |
||
34 | return []; |
||
35 | } |
||
36 | 6 | ||
37 | // Will list only dirs in releases. |
||
38 | $list = explode("\n", run('cd releases && ls -t -1 -d */')); |
||
39 | 6 | ||
40 | 1 | // Prepare list. |
|
41 | $list = array_map(function ($release) { |
||
42 | return basename(rtrim(trim($release), '/')); |
||
43 | }, $list); |
||
44 | 5 | ||
45 | $releases = []; // Releases list. |
||
46 | |||
47 | // Collect releases based on .dep/releases info. |
||
48 | 5 | // Other will be ignored. |
|
49 | 5 | ||
50 | if (test('[ -f .dep/releases ]')) { |
||
51 | 5 | $keepReleases = get('keep_releases'); |
|
52 | if ($keepReleases === -1) { |
||
53 | $csv = run('cat .dep/releases'); |
||
54 | } else { |
||
55 | // Instead of `tail -n` call here can be `cat` call, |
||
56 | 5 | // but on hosts with a lot of deploys (more 1k) it |
|
57 | 5 | // will output a really big list of previous releases. |
|
58 | 5 | // It spoils appearance of output log, to make it pretty, |
|
59 | // we limit it to `n*2 + 5` lines from end of file (15 lines). |
||
60 | // Always read as many lines as there are release directories. |
||
61 | $csv = run("tail -n " . max(count($releases), ($keepReleases * 2 + 5)) . " .dep/releases"); |
||
62 | } |
||
63 | |||
64 | $metainfo = Csv::parse($csv); |
||
65 | |||
66 | for ($i = count($metainfo) - 1; $i >= 0; --$i) { |
||
67 | 5 | if (is_array($metainfo[$i]) && count($metainfo[$i]) >= 2) { |
|
68 | list(, $release) = $metainfo[$i]; |
||
69 | $index = array_search($release, $list, true); |
||
70 | 5 | if ($index !== false) { |
|
71 | $releases[] = $release; |
||
72 | 5 | unset($list[$index]); |
|
73 | 5 | } |
|
74 | 5 | } |
|
75 | 5 | } |
|
76 | 5 | } |
|
77 | 5 | ||
78 | 5 | return $releases; |
|
79 | }); |
||
80 | |||
81 | /** |
||
82 | * Return release path. |
||
83 | */ |
||
84 | 5 | set('release_path', function () { |
|
85 | 8 | $releaseExists = test('[ -h {{deploy_path}}/release ]'); |
|
86 | if ($releaseExists) { |
||
87 | $link = run("readlink {{deploy_path}}/release"); |
||
88 | return substr($link, 0, 1) === '/' ? $link : get('deploy_path') . '/' . $link; |
||
89 | } else { |
||
90 | throw new Exception(parse('The "release_path" ({{deploy_path}}/release) does not exist.')); |
||
91 | 4 | } |
|
92 | 4 | }); |
|
93 | 4 | ||
94 | 4 | ||
95 | desc('Prepare release. Clean up unfinished releases and prepare next release'); |
||
96 | task('deploy:release', function () { |
||
97 | cd('{{deploy_path}}'); |
||
98 | 8 | ||
99 | // Clean up if there is unfinished release |
||
100 | $previousReleaseExist = test('[ -h release ]'); |
||
101 | 8 | ||
102 | if ($previousReleaseExist) { |
||
103 | 4 | run('rm -rf "$(readlink release)"'); // Delete release |
|
104 | run('rm release'); // Delete symlink |
||
105 | } |
||
106 | 4 | ||
107 | // We need to get releases_list at same point as release_name, |
||
108 | 4 | // as standard release_name's implementation depends on it and, |
|
109 | // if user overrides it, we need to get releases_list manually. |
||
110 | $releasesList = get('releases_list'); |
||
111 | $releaseName = get('release_name'); |
||
112 | |||
113 | // Fix collisions |
||
114 | $i = 0; |
||
115 | while (test("[ -d {{deploy_path}}/releases/$releaseName ]")) { |
||
116 | 4 | $releaseName .= '.' . ++$i; |
|
117 | 4 | set('release_name', $releaseName); |
|
118 | } |
||
119 | |||
120 | 4 | $releasePath = parse("{{deploy_path}}/releases/{{release_name}}"); |
|
121 | 4 | ||
122 | // Metainfo. |
||
123 | $date = run('date +"%Y%m%d%H%M%S"'); |
||
124 | |||
125 | // Save metainfo about release |
||
126 | 4 | run("echo '$date,{{release_name}}' >> .dep/releases"); |
|
127 | |||
128 | // Make new release |
||
129 | 4 | run("mkdir -p $releasePath"); |
|
130 | run("{{bin/symlink}} $releasePath {{deploy_path}}/release"); |
||
131 | |||
132 | 4 | // Add to releases list |
|
133 | array_unshift($releasesList, $releaseName); |
||
134 | set('releases_list', $releasesList); |
||
135 | 4 | ||
136 | 4 | // Set previous_release |
|
137 | if (isset($releasesList[1])) { |
||
138 | set('previous_release', "{{deploy_path}}/releases/{$releasesList[1]}"); |
||
139 | 4 | } |
|
140 | }); |
||
141 |