Mercurial > public > develkit
comparison scripts/release.groovy @ 216:b628d49d2891
DEP-11: change name of lock file for release branch. update release script to depend on new resolution and dependency locking
author | smith@nwoca.org |
---|---|
date | Wed, 29 Jun 2016 13:57:17 +0100 |
parents | 5bebb590b30e |
children | 49a220a1bde0 |
comparison
equal
deleted
inserted
replaced
215:5bebb590b30e | 216:b628d49d2891 |
---|---|
1 #!groovy | 1 #!groovy |
2 import groovy.transform.Sortable | |
3 import groovy.transform.ToString | |
4 import groovy.transform.TupleConstructor | |
2 | 5 |
3 /** | 6 /** |
4 This script implements the SSDT branching strategy based on hg flow. | 7 This script implements the SSDT branching strategy based on hg flow |
5 | 8 and dependency resolution locking. |
6 The intention is to reduce drudgery of creating release branches. The | 9 |
7 script tries to do the right thing based on standard SSDT project structures, | 10 The intention is to automate of creation of correctly configured release branches. |
8 but it is the user's responsibility to ensure it's correct. | 11 The script tries to do the right thing based on standard SSDT project structures, |
9 | 12 but it is the user's responsibility to ensure it's correct. |
10 The script does NOT "hg push --new-branch". That step is left for you | 13 |
14 The script does NOT "hg push --new-branch". That step is left for you | |
11 if the branch was created correctly. | 15 if the branch was created correctly. |
12 | 16 |
13 */ | 17 */ |
14 def project = new Properties() | 18 |
15 | 19 def branch = new BranchInfo() |
16 if (new File('gradle.properties').exists() ) { | 20 |
17 project.load(new File('gradle.properties').newInputStream()) | 21 println "Project:\n" |
18 } | 22 |
19 | 23 println "\trepo\t${("hg path".execute().text.split('=') ?: ['', ''])[1].trim()}" |
20 println "\nCurrent project:" | 24 println "\tbranch\t$branch" |
21 println "\tversion: " + project.version ?: "Unknown" | 25 println "\tversion\t$branch.version" |
22 println "-" * 20 | 26 |
23 | 27 println "-" * 40 |
24 if (args.size() < 2) { | 28 println "" |
29 | |
30 if (args.size() < 1) { | |
25 println """ | 31 println """ |
26 usage: release.groovy {releaseVersion} {nextVersion}\n | 32 usage: release.groovy {releaseVersion}\n |
27 e.g: release.groovy 1.6.0 1.7.0 (SNAPSHOT will be added automatically) | 33 e.g: release.groovy 1.6.0 |
28 | 34 |
29 If release ends in ".0", then will create 'release' stream, otherwise 'hotfix'. | 35 If release ends in ".0", then will create 'release' stream, otherwise 'hotfix'. |
30 For hotfix, current working branch should be the release branch. | 36 For hotfix, current working branch should be the release branch being hotfix'ed. |
31 | 37 |
32 Recommend that this script be executed in a fresh clone of the repo. | 38 Recommend that this script be executed in a fresh clone of the repo. |
33 | 39 |
34 ** Any uncommitted changes in the working directory will be committed with | 40 ** Any uncommitted changes in the working directory will be committed with |
35 the initial setting of the version. These are assumed to be | 41 the initial setting of the version. These are assumed to be |
38 | 44 |
39 System.exit(0) | 45 System.exit(0) |
40 } | 46 } |
41 | 47 |
42 def releaseVersion = args[0] | 48 def releaseVersion = args[0] |
43 def nextVersion = args[1] | 49 |
44 def hotfix = !releaseVersion.endsWith('.0') | 50 def hotfix = !releaseVersion.endsWith('.0') |
45 def stream = hotfix ? 'hotfix' : 'release' | 51 def stream = hotfix ? 'hotfix' : 'release' |
46 | 52 |
47 println "Creating ${hotfix ? 'hotfix' : 'release'} branch for $releaseVersion" | 53 println "Creating $stream branch for $releaseVersion" |
48 | 54 |
49 checkForSnapshots() | 55 checkForSnapshots() |
50 | 56 |
51 println "hg flow $stream start v${releaseVersion} --dry-run".execute().text | 57 println "hg flow $stream start v${releaseVersion} --dry-run".execute().text |
52 | 58 |
53 println "Continue? Enter = Yes, ^C to cancel" | 59 println "Continue? Enter = Yes, ^C to cancel" |
54 System.in.newReader().readLine() | 60 System.in.newReader().readLine() |
55 | 61 |
56 updateVersion(releaseVersion) | |
57 | |
58 println 'hg com -m "release: set release version"'.execute().text | |
59 | |
60 println "hg flow ${stream} start v${releaseVersion} --dirty".execute().text | 62 println "hg flow ${stream} start v${releaseVersion} --dirty".execute().text |
61 | 63 |
62 println "hg update default".execute().text | |
63 | |
64 updateVersion(nextVersion + ".SNAPSHOT") | |
65 | |
66 println 'hg com -m "release: set next release version"'.execute().text | |
67 | |
68 println "hg update ${stream}/v${releaseVersion}".execute().text | 64 println "hg update ${stream}/v${releaseVersion}".execute().text |
69 | 65 |
70 println "Done! Created $releaseVersion $stream branch." | 66 println "Starting dependency lock via gradle... (please wait)" |
71 println " Verify the branch created correctly then push the new branch." | 67 println "cmd /c gradlew.bat deleteGLobalLock generateGlobalLock saveGlobalLock".execute().text |
72 println " If any problems, then delete repo and clone fresh repository." | 68 |
73 | 69 println 'hg commit -A release.lock -m "lock dynamic dependencies for release"'.execute().text |
74 def updateVersion(String newVersion) { | 70 |
75 | 71 println "Created $releaseVersion $stream branch with locked dynamic dependencies." |
76 new File('gradle.properties').write( | 72 println " Verify the branch and release.lock file created correctly then push the new branch." |
77 new File('gradle.properties').text.replaceAll(/version=(.*)/,"version=$newVersion") | 73 println " If any problems, then delete repo and clone a fresh copy repository." |
78 ) | |
79 } | |
80 | 74 |
81 def checkForSnapshots() { | 75 def checkForSnapshots() { |
82 def lines = new File('gradle.properties').readLines() + new File('build.gradle').readLines() | 76 def lines = new File('gradle.properties').readLines() + new File('build.gradle').readLines() |
83 def snapshots = lines.collect { it.trim() }.findAll{ | 77 def snapshots = lines.collect { it.trim() }.findAll{ |
84 it.contains('.SNAPSHOT') && !it.startsWith('version=') || | 78 it.contains('.SNAPSHOT') && !it.startsWith('version=') || |
86 } | 80 } |
87 if (snapshots) { | 81 if (snapshots) { |
88 println "project contains SNAPSHOT dependencies: \n\t" + snapshots.join('\n\t') | 82 println "project contains SNAPSHOT dependencies: \n\t" + snapshots.join('\n\t') |
89 System.exit(1) | 83 System.exit(1) |
90 } | 84 } |
91 | 85 } |
92 } | 86 |
93 | 87 |
88 @TupleConstructor | |
89 @Sortable | |
90 class Version { | |
91 | |
92 Integer major = 0 | |
93 Integer minor = 0 | |
94 Integer patch = 0 | |
95 Boolean snapshot = true | |
96 | |
97 Version nextVersion() { | |
98 new Version(major, minor + 1, 0) | |
99 } | |
100 | |
101 String toString() { | |
102 "${major}.${minor}.${patch}${snapshot ? '.SNAPSHOT' : ''}" | |
103 } | |
104 | |
105 } | |
106 | |
107 | |
108 @ToString(includes=['name','shortName','buildVersion','imageId','deployName'],includeNames= true) | |
109 class BranchInfo { | |
110 def name | |
111 def stream = "none" | |
112 def buildNumber = "" | |
113 def changeset = "" | |
114 def version | |
115 | |
116 BranchInfo(name = null) { | |
117 this.name = name | |
118 if (!name) { | |
119 this.name = determineName() ?: '' | |
120 } | |
121 this.name = this.name.replace('@', '-') | |
122 determineStream() | |
123 buildNumber = System.getenv('bamboo_buildNumber') ?: "" | |
124 changeset = System.getenv('bamboo_planRepository_revision') ?: "" | |
125 } | |
126 | |
127 String getDefaultDependencyStatus() { | |
128 return isRelease() ? 'release' : 'integration' | |
129 } | |
130 | |
131 private boolean isRelease() { | |
132 return stream in ['release', 'hotfix'] | |
133 } | |
134 | |
135 def getShortName() { | |
136 def result = name.contains('/') ? name.split('/')[1] : name | |
137 } | |
138 | |
139 String getBuildVersion() { | |
140 def v = isRelease() ? shortName - "v": "" | |
141 return v | |
142 } | |
143 | |
144 def Version getVersion() { | |
145 if (!version) { | |
146 if (isRelease()) { | |
147 version = new Version(*getBuildVersion().split('\\.')*.toInteger(), false) | |
148 } else { | |
149 version = findSnapshotVersion() | |
150 } | |
151 } | |
152 return version | |
153 } | |
154 | |
155 def getImageId() { | |
156 (buildVersion ?: shortName.take(25)) + (buildNumber ? "-${buildNumber}" : "-0") | |
157 } | |
158 | |
159 def getDeployName() { | |
160 (buildVersion ?: shortName.take(25)).toLowerCase().collectReplacements { | |
161 ('a'..'z').contains(it) || ('0'..'9').contains(it) || it == "-" ? null : '-' | |
162 } | |
163 } | |
164 | |
165 def getHash() { | |
166 generateMD5(name) | |
167 } | |
168 def generateMD5(String s) { | |
169 def digest = java.security.MessageDigest.getInstance("MD5") | |
170 digest.update(s.bytes); | |
171 new BigInteger(1, digest.digest()).toString(16).padLeft(32, '0') | |
172 } | |
173 | |
174 private findSnapshotVersion() { | |
175 def versions = "hg branches --closed".execute().text.split('\n').findAll { | |
176 it.startsWith( 'release') || it.startsWith( 'hotfix') | |
177 }.collect { | |
178 it.replaceAll('\\s+',' ').split(' ')[0].split('/')[1] - 'v' | |
179 }.collect { | |
180 new Version(*it.split('\\.')*.toInteger()) | |
181 }.sort { v1, v2 -> v2 <=> v1 } | |
182 | |
183 return versions ? versions.first().nextVersion() : new Version().nextVersion() | |
184 | |
185 } | |
186 | |
187 | |
188 def determineName() { | |
189 try { | |
190 def branch = "hg branch".execute().text.trim() | |
191 def rawParents = 'hg parents'.execute().text | |
192 def parent = rawParents.split('\n').find { it.startsWith("branch") }?.split(":")?.getAt(1)?.trim() | |
193 return parent ?: branch | |
194 } catch (e) { | |
195 ['.hg/branch', '../.hg/branch'].findResult { | |
196 new File(it).exists() ? new File(it).text : null | |
197 } | |
198 } | |
199 } | |
200 | |
201 void determineStream() { | |
202 def flowConfig = new File('.hgflow').exists() ? new File('.hgflow') : new File('../.hgflow') | |
203 if (flowConfig.exists()) { | |
204 def flows = new Properties() | |
205 flows.load(flowConfig.newReader()) | |
206 flows.stringPropertyNames().each { | |
207 if (!it.startsWith("[") && name.startsWith(flows.getProperty(it))) { | |
208 stream = it | |
209 } | |
210 } | |
211 } | |
212 } | |
213 | |
214 } |