-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathrelease-yamlscript
executable file
·314 lines (221 loc) · 8.32 KB
/
release-yamlscript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
#!/usr/bin/env ys-0
# This script is for automating the YAMLScript release process as much as
# possible. The release process involves many steps, and might need to be
# restarted at a certain step.
#
# Usage: release-yamlscript <old-version> <new-version> [<starting-step>]
#
# The following environment variables can be used to control the script:
#
# * YS_RELEASE_DRYRUN=1 - Don't actually run any commands, just show them
# * YS_RELEASE_VERBOSE=1 - Show more information about what's happening
# * YS_RELEASE_LAST_STEP=n - The last step to run (default is 10)
version-file =: '.version.ys'
steps =: 11
bindings =::
- java
- clojure
- go
- julia
- nodejs
- perl
- perl-alien
- python
- raku
- ruby
- rust
# verbose =: B(ENV.YS_RELEASE_VERBOSE)
verbose =: true
dryrun =: boolean(ENV.YS_RELEASE_DRYRUN)
last-step =: (ENV.YS_RELEASE_LAST_STEP || steps):N
#------------------------------------------------------------------------------
# Run each step in succession, starting at the specified step number if given
# and ending at the specified last step number if given.
#------------------------------------------------------------------------------
defn main(old-version=0 new-version=0 start=1):
ctx =:
if dryrun || ENV.RELEASE_ID:
then: -{}
else:
check-args: old-version new-version start
say: "\nReleasing YAMLScript v$new-version at $(ctx.date-time)\n"
if ENV.RELEASE_ID:
step-9: ctx
each i (1 .. steps):
when (i >= start) && (i <= last-step):
resolve(symbol("step-$i")): ctx
say: ''
#------------------------------------------------------------------------------
# Change the .version.ys version bump script to use the new version string.
#------------------------------------------------------------------------------
defn step-1(ctx):
o: 'Step 1) Do nothing, Step no longer needed'
#------------------------------------------------------------------------------
# Change all current version strings in dozens of files to the new version.
#------------------------------------------------------------------------------
defn step-2(ctx):
o: "Step 2) Run 'make bump'"
run:: make bump
when verbose:
run:: git -P diff
#------------------------------------------------------------------------------
# Collect the git log subject lines since the last release, reverse them and
# then create a new Changes file entry and add it to the top of the Changes
# file.
#
# Open the file in an editor to review the entry and update if needed.
#------------------------------------------------------------------------------
defn step-3(ctx):
o: "Step 3) Update the 'Changes' file"
when-not dryrun:
changes =:
make-changes-entry: ctx
spit 'release-changes.txt': changes
prompt: "Press Enter to edit the 'Changes' file."
editor =: ENV.EDITOR || 'vi'
run: "$editor release-changes.txt"
prompt: 'Press Enter to continue or Ctrl-C to abort.'
validate-yaml: slurp('release-changes.txt')
when verbose:
# Show git changes since last release:
run: "grep -F -B999 '$(ctx.old)' Changes"
#------------------------------------------------------------------------------
# Run 'make test' to ensure everything is working as expected.
#------------------------------------------------------------------------------
defn step-4(ctx):
o: "Step 4) Run 'make test'"
run:: make test
# Update Changes if tests pass:
when-not dryrun:
changes =: slurp('release-changes.txt')
file-prepend 'Changes': |
- version: $(ctx.new)
date: $(ctx.date-time)
changes:
$(changes:str/trimr)
validate-yaml: slurp('Changes')
changes =: changes.replace(/(?m)^ -/ '*')
spit 'release-changes.txt': changes
#------------------------------------------------------------------------------
# Some of the binding library directories have a change log file.
# Update them.
#------------------------------------------------------------------------------
defn step-5(ctx):
o: 'Step 5) Update the Change Log files for the binding modules'
when-not dryrun:
# A change log (YAML) entry for Perl:
perl-entry =: |
---
version: $(ctx.new)
date: $(ctx.date-time)
changes:
- libyamlscript $(ctx.new)
validate-yaml: perl-entry
file-prepend 'perl/Changes': perl-entry
when verbose:
run:: head perl/Changes
file-prepend 'perl-alien/Changes': perl-entry
when verbose:
run:: head perl-alien/Changes
# Change log entry for Ruby:
ruby-entry =: |+
## [$(ctx.new)] - $(ctx.date)
- libyamlscript $(ctx.new)
file-prepend 'ruby/ChangeLog.md': ruby-entry
when verbose:
run:: head ruby/ChangeLog.md
#------------------------------------------------------------------------------
# git commit the release changes we've made so far.
#------------------------------------------------------------------------------
defn step-6(ctx):
o: 'Step 6) Commit the release changes to git'
run: "git commit -a -m 'release: $(ctx.new)'"
#------------------------------------------------------------------------------
# git tag using the new version
#------------------------------------------------------------------------------
defn step-7(ctx):
o: 'Step 7) Add git tag for the new version'
run: "git tag $(ctx.new)"
#------------------------------------------------------------------------------
# git push commit and tag
#------------------------------------------------------------------------------
defn step-8(ctx):
o: 'Step 8) Push the git commit and tag'
run:: git push
run:: git push --tags
#------------------------------------------------------------------------------
# Call 'make release'
#------------------------------------------------------------------------------
defn step-9(ctx):
o: "Step 9) Run 'make release-assets'"
run:: make test-core test-ys
run:: make release-assets
run:: make install
when-not dryrun || ENV.RELEASE_ID:
shell {:out "release-id.txt"}: "grep '^Release id:' release-$(ctx.new).log"
run:: cat release-id.txt
#------------------------------------------------------------------------------
# For each of the many binding libraries, run 'make release'
#------------------------------------------------------------------------------
defn step-10(ctx):
o: "Step 10) Run 'make release' for each language binding library"
prompt: 'Press Enter when ready to continue.'
each dir bindings:
try:
run: "make -C $dir release"
catch Exception e:
if (dir == 'clojure') || (dir == 'java'):
warn: "Failed to release $dir. Continuing."
die: "Failed to release $dir. Exiting."
try:
run: "git tag -d v$(ctx.new)"
run: "git push origin :v$(ctx.new)"
catch Exception e:
run: 'git checkout -- perl perl-alien'
when verbose:
run:: git -P diff
#------------------------------------------------------------------------------
# Publish the website. A new release will change the content of some pages.
#------------------------------------------------------------------------------
defn step-11(ctx):
o: 'Step 11) Publish the yamlscript.org website'
run: 'make -C www realclean publish'
#------------------------------------------------------------------------------
# Helper functions:
#------------------------------------------------------------------------------
defn o(msg): say("\n$msg")
defn prompt(msg):
print: "$msg "
trim: read-line()
defn file-prepend(file text):
spit file:
str: text slurp(file)
defn make-changes-entry(ctx):
lines =:
sh("git log --oneline $(ctx.old)..HEAD")
.out:str/split-lines:reverse
str/join "\n":
map \(str/replace %1, /^\w+ /, ' - '): lines
defn validate-yaml(yaml):
when-not dryrun:
try:
yaml/load: yaml
catch Exception e:
die: "Invalid YAML: $e"
defn run(cmd):
say: "+ $cmd"
when-not dryrun:
shell: cmd
defn check-args(old new start):
when-not (string? old) && (re-matches /0\.\d+\.\d+/ old):
die: "Invalid old version '$old'"
when-not (string? new) && (re-matches /0\.\d+\.\d+/ new):
die: "Invalid new version '$new'"
when-not (number? start) && (start >= 1) && (start <= steps):
die: "Invalid starting step number '$start'"
# Return context mapping:
=>::
old:: old
new:: new
date:: sh('date +%Y-%m-%d').out:str/trim-newline
date-time:: sh('date').out:str/trim-newline