samus 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +173 -8
- data/bin/samus +5 -1
- data/commands/build/archive-git-full +2 -0
- data/commands/build/fs-sedfiles +1 -1
- data/commands/build/npm-task +3 -0
- data/commands/build/npm-task.help.md +7 -0
- data/commands/build/samus-build +3 -0
- data/commands/build/samus-build.help.md +9 -0
- data/commands/publish/samus-publish +3 -0
- data/commands/publish/samus-publish.help.md +7 -0
- data/lib/samus/builder.rb +11 -7
- data/lib/samus/command.rb +25 -13
- data/lib/samus/version.rb +1 -1
- data/samus.json +2 -2
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d0e11cb6836e13b5e668f722bd179d46b26ee3d
|
4
|
+
data.tar.gz: 33e0c0b7778b5e70b25425520f81ee268c02951e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ddd01675f4c353aae8adcd31466dc74bb15d9df3c02e9db9be84f37895dd5672f84c32489b442a55a0afc40c55b5a2e89c61a3f13f7bec0990ac0a9d9fcc6b8
|
7
|
+
data.tar.gz: 11d1f94c34594257b77689ec82a21127921f88382c1d0f91176b4fe19f9758c1e131748f5202eb464bc073bdd4e73f511bb8fb39a23e8d7906d4971ba7f5b966
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Samus
|
1
|
+
# Samus <a href="http://badge.fury.io/rb/samus"><img src="https://badge.fury.io/rb/samus@2x.png" alt="Gem Version" height="18"></a> [](https://codeclimate.com/github/lsegal/samus)
|
2
2
|
|
3
3
|
Samus helps you automate the release of Open Source Software. Samus works
|
4
4
|
through a manifest file to describe discrete steps that you typically perform
|
@@ -13,6 +13,14 @@ your code. That's right, Samus has a mechanism to share publishing credentials
|
|
13
13
|
in a fairly secure way, so you can reliably publish releases from almost any
|
14
14
|
machine.
|
15
15
|
|
16
|
+
## Installing
|
17
|
+
|
18
|
+
Samus is a RubyGem and requires Ruby 1.9.x+. Installing is as easy as typing:
|
19
|
+
|
20
|
+
```sh
|
21
|
+
$ gem install samus
|
22
|
+
```
|
23
|
+
|
16
24
|
## Usage
|
17
25
|
|
18
26
|
Samus is driven by a manifest file that describes the steps to perform when
|
@@ -22,9 +30,9 @@ can use it for both, it's your choice.
|
|
22
30
|
### Publishing
|
23
31
|
|
24
32
|
If you can handle building all of your assets on your own, you can use Samus
|
25
|
-
just to publish your code. Create a manifest file called manifest.json
|
26
|
-
put it in a directory with all of your assets. The
|
27
|
-
list of discrete actions like so (minus comments):
|
33
|
+
just to publish your code. Create a manifest file called `manifest.json` (it
|
34
|
+
must be named this way) and put it in a directory with all of your assets. The
|
35
|
+
manifest file is just a list of discrete actions like so (minus comments):
|
28
36
|
|
29
37
|
```js
|
30
38
|
{
|
@@ -204,10 +212,11 @@ The above command creates:
|
|
204
212
|
|
205
213
|
### Commands
|
206
214
|
|
207
|
-
Commands in Samus are just shell scripts
|
208
|
-
|
209
|
-
|
210
|
-
|
215
|
+
Commands in Samus are just shell scripts which execute from the workspace
|
216
|
+
or release directory (unless overridden by the build manifest). Samus passes
|
217
|
+
all argument values (the keys from the "arguments" section of the manifest) in
|
218
|
+
as environment variables with a prefixed underscore. For example, the
|
219
|
+
`rake-task` command is just:
|
211
220
|
|
212
221
|
```sh
|
213
222
|
#!/bin/sh
|
@@ -217,6 +226,58 @@ rake $_task
|
|
217
226
|
|
218
227
|
The `$_task` variable is the "task" argument from the manifest.
|
219
228
|
|
229
|
+
Note that commands must be executable (`chmod +x`) and have proper shebang
|
230
|
+
lines or they will not function.
|
231
|
+
|
232
|
+
#### Stages
|
233
|
+
|
234
|
+
Commands either live in the build/ or publish/ sub-directories under the
|
235
|
+
commands directory depending on whether they are for `samus build` or
|
236
|
+
`samus publish`. These are considered the respective "stages".
|
237
|
+
|
238
|
+
#### Special Variables
|
239
|
+
|
240
|
+
In addition to exposing arguments as underscored environment variables,
|
241
|
+
Samus also exposes a few special variables with double underscore prefixes:
|
242
|
+
|
243
|
+
* `__build_dir` - this variable refers to the temporary directory that the
|
244
|
+
release package is being built inside of. The files inside of this directory,
|
245
|
+
and *only* the files inside of this directory, will be built into the release
|
246
|
+
archive. If you write a build-time command that produces an output file which
|
247
|
+
is part of the release, you should make sure to move it into this directory.
|
248
|
+
* `__restore_file` - the restore file is a newline delimited file containing
|
249
|
+
branches and their original ref. All branches listed in this file will be
|
250
|
+
restored to the respective ref at the end of `samus build` regardless of
|
251
|
+
success status. If you make destructive modifications to existing branches
|
252
|
+
in the workspace repository, you should add the original ref for the branch
|
253
|
+
to this file.
|
254
|
+
* `__creds_*` - provides key, secret, and other values loaded from credentials.
|
255
|
+
See Credentials section for more information on how these are set.
|
256
|
+
|
257
|
+
#### Help Files
|
258
|
+
|
259
|
+
In order to integrate with `samus show-cmd <stage> <command>` syntax, your
|
260
|
+
command should include a file named `your-command.help.md` in the same directory
|
261
|
+
as the command script itself. These files are Markdown-formatted files and
|
262
|
+
should follow the same structure of the built-in command help files:
|
263
|
+
|
264
|
+
```
|
265
|
+
Short description of command.
|
266
|
+
|
267
|
+
* Files:
|
268
|
+
* Description of what the command line arguments are
|
269
|
+
|
270
|
+
* Arguments:
|
271
|
+
* argname: Documentation for argument
|
272
|
+
```
|
273
|
+
|
274
|
+
Notes:
|
275
|
+
|
276
|
+
* The first line of the help file is used as the summary in the `show-cmd`
|
277
|
+
listing.
|
278
|
+
* Never omit a section. If a command has no files or arguments, use "(none)"
|
279
|
+
as the list item text.
|
280
|
+
|
220
281
|
### Credentials
|
221
282
|
|
222
283
|
Custom credentials are just flat files or executables in the `credentials/`
|
@@ -244,6 +305,110 @@ These values are read in by Samus and get exposed as `$__creds_key` and
|
|
244
305
|
metadata as well, which would be included as `$__creds_name` (for the
|
245
306
|
line "NAME: value").
|
246
307
|
|
308
|
+
## Manifest File Format
|
309
|
+
|
310
|
+
The following section defines the manifest formats for the samus.json build
|
311
|
+
manifest as well as the manifest.json stored in release packages.
|
312
|
+
|
313
|
+
### Base Format
|
314
|
+
|
315
|
+
The base format is defined as follows:
|
316
|
+
|
317
|
+
```js
|
318
|
+
{
|
319
|
+
"actions": [
|
320
|
+
{
|
321
|
+
"action": "COMMAND_NAME", // [required] command name to execute
|
322
|
+
"files": ["file1", ...], // optional list of files
|
323
|
+
"arguments": { // optional map of arguments to pass to cmd
|
324
|
+
"key": "value", // each key is passed in as _key in ENV
|
325
|
+
// ... (optional) more keys ...
|
326
|
+
},
|
327
|
+
"pwd": "path" // optional path to execute command from
|
328
|
+
"credentials": "KEY", // optional credentials to load for cmd
|
329
|
+
},
|
330
|
+
// ... (optional) more action items ...
|
331
|
+
]
|
332
|
+
}
|
333
|
+
```
|
334
|
+
|
335
|
+
All manifests include a list of "actions", known individually as action items.
|
336
|
+
Each action item has a single required property, "action", which is the command
|
337
|
+
to execute for the action (found in `samus show-cmd`). An optional list of
|
338
|
+
files are passed into the command as command line arguments, and the "arguments"
|
339
|
+
property is a map of keys to values passed in as environment variables with a
|
340
|
+
"\_" prefix (key "foo" is set as environment variable "_foo"). Optional
|
341
|
+
credentials are loaded from the credentials directory.
|
342
|
+
|
343
|
+
### Build Manifest Format
|
344
|
+
|
345
|
+
The build manifest format is similar to the above but allows for two extra keys
|
346
|
+
in each action item called "publish" and "condition".
|
347
|
+
|
348
|
+
#### "publish" Property
|
349
|
+
|
350
|
+
The "publish" property should contain the action item that is added to the
|
351
|
+
final manifest.json built into the release package if the action item is
|
352
|
+
evaluated (condition matches and command successfully executes). If a "files"
|
353
|
+
property is set on the parent action item, that property is copied into the
|
354
|
+
publish action by default, but it can be overridden.
|
355
|
+
|
356
|
+
Here is an example build manifest showing the added use of the "publish"
|
357
|
+
property:
|
358
|
+
|
359
|
+
```js
|
360
|
+
{
|
361
|
+
"actions": [
|
362
|
+
{
|
363
|
+
"action": "readme-update",
|
364
|
+
"files": ["README.txt"],
|
365
|
+
"publish": {
|
366
|
+
"action": "readme-publish"
|
367
|
+
"arguments": {
|
368
|
+
"host": "www.mywebsite.com"
|
369
|
+
},
|
370
|
+
"credentials": "www.mywebsite.com"
|
371
|
+
}
|
372
|
+
},
|
373
|
+
{
|
374
|
+
"action": "readme-build",
|
375
|
+
"files": ["README.txt"],
|
376
|
+
"publish": {
|
377
|
+
"action": "readme-publish"
|
378
|
+
"arguments": {
|
379
|
+
"files": ["README.html"], // override files property
|
380
|
+
"host": "www.mywebsite.com"
|
381
|
+
},
|
382
|
+
"credentials": "www.mywebsite.com"
|
383
|
+
}
|
384
|
+
}
|
385
|
+
]
|
386
|
+
|
387
|
+
}
|
388
|
+
```
|
389
|
+
|
390
|
+
#### "condition" Property
|
391
|
+
|
392
|
+
The "condition" property is a Ruby expression that is evaluated for truthiness
|
393
|
+
to decide if the action item should be evaluated or skipped. A common use for
|
394
|
+
this is to take action based on the version (see "$version" variable section
|
395
|
+
below). The following example runs an action item only for version 2.0+ of a
|
396
|
+
release:
|
397
|
+
|
398
|
+
```js
|
399
|
+
{
|
400
|
+
"action": "rake-task",
|
401
|
+
"arguments": { "task": "assets:package" },
|
402
|
+
"condition": "'$version' > '2.0'"
|
403
|
+
}
|
404
|
+
```
|
405
|
+
|
406
|
+
#### "$version" Variable
|
407
|
+
|
408
|
+
A special variable "$version" is interpolated when loading the build manifest.
|
409
|
+
This variable can appear anywhere in the JSON document, and is interpolated
|
410
|
+
before any actions or conditions are evaluated.
|
411
|
+
|
247
412
|
## Contributing & TODO
|
248
413
|
|
249
414
|
Please help by contributing commands that Samus can use to build or publish
|
data/bin/samus
CHANGED
@@ -40,6 +40,7 @@ end
|
|
40
40
|
|
41
41
|
dry_run = false
|
42
42
|
zip_release = true
|
43
|
+
outfile = nil
|
43
44
|
opts = OptionParser.new do |opts|
|
44
45
|
opts.banner = "Usage: samus publish [options] <directory> [directory ...]\n"
|
45
46
|
opts.banner += " samus build [options] <version> [build.json]\n"
|
@@ -54,6 +55,9 @@ opts = OptionParser.new do |opts|
|
|
54
55
|
opts.on("--[no-]zip", "Zip release directory") do |zip|
|
55
56
|
zip_release = zip
|
56
57
|
end
|
58
|
+
opts.on("-o FILE", "--output", "The file (no extension) to generate") do |file|
|
59
|
+
outfile = file
|
60
|
+
end
|
57
61
|
end
|
58
62
|
end
|
59
63
|
opts.parse!
|
@@ -79,7 +83,7 @@ elsif command == Samus::Builder
|
|
79
83
|
$VERSION = $VERSION.sub(/^v/, '')
|
80
84
|
|
81
85
|
(ARGV.empty? ? ['samus.json'] : ARGV).each do |file|
|
82
|
-
command.new(file).build(dry_run, zip_release)
|
86
|
+
command.new(file).build(dry_run, zip_release, outfile)
|
83
87
|
end
|
84
88
|
else
|
85
89
|
puts opts
|
data/commands/build/fs-sedfiles
CHANGED
@@ -0,0 +1,9 @@
|
|
1
|
+
Builds a separate Samus-backed repository as part of this Samus build.
|
2
|
+
|
3
|
+
Files:
|
4
|
+
* The archive name of the generated Samus release package.
|
5
|
+
|
6
|
+
Arguments:
|
7
|
+
* build_version: the version of the package to build.
|
8
|
+
* manifest: (optional) the name of the manifest to use when building the
|
9
|
+
manifest.
|
data/lib/samus/builder.rb
CHANGED
@@ -16,12 +16,16 @@ module Samus
|
|
16
16
|
@manifest = {}
|
17
17
|
end
|
18
18
|
|
19
|
-
def build(dry_run = false, zip_release = true)
|
19
|
+
def build(dry_run = false, zip_release = true, outfile = nil)
|
20
20
|
orig_pwd = Dir.pwd
|
21
21
|
manifest = {'version' => $VERSION, 'actions' => []}
|
22
22
|
build_branch = "samus-release/v#{$VERSION}"
|
23
23
|
orig_branch = `git symbolic-ref -q --short HEAD`.chomp
|
24
24
|
|
25
|
+
if `git diff --shortstat 2> /dev/null | tail -n1` != ""
|
26
|
+
Samus.error "Repository is dirty, it is too dangerous to continue."
|
27
|
+
end
|
28
|
+
|
25
29
|
system "git checkout -qb #{build_branch} 2>/dev/null"
|
26
30
|
remove_restore_file
|
27
31
|
|
@@ -41,14 +45,14 @@ module Samus
|
|
41
45
|
|
42
46
|
Dir.chdir(build_dir) do
|
43
47
|
generate_manifest(manifest)
|
44
|
-
generate_release(orig_pwd, zip_release)
|
48
|
+
generate_release(orig_pwd, zip_release, outfile)
|
45
49
|
end unless dry_run
|
46
50
|
end
|
47
51
|
|
48
52
|
ensure
|
49
53
|
restore_git_repo
|
50
|
-
system "git checkout -q #{orig_branch}"
|
51
|
-
system "git branch -qD #{build_branch}"
|
54
|
+
system "git checkout -q #{orig_branch} 2>/dev/null"
|
55
|
+
system "git branch -qD #{build_branch} 2>/dev/null"
|
52
56
|
end
|
53
57
|
|
54
58
|
private
|
@@ -59,9 +63,9 @@ module Samus
|
|
59
63
|
end
|
60
64
|
end
|
61
65
|
|
62
|
-
def generate_release(orig_pwd, zip_release = true)
|
63
|
-
file = build_manifest['output'] || "release-v#{$VERSION}"
|
64
|
-
file = File.join(orig_pwd, file)
|
66
|
+
def generate_release(orig_pwd, zip_release = true, outfile = nil)
|
67
|
+
file = outfile || build_manifest['output'] || "release-v#{$VERSION}"
|
68
|
+
file = File.join(orig_pwd, file) unless file[0] == '/'
|
65
69
|
if zip_release
|
66
70
|
file += '.tar.gz'
|
67
71
|
system "tar cfz #{file} *"
|
data/lib/samus/command.rb
CHANGED
@@ -4,16 +4,12 @@ module Samus
|
|
4
4
|
def command_paths; @@command_paths end
|
5
5
|
|
6
6
|
def list_commands(stage = nil)
|
7
|
-
|
8
|
-
|
9
|
-
Dir.glob(File.join(path, '*', '*')).each do |dir|
|
10
|
-
type, name = *dir.split(File::SEPARATOR)[-2,2]
|
11
|
-
next if name =~ /\.md$/
|
12
|
-
next if stage && stage != type
|
13
|
-
(stages[type] ||= []).push(new(type, name))
|
14
|
-
end
|
15
|
-
end
|
7
|
+
display_commands(collect_commands(stage))
|
8
|
+
end
|
16
9
|
|
10
|
+
private
|
11
|
+
|
12
|
+
def display_commands(stages)
|
17
13
|
puts "Commands:"
|
18
14
|
puts ""
|
19
15
|
stages.each do |type, commands|
|
@@ -25,6 +21,19 @@ module Samus
|
|
25
21
|
puts ""
|
26
22
|
end
|
27
23
|
end
|
24
|
+
|
25
|
+
def collect_commands(stage)
|
26
|
+
stages = {}
|
27
|
+
command_paths.each do |path|
|
28
|
+
Dir.glob(File.join(path, '*', '*')).each do |dir|
|
29
|
+
type, name = *dir.split(File::SEPARATOR)[-2,2]
|
30
|
+
next if name =~ /\.md$/
|
31
|
+
next if stage && stage != type
|
32
|
+
(stages[type] ||= []).push(new(type, name))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
stages
|
36
|
+
end
|
28
37
|
end
|
29
38
|
|
30
39
|
@@command_paths = [File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'commands'))]
|
@@ -66,10 +75,7 @@ module Samus
|
|
66
75
|
exec_in_dir(pwd) do
|
67
76
|
system(env, @full_path + " " + (arguments ? arguments.join(" ") : ""))
|
68
77
|
end
|
69
|
-
|
70
|
-
puts "[E] Last command failed with #{$?}#{allow_fail ? ' but allowFail=true' : ', exiting'}."
|
71
|
-
exit($?.to_i) unless allow_fail
|
72
|
-
end
|
78
|
+
report_error($?, allow_fail)
|
73
79
|
end
|
74
80
|
end
|
75
81
|
|
@@ -79,6 +85,12 @@ module Samus
|
|
79
85
|
|
80
86
|
private
|
81
87
|
|
88
|
+
def report_error(exit_code, allow_fail)
|
89
|
+
return if exit_code.to_i == 0
|
90
|
+
puts "[E] Last command failed with #{exit_code}#{allow_fail ? ' but allowFail=true' : ', exiting'}."
|
91
|
+
exit(exit_code.to_i) unless allow_fail
|
92
|
+
end
|
93
|
+
|
82
94
|
def exec_in_dir(dir, &block)
|
83
95
|
dir ? Dir.chdir(dir, &block) : yield
|
84
96
|
end
|
data/lib/samus/version.rb
CHANGED
data/samus.json
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
"actions": [
|
3
3
|
{
|
4
4
|
"action": "fs-sedfiles",
|
5
|
-
"files": ["lib
|
5
|
+
"files": ["lib/*/version.rb"],
|
6
6
|
"arguments": {
|
7
7
|
"search": "VERSION = ['\"](.+?)['\"]",
|
8
8
|
"replace": "VERSION = '$version'"
|
@@ -10,7 +10,7 @@
|
|
10
10
|
},
|
11
11
|
{
|
12
12
|
"action": "git-commit",
|
13
|
-
"files": ["lib
|
13
|
+
"files": ["lib/*/version.rb"]
|
14
14
|
},
|
15
15
|
{
|
16
16
|
"action": "git-merge",
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: samus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Loren Segal
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-03-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email: lsegal@soen.ca
|
@@ -42,10 +42,14 @@ files:
|
|
42
42
|
- commands/build/git-commit.help.md
|
43
43
|
- commands/build/git-merge
|
44
44
|
- commands/build/git-merge.help.md
|
45
|
+
- commands/build/npm-task
|
46
|
+
- commands/build/npm-task.help.md
|
45
47
|
- commands/build/npm-test
|
46
48
|
- commands/build/npm-test.help.md
|
47
49
|
- commands/build/rake-task
|
48
50
|
- commands/build/rake-task.help.md
|
51
|
+
- commands/build/samus-build
|
52
|
+
- commands/build/samus-build.help.md
|
49
53
|
- commands/publish/cf-invalidate
|
50
54
|
- commands/publish/cf-invalidate.help.md
|
51
55
|
- commands/publish/gem-push
|
@@ -56,6 +60,8 @@ files:
|
|
56
60
|
- commands/publish/npm-publish.help.md
|
57
61
|
- commands/publish/s3-put
|
58
62
|
- commands/publish/s3-put.help.md
|
63
|
+
- commands/publish/samus-publish
|
64
|
+
- commands/publish/samus-publish.help.md
|
59
65
|
- lib/samus.rb
|
60
66
|
- lib/samus/action.rb
|
61
67
|
- lib/samus/build_action.rb
|