@codedependant/semantic-release-docker 4.3.0 → 4.4.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.
- package/CHANGELOG.md +8 -0
- package/README.md +65 -15
- package/lib/build-config.js +6 -0
- package/lib/docker/image.js +56 -16
- package/lib/prepare.js +14 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Semantic Release Docker
|
|
2
2
|
|
|
3
|
+
# [4.4.0](https://github.com/esatterwhite/semantic-release-docker/compare/v4.3.0...v4.4.0) (2023-07-11)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **image**: add support for cache-from build flag [efae32d](https://github.com/esatterwhite/semantic-release-docker/commit/efae32d760bc0ef1978ad97f834b4cb034199ace) - Eric Satterwhite, closes: [#35](https://github.com/esatterwhite/semantic-release-docker/issues/35)
|
|
9
|
+
* **image**: support arbitrary build flags [d7e875d](https://github.com/esatterwhite/semantic-release-docker/commit/d7e875d2b0b8de58e57c56e9ba24bf3c2db5df84) - Eric Satterwhite
|
|
10
|
+
|
|
3
11
|
# [4.3.0](https://github.com/esatterwhite/semantic-release-docker/compare/v4.2.0...v4.3.0) (2022-12-29)
|
|
4
12
|
|
|
5
13
|
|
package/README.md
CHANGED
|
@@ -42,20 +42,22 @@ omitted, it is assumed the docker daemon is already authenticated with the targe
|
|
|
42
42
|
|
|
43
43
|
### Options
|
|
44
44
|
|
|
45
|
-
| Option
|
|
46
|
-
|
|
47
|
-
| `dockerTags`
|
|
48
|
-
| `dockerImage`
|
|
49
|
-
| `dockerRegistry`
|
|
50
|
-
| `dockerProject`
|
|
51
|
-
| `dockerFile`
|
|
52
|
-
| `dockerContext`
|
|
53
|
-
| `dockerLogin`
|
|
54
|
-
| `dockerArgs`
|
|
55
|
-
| `dockerPublish`
|
|
56
|
-
| `dockerVerifyCmd`
|
|
57
|
-
| `dockerNetwork`
|
|
58
|
-
| `dockerAutoClean`
|
|
45
|
+
| Option | Description | Type | Default |
|
|
46
|
+
|------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|---------------------------------------------------------------|
|
|
47
|
+
| `dockerTags` | _Optional_. An array of strings allowing to specify additional tags to apply to the image. Supports templating | [Array][]<[String][]> | [`latest`, `{{major}}-latest`, `{{version}}`] |
|
|
48
|
+
| `dockerImage` | _Optional_. The name of the image to release. | [String][] | Parsed from package.json `name` property |
|
|
49
|
+
| `dockerRegistry` | _Optional_. The hostname and port used by the the registry in format `hostname[:port]`. Omit the port if the registry uses the default port | [String][] | `null` (dockerhub) |
|
|
50
|
+
| `dockerProject` | _Optional_. The project or repository name to publish the image to | [String][] | For scoped packages, the scope will be used, otherwise `null` |
|
|
51
|
+
| `dockerFile` | _Optional_. The path, relative to `$PWD` to a Docker file to build the target image with | [String][] | `Dockerfile` |
|
|
52
|
+
| `dockerContext` | _Optional_. A path, relative to `$PWD` to use as the build context A | [String][] | `.` |
|
|
53
|
+
| `dockerLogin` | _Optional_. Set to false it by pass docker login if the docker daemon is already authorized | [String][] | `true` |
|
|
54
|
+
| `dockerArgs` | _Optional_. Include additional values for docker's `build-arg`. Supports templating | [Object][] | |
|
|
55
|
+
| `dockerPublish` | _Optional_. Automatically push image tags during the publish phase. | [Boolean][] | `true` |
|
|
56
|
+
| `dockerVerifyCmd` | _Optional_. If specified, during the verify stage, the specified command will execute in a container of the build image. If the command errors, the release will fail. | [String][] | `false` |
|
|
57
|
+
| `dockerNetwork` | _Optional_. Specify the Docker network to use while the image is building. | [String][] | `default` |
|
|
58
|
+
| `dockerAutoClean` | _Optional_. If set to true | [Boolean][] | `true` |
|
|
59
|
+
| `dockerBuildFlags` | _Optional_. An object containing additional flags to the `docker build` command. Values can be strings or an array of strings | [Object][] | `{}` |
|
|
60
|
+
| `dockerBuildCacheFrom` | _Optional_. A list of external cache sources. See [--cache-from][] | [String][] | [Array][]<[String][]> | |
|
|
59
61
|
|
|
60
62
|
### Build Arguments
|
|
61
63
|
|
|
@@ -117,7 +119,50 @@ The following handlebars template helpers are pre installed
|
|
|
117
119
|
| `startswith` | returns true if a string starts with another | [Boolean][] | <pre lang="hbs">{{#if (starts myvar 'foo')}}{{ othervar }}{{/if}}</pre> |
|
|
118
120
|
| `upper` | returns the upper cased varient of the input string | [String][] | <pre lang="hbs">{{upper my_var}}</pre> |
|
|
119
121
|
|
|
122
|
+
### Build Flags
|
|
120
123
|
|
|
124
|
+
Using the `dockerBuildFlags` option allows you to pass arbitrary flags to the build command.
|
|
125
|
+
If the standardized options are not sufficient, `dockerBuildFlags` is a perfect workaround
|
|
126
|
+
until first class support can be added. This is considered and advanced feature, and you should
|
|
127
|
+
know what you intend to do before using. There is no validation, and any configuration of the
|
|
128
|
+
docker daemon required is expected to be done before hand.
|
|
129
|
+
|
|
130
|
+
Keys found in `dockerBuildFlags` are normalized as command line flags in the following manner:
|
|
131
|
+
|
|
132
|
+
* If the key does not start with a `-` it will be prepended
|
|
133
|
+
* all occurences of `_` will be re-written as `-`
|
|
134
|
+
* Single letter keys are considered shorthands e.g. `p` becomes `-p`
|
|
135
|
+
* Multi letter keys are considered long form e.g. `foo_bar` becomes `--foo-bar`
|
|
136
|
+
* If the value is an array, the flag is repeated for each occurance
|
|
137
|
+
* A `null` value may be used to omit the value and only inject the flag itself
|
|
138
|
+
|
|
139
|
+
#### Example
|
|
140
|
+
|
|
141
|
+
```javascript
|
|
142
|
+
{
|
|
143
|
+
plugins: [
|
|
144
|
+
['@codedependant/semantic-release-docker', {
|
|
145
|
+
dockerImage: 'my-image',
|
|
146
|
+
dockerRegistry: 'quay.io',
|
|
147
|
+
dockerProject: 'codedependant',
|
|
148
|
+
dockerCacheFrom: 'myname/myapp'
|
|
149
|
+
dockerBuildFlags: {
|
|
150
|
+
pull: null
|
|
151
|
+
, target: 'release'
|
|
152
|
+
},
|
|
153
|
+
dockerArgs: {
|
|
154
|
+
GITHUB_TOKEN: null
|
|
155
|
+
}
|
|
156
|
+
}]
|
|
157
|
+
]
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
This configuration, will generate the following build command
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
> docker build --network=default --quiet --tag quay.io/codedependant/my-image:abc123 --cache-from myname/myapp --build-arg GITHUB_TOKEN --pull --target release -f path/to/repo/Dockerfile /path/to/repo
|
|
165
|
+
```
|
|
121
166
|
|
|
122
167
|
## Usage
|
|
123
168
|
|
|
@@ -135,8 +180,12 @@ module.exports = {
|
|
|
135
180
|
dockerFile: 'Dockerfile',
|
|
136
181
|
dockerRegistry: 'quay.io',
|
|
137
182
|
dockerProject: 'codedependant',
|
|
183
|
+
dockerBuildFlags: {
|
|
184
|
+
pull: null
|
|
185
|
+
, target: 'release'
|
|
186
|
+
},
|
|
138
187
|
dockerArgs: {
|
|
139
|
-
API_TOKEN:
|
|
188
|
+
API_TOKEN: null
|
|
140
189
|
, RELEASE_DATE: new Date().toISOString()
|
|
141
190
|
, RELEASE_VERSION: '{{next.version}}'
|
|
142
191
|
}
|
|
@@ -233,3 +282,4 @@ $ openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout server.key -o
|
|
|
233
282
|
[Array]: https://mdn.io/array
|
|
234
283
|
[Object]: https://mdn.io/object
|
|
235
284
|
[Number]: https://mdn.io/number
|
|
285
|
+
[--cache-from]: https://docs.docker.com/engine/reference/commandline/build/#cache-from
|
package/lib/build-config.js
CHANGED
|
@@ -16,6 +16,8 @@ async function buildConfig(build_id, config, context) {
|
|
|
16
16
|
, dockerNoCache: nocache = false
|
|
17
17
|
, dockerTags: tags = ['latest', '{{major}}-latest', '{{version}}']
|
|
18
18
|
, dockerArgs: args = {}
|
|
19
|
+
, dockerBuildFlags: build_flags = {}
|
|
20
|
+
, dockerBuildCacheFrom: cache_from
|
|
19
21
|
, dockerRegistry: registry = null
|
|
20
22
|
, dockerLogin: login = true
|
|
21
23
|
, dockerImage: image
|
|
@@ -40,10 +42,14 @@ async function buildConfig(build_id, config, context) {
|
|
|
40
42
|
const root = object.get(context, 'options.root')
|
|
41
43
|
const target = path.relative(root || context.cwd, context.cwd) || PWD
|
|
42
44
|
const {nextRelease = {}} = context
|
|
45
|
+
|
|
46
|
+
if (cache_from) build_flags.cache_from = array.toArray(cache_from)
|
|
47
|
+
|
|
43
48
|
return {
|
|
44
49
|
registry
|
|
45
50
|
, dockerfile
|
|
46
51
|
, nocache
|
|
52
|
+
, build_flags
|
|
47
53
|
, pkg
|
|
48
54
|
, project
|
|
49
55
|
, publish
|
package/lib/docker/image.js
CHANGED
|
@@ -26,15 +26,16 @@ class Image {
|
|
|
26
26
|
|
|
27
27
|
this.sha = sha
|
|
28
28
|
this.opts = {
|
|
29
|
-
|
|
30
|
-
,
|
|
31
|
-
, project: project
|
|
32
|
-
, name: name
|
|
33
|
-
, build_id: build_id
|
|
34
|
-
, dockerfile: dockerfile
|
|
29
|
+
build_id: build_id
|
|
30
|
+
, args: new Map()
|
|
35
31
|
, context: context
|
|
36
32
|
, cwd: cwd
|
|
33
|
+
, dockerfile: dockerfile
|
|
34
|
+
, flags: new Map()
|
|
35
|
+
, name: name
|
|
37
36
|
, network: network
|
|
37
|
+
, project: project
|
|
38
|
+
, registry: registry
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
|
|
@@ -72,27 +73,66 @@ class Image {
|
|
|
72
73
|
return this.opts.network
|
|
73
74
|
}
|
|
74
75
|
|
|
75
|
-
|
|
76
|
+
get flags() {
|
|
77
|
+
const output = []
|
|
78
|
+
|
|
79
|
+
for (const [key, value] of this.opts.flags.entries()) {
|
|
80
|
+
let normalized = key
|
|
81
|
+
if (!key.startsWith('-')) {
|
|
82
|
+
normalized = (key.length === 1 ? `-${key}` : `--${key}`)
|
|
83
|
+
.toLowerCase()
|
|
84
|
+
.replace(/_/g, '-')
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (value === null) {
|
|
88
|
+
output.push(normalized)
|
|
89
|
+
continue
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
for (const item of value) {
|
|
93
|
+
output.push(normalized, item)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return output
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
arg(key, val = null) {
|
|
101
|
+
if (val === true || val == null) { // eslint-disable-line no-eq-null
|
|
102
|
+
this.flag('build-arg', key)
|
|
103
|
+
} else {
|
|
104
|
+
this.flag('build-arg', `${key}=${val}`)
|
|
105
|
+
}
|
|
76
106
|
this.opts.args.set(key, val)
|
|
77
107
|
return this
|
|
78
108
|
}
|
|
79
109
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
110
|
+
flag(key, val) {
|
|
111
|
+
if (val === null) {
|
|
112
|
+
this.opts.flags.set(key, val)
|
|
113
|
+
return this
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
let value = this.opts.flags.get(key) || []
|
|
117
|
+
|
|
118
|
+
if (Array.isArray(val)) {
|
|
119
|
+
value = value.concat(val)
|
|
120
|
+
} else {
|
|
121
|
+
value.push(val)
|
|
88
122
|
}
|
|
123
|
+
|
|
124
|
+
this.opts.flags.set(key, value)
|
|
125
|
+
return this
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
get build_cmd() {
|
|
89
129
|
return [
|
|
90
130
|
'build'
|
|
91
131
|
, `--network=${this.network}`
|
|
92
132
|
, '--quiet'
|
|
93
133
|
, '--tag'
|
|
94
134
|
, this.name
|
|
95
|
-
, ...
|
|
135
|
+
, ...this.flags
|
|
96
136
|
, '-f'
|
|
97
137
|
, this.dockerfile
|
|
98
138
|
, this.context
|
package/lib/prepare.js
CHANGED
|
@@ -20,15 +20,25 @@ async function dockerPrepare(opts, context) {
|
|
|
20
20
|
, network: opts.network
|
|
21
21
|
})
|
|
22
22
|
|
|
23
|
-
const
|
|
24
|
-
|
|
23
|
+
const vars = buildTemplateVars(opts, context)
|
|
24
|
+
|
|
25
|
+
function render(item, vars) {
|
|
26
|
+
if (Array.isArray(item)) {
|
|
27
|
+
return item.map((element) => {
|
|
28
|
+
return string.template(element)(vars)
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
return string.template(item)(vars)
|
|
25
32
|
}
|
|
26
33
|
|
|
27
|
-
const
|
|
28
|
-
for (const [key, value] of Object.entries(args)) {
|
|
34
|
+
for (const [key, value] of Object.entries(opts.args)) {
|
|
29
35
|
image.arg(key, string.template(value)(vars))
|
|
30
36
|
}
|
|
31
37
|
|
|
38
|
+
for (const [key, value] of Object.entries(opts.build_flags)) {
|
|
39
|
+
image.flag(key, render(value, vars))
|
|
40
|
+
}
|
|
41
|
+
|
|
32
42
|
context.logger.info('building image', image.name)
|
|
33
43
|
context.logger.debug('build command: docker %s', image.build_cmd.join(' '))
|
|
34
44
|
await image.build(path.join(cwd, opts.context))
|