@datatruck/cli 0.8.0 → 0.9.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/Task/MysqlDumpTask.d.ts +2 -1
- package/Task/MysqlDumpTask.js +31 -1
- package/Task/PostgresqlDumpTask.d.ts +2 -1
- package/Task/PostgresqlDumpTask.js +4 -1
- package/Task/SqlDumpTaskAbstract.d.ts +3 -1
- package/Task/SqlDumpTaskAbstract.js +7 -2
- package/config.schema.json +3 -0
- package/package.json +9 -9
- package/util/date-util.d.ts +1 -1
- package/util/entity-util.d.ts +1 -1
- package/util/fs-util.d.ts +1 -0
- package/util/process-util.d.ts +1 -0
- package/CHANGELOG.md +0 -145
package/Task/MysqlDumpTask.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export declare class MysqlDumpTask extends SqlDumpTaskAbstract<MysqlDumpTaskConf
|
|
|
9
9
|
onCreateDatabase(database: TargetDatabaseType): Promise<void>;
|
|
10
10
|
onExecQuery(query: string): Promise<import("../util/process-util").ExecResultType>;
|
|
11
11
|
onFetchTableNames(database: string): Promise<string[]>;
|
|
12
|
-
|
|
12
|
+
onExportTables(tableNames: string[], output: string): Promise<void>;
|
|
13
|
+
onExportStoredPrograms(output: string): Promise<void>;
|
|
13
14
|
onImport(path: string, database: string): Promise<void>;
|
|
14
15
|
}
|
package/Task/MysqlDumpTask.js
CHANGED
|
@@ -68,7 +68,7 @@ class MysqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
|
|
|
68
68
|
table_schema = '${database}'
|
|
69
69
|
`);
|
|
70
70
|
}
|
|
71
|
-
async
|
|
71
|
+
async onExportTables(tableNames, output) {
|
|
72
72
|
const stream = (0, fs_1.createWriteStream)(output);
|
|
73
73
|
await Promise.all([
|
|
74
74
|
new Promise((resolve, reject) => {
|
|
@@ -107,6 +107,36 @@ class MysqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
|
|
|
107
107
|
if (!successFooter)
|
|
108
108
|
throw new AppError_1.AppError("No end line found (incomplete backup)");
|
|
109
109
|
}
|
|
110
|
+
async onExportStoredPrograms(output) {
|
|
111
|
+
const stream = (0, fs_1.createWriteStream)(output);
|
|
112
|
+
await Promise.all([
|
|
113
|
+
new Promise((resolve, reject) => {
|
|
114
|
+
stream.on("close", resolve);
|
|
115
|
+
stream.on("error", reject);
|
|
116
|
+
}),
|
|
117
|
+
await (0, process_util_1.exec)("mysqldump", [
|
|
118
|
+
...(await this.buildConnectionArgs()),
|
|
119
|
+
"--lock-tables=false",
|
|
120
|
+
"--routines",
|
|
121
|
+
"--events",
|
|
122
|
+
"--skip-triggers",
|
|
123
|
+
"--no-create-info",
|
|
124
|
+
"--no-data",
|
|
125
|
+
"--no-create-db",
|
|
126
|
+
"--skip-opt",
|
|
127
|
+
], null, {
|
|
128
|
+
pipe: { stream: stream },
|
|
129
|
+
log: {
|
|
130
|
+
exec: this.verbose,
|
|
131
|
+
stderr: this.verbose,
|
|
132
|
+
allToStderr: true,
|
|
133
|
+
},
|
|
134
|
+
stderr: {
|
|
135
|
+
toExitCode: true,
|
|
136
|
+
},
|
|
137
|
+
}),
|
|
138
|
+
]);
|
|
139
|
+
}
|
|
110
140
|
async onImport(path, database) {
|
|
111
141
|
await (0, process_util_1.exec)("mysql", [...(await this.buildConnectionArgs(false)), database], null, {
|
|
112
142
|
pipe: {
|
|
@@ -9,6 +9,7 @@ export declare class PostgresqlDumpTask extends SqlDumpTaskAbstract<PostgresqlDu
|
|
|
9
9
|
onCreateDatabase(database: TargetDatabaseType): Promise<void>;
|
|
10
10
|
onExecQuery(query: string): Promise<import("../util/process-util").ExecResultType>;
|
|
11
11
|
onFetchTableNames(database: string): Promise<string[]>;
|
|
12
|
-
|
|
12
|
+
onExportTables(tableNames: string[], output: string): Promise<void>;
|
|
13
|
+
onExportStoredPrograms(): Promise<void>;
|
|
13
14
|
onImport(path: string, database: string): Promise<void>;
|
|
14
15
|
}
|
|
@@ -71,7 +71,7 @@ class PostgresqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
|
|
|
71
71
|
table_schema NOT IN ('pg_catalog', 'information_schema')
|
|
72
72
|
`);
|
|
73
73
|
}
|
|
74
|
-
async
|
|
74
|
+
async onExportTables(tableNames, output) {
|
|
75
75
|
const stream = (0, fs_1.createWriteStream)(output);
|
|
76
76
|
await Promise.all([
|
|
77
77
|
new Promise((resolve, reject) => {
|
|
@@ -90,6 +90,9 @@ class PostgresqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
|
|
|
90
90
|
}),
|
|
91
91
|
]);
|
|
92
92
|
}
|
|
93
|
+
async onExportStoredPrograms() {
|
|
94
|
+
throw new Error(`Method not implemented: onExportStoredPrograms`);
|
|
95
|
+
}
|
|
93
96
|
async onImport(path, database) {
|
|
94
97
|
await (0, process_util_1.exec)("psql", [...(await this.buildConnectionArgs(database)), "-f", (0, path_1.normalize)(path)], undefined, {
|
|
95
98
|
log: this.verbose,
|
|
@@ -14,6 +14,7 @@ export declare type SqlDumpTaskConfigType = {
|
|
|
14
14
|
port?: number;
|
|
15
15
|
database: string;
|
|
16
16
|
username: string;
|
|
17
|
+
storedPrograms?: boolean;
|
|
17
18
|
targetDatabase?: TargetDatabaseType;
|
|
18
19
|
includeTables?: string[];
|
|
19
20
|
excludeTables?: string[];
|
|
@@ -28,7 +29,8 @@ export declare abstract class SqlDumpTaskAbstract<TConfig extends SqlDumpTaskCon
|
|
|
28
29
|
abstract onDatabaseIsEmpty(databaseName: string): Promise<boolean>;
|
|
29
30
|
abstract onFetchTableNames(database: string): Promise<string[]>;
|
|
30
31
|
abstract onExecQuery(query: string): ReturnType<typeof exec>;
|
|
31
|
-
abstract
|
|
32
|
+
abstract onExportTables(tableNames: string[], output: string): Promise<void>;
|
|
33
|
+
abstract onExportStoredPrograms(output: string): Promise<void>;
|
|
32
34
|
abstract onImport(path: string, database: string): Promise<void>;
|
|
33
35
|
onBackup(data: BackupDataType): Promise<void>;
|
|
34
36
|
onRestore(data: RestoreDataType): Promise<void>;
|
|
@@ -44,6 +44,7 @@ exports.sqlDumpTaskDefinition = {
|
|
|
44
44
|
collate: { type: "string" },
|
|
45
45
|
},
|
|
46
46
|
},
|
|
47
|
+
storedPrograms: { type: "boolean" },
|
|
47
48
|
includeTables: (0, DefinitionEnum_1.makeRef)(DefinitionEnum_1.DefinitionEnum.stringListUtil),
|
|
48
49
|
excludeTables: (0, DefinitionEnum_1.makeRef)(DefinitionEnum_1.DefinitionEnum.stringListUtil),
|
|
49
50
|
oneFileByTable: { type: "boolean" },
|
|
@@ -116,7 +117,7 @@ class SqlDumpTaskAbstract extends TaskAbstract_1.TaskAbstract {
|
|
|
116
117
|
await (0, promises_1.mkdir)(outputPath, { recursive: true });
|
|
117
118
|
if (!this.config.oneFileByTable) {
|
|
118
119
|
const outPath = (0, path_1.join)(outputPath, serializeSqlFile({ database: this.config.database }));
|
|
119
|
-
await this.
|
|
120
|
+
await this.onExportTables(tableNames, outPath);
|
|
120
121
|
}
|
|
121
122
|
else {
|
|
122
123
|
let current = 0;
|
|
@@ -129,9 +130,13 @@ class SqlDumpTaskAbstract extends TaskAbstract_1.TaskAbstract {
|
|
|
129
130
|
});
|
|
130
131
|
current++;
|
|
131
132
|
const outPath = (0, path_1.join)(outputPath, serializeSqlFile({ table: tableName }));
|
|
132
|
-
await this.
|
|
133
|
+
await this.onExportTables([tableName], outPath);
|
|
133
134
|
}
|
|
134
135
|
}
|
|
136
|
+
if (this.config.storedPrograms) {
|
|
137
|
+
const outPath = (0, path_1.join)(outputPath, "stored-programs.sql");
|
|
138
|
+
await this.onExportStoredPrograms(outPath);
|
|
139
|
+
}
|
|
135
140
|
}
|
|
136
141
|
async onRestore(data) {
|
|
137
142
|
const restorePath = data.package.restorePath;
|
package/config.schema.json
CHANGED
package/package.json
CHANGED
|
@@ -1,29 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datatruck/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"ajv": "^8.11.0",
|
|
6
6
|
"async": "^3.2.4",
|
|
7
7
|
"chalk": "^4.1.2",
|
|
8
8
|
"cli-table3": "^0.6.2",
|
|
9
|
-
"commander": "^9.
|
|
10
|
-
"dayjs": "^1.11.
|
|
9
|
+
"commander": "^9.3.0",
|
|
10
|
+
"dayjs": "^1.11.3",
|
|
11
11
|
"fast-glob": "^3.2.11",
|
|
12
12
|
"micromatch": "^4.0.5",
|
|
13
13
|
"sqlite": "^4.1.1",
|
|
14
14
|
"sqlite3": "^5.0.8"
|
|
15
15
|
},
|
|
16
16
|
"optionalDependencies": {
|
|
17
|
-
"ts-node": "^10.
|
|
18
|
-
"yaml": "^2.1.
|
|
17
|
+
"ts-node": "^10.8.2",
|
|
18
|
+
"yaml": "^2.1.1"
|
|
19
19
|
},
|
|
20
20
|
"engine": {
|
|
21
21
|
"node": ">=16.0.0"
|
|
22
22
|
},
|
|
23
|
-
"bin": {
|
|
24
|
-
"datatruck": "bin.js",
|
|
25
|
-
"dtt": "bin.js"
|
|
26
|
-
},
|
|
27
23
|
"description": "Tool for creating and managing backups",
|
|
28
24
|
"homepage": "https://github.com/swordev/datatruck#readme",
|
|
29
25
|
"bugs": {
|
|
@@ -38,5 +34,9 @@
|
|
|
38
34
|
"name": "Juanra GM",
|
|
39
35
|
"email": "juanrgm724@gmail.com",
|
|
40
36
|
"url": "https://github.com/juanrgm"
|
|
37
|
+
},
|
|
38
|
+
"bin": {
|
|
39
|
+
"datatruck": "bin.js",
|
|
40
|
+
"dtt": "bin.js"
|
|
41
41
|
}
|
|
42
42
|
}
|
package/util/date-util.d.ts
CHANGED
|
@@ -12,5 +12,5 @@ export declare function filterByLast<TItem extends {
|
|
|
12
12
|
}>(items: TItem[], options: FilterByLastOptionsType, reasons?: Record<number, string[]>): TItem[];
|
|
13
13
|
export declare function createChron(): {
|
|
14
14
|
start: () => number;
|
|
15
|
-
elapsed: (formatted?: boolean
|
|
15
|
+
elapsed: (formatted?: boolean) => string | number;
|
|
16
16
|
};
|
package/util/entity-util.d.ts
CHANGED
package/util/fs-util.d.ts
CHANGED
package/util/process-util.d.ts
CHANGED
package/CHANGELOG.md
DELETED
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
# @datatruck/cli
|
|
2
|
-
|
|
3
|
-
## 0.8.0
|
|
4
|
-
|
|
5
|
-
### Minor Changes
|
|
6
|
-
|
|
7
|
-
- [`8c421ab`](https://github.com/swordev/datatruck/commit/8c421ab0adb6f2d5bc81e91fa387c5daa848f411) Thanks [@juanrgm](https://github.com/juanrgm)! - Add `--package-task` option to snapshot command
|
|
8
|
-
|
|
9
|
-
## 0.7.0
|
|
10
|
-
|
|
11
|
-
### Minor Changes
|
|
12
|
-
|
|
13
|
-
- [`3b8d6da`](https://github.com/swordev/datatruck/commit/3b8d6da01495799aceb848a63b35b8c46a7d1b0e) Thanks [@juanrgm](https://github.com/juanrgm)! - Add `--package-task` cli option
|
|
14
|
-
|
|
15
|
-
* [`69b34a0`](https://github.com/swordev/datatruck/commit/69b34a02b9cade48df2b071a92a8f79d5cfec23e) Thanks [@juanrgm](https://github.com/juanrgm)! - Allow restore multiple backups over the same database
|
|
16
|
-
|
|
17
|
-
- [`69caf26`](https://github.com/swordev/datatruck/commit/69caf26881272331bd4c8d7d345b3b85d33e33ac) Thanks [@juanrgm](https://github.com/juanrgm)! - Add cli short option to `--tag`
|
|
18
|
-
|
|
19
|
-
* [`377f0de`](https://github.com/swordev/datatruck/commit/377f0de345c9c8f45c772ac47e4ded81e91725d7) Thanks [@juanrgm](https://github.com/juanrgm)! - Rename cli short option to `-rt`
|
|
20
|
-
|
|
21
|
-
### Patch Changes
|
|
22
|
-
|
|
23
|
-
- [`c03200a`](https://github.com/swordev/datatruck/commit/c03200a6347d1e9f9fdad86dcb22df30bbefcab4) Thanks [@juanrgm](https://github.com/juanrgm)! - Fix `sql-dump` tasks
|
|
24
|
-
|
|
25
|
-
* [`f56a4bc`](https://github.com/swordev/datatruck/commit/f56a4bcb429a674c13f32de73985cd67eb1acc23) Thanks [@juanrgm](https://github.com/juanrgm)! - Show full error message
|
|
26
|
-
|
|
27
|
-
- [`4324422`](https://github.com/swordev/datatruck/commit/4324422550474619811a8d455af55bc6e3b08aeb) Thanks [@juanrgm](https://github.com/juanrgm)! - Use connection port in `mysql-dump` task
|
|
28
|
-
|
|
29
|
-
## 0.6.1
|
|
30
|
-
|
|
31
|
-
### Patch Changes
|
|
32
|
-
|
|
33
|
-
- [`0ba6229`](https://github.com/swordev/datatruck/commit/0ba6229348c109a59783e72242ab7c0e61f25e36) Thanks [@juanrgm](https://github.com/juanrgm)! - Fix progress bar in restic repository
|
|
34
|
-
|
|
35
|
-
## 0.6.0
|
|
36
|
-
|
|
37
|
-
### Minor Changes
|
|
38
|
-
|
|
39
|
-
- [`0c6877d`](https://github.com/swordev/datatruck/commit/0c6877d189761e75dd434b0a8d72b71621d024de) Thanks [@juanrgm](https://github.com/juanrgm)! - Show more progress stats
|
|
40
|
-
|
|
41
|
-
* [`751e1f6`](https://github.com/swordev/datatruck/commit/751e1f6d6b33d3fa96eb40d998fdd140ce0e3875) Thanks [@juanrgm](https://github.com/juanrgm)! - Add `fileCopyConcurrency` option
|
|
42
|
-
|
|
43
|
-
- [`05487e6`](https://github.com/swordev/datatruck/commit/05487e6a33f875a3afb7ff0815b16da6f2a41301) Thanks [@juanrgm](https://github.com/juanrgm)! - Parse InnoDB error in `MariadbTask` to avoid infinite wait
|
|
44
|
-
|
|
45
|
-
### Patch Changes
|
|
46
|
-
|
|
47
|
-
- [`b62a6f8`](https://github.com/swordev/datatruck/commit/b62a6f8a82409339afd65d4f96476eb57bbfb5a2) Thanks [@juanrgm](https://github.com/juanrgm)! - Resolve target/restore path in local repository
|
|
48
|
-
|
|
49
|
-
## 0.5.0
|
|
50
|
-
|
|
51
|
-
### Minor Changes
|
|
52
|
-
|
|
53
|
-
- [`5aeb2af`](https://github.com/swordev/datatruck/commit/5aeb2afb96692e00bdba501b58df9cc0e02dceaa) Thanks [@juanrgm](https://github.com/juanrgm)! - Add `enabled` option to repository config
|
|
54
|
-
|
|
55
|
-
* [`75de836`](https://github.com/swordev/datatruck/commit/75de8369356cf02ed3fd5c58b1f9bea66432cda8) Thanks [@juanrgm](https://github.com/juanrgm)! - Allow restic password without file
|
|
56
|
-
|
|
57
|
-
## 0.4.0
|
|
58
|
-
|
|
59
|
-
### Minor Changes
|
|
60
|
-
|
|
61
|
-
- [`eeb00a6`](https://github.com/swordev/datatruck/commit/eeb00a69d75c91da40711ae79475612b1d5193b6) Thanks [@juanrgm](https://github.com/juanrgm)! - Add `tempDir` config option
|
|
62
|
-
|
|
63
|
-
## 0.3.2
|
|
64
|
-
|
|
65
|
-
### Patch Changes
|
|
66
|
-
|
|
67
|
-
- [`8957c3b`](https://github.com/swordev/datatruck/commit/8957c3b5846606db8b825fef357445210f2a3ac3) Thanks [@juanrgm](https://github.com/juanrgm)! - Fix restic progress parser
|
|
68
|
-
|
|
69
|
-
* [`2989718`](https://github.com/swordev/datatruck/commit/29897185e3d6659359d51ab2212351005137f86c) Thanks [@juanrgm](https://github.com/juanrgm)! - Show closing reason
|
|
70
|
-
|
|
71
|
-
- [`b9e0843`](https://github.com/swordev/datatruck/commit/b9e0843c7970944cfd30a7d2a543f515adfa60e4) Thanks [@juanrgm](https://github.com/juanrgm)! - Show restic progress in megabytes
|
|
72
|
-
|
|
73
|
-
## 0.3.1
|
|
74
|
-
|
|
75
|
-
### Patch Changes
|
|
76
|
-
|
|
77
|
-
- [`c3bb4c6`](https://github.com/swordev/datatruck/commit/c3bb4c609887c5525cf35487ea237750addb6e75) Thanks [@juanrgm](https://github.com/juanrgm)! - Fix restic stdout parser
|
|
78
|
-
|
|
79
|
-
## 0.3.0
|
|
80
|
-
|
|
81
|
-
### Minor Changes
|
|
82
|
-
|
|
83
|
-
- [`d63fd25`](https://github.com/swordev/datatruck/commit/d63fd25ffa8d2e539d2125dfd6a3f55020086804) Thanks [@juanrgm](https://github.com/juanrgm)! - Add `snapshotDate` param
|
|
84
|
-
|
|
85
|
-
* [`486ef4a`](https://github.com/swordev/datatruck/commit/486ef4add27ae1dbfd166b16c257522f43537ecd) Thanks [@juanrgm](https://github.com/juanrgm)! - Resolve params in `include` and `exclude`
|
|
86
|
-
|
|
87
|
-
- [`617dae2`](https://github.com/swordev/datatruck/commit/617dae2c8ed90e6e65e8109f03cfad0e64bd7c02) Thanks [@juanrgm](https://github.com/juanrgm)! - Add `script` task
|
|
88
|
-
|
|
89
|
-
### Patch Changes
|
|
90
|
-
|
|
91
|
-
- [`d1b3ea9`](https://github.com/swordev/datatruck/commit/d1b3ea9c9540d30898c00490963523a4fbc68193) Thanks [@juanrgm](https://github.com/juanrgm)! - Avoid use gitignore if is not necessary in restic repository
|
|
92
|
-
|
|
93
|
-
## 0.2.0
|
|
94
|
-
|
|
95
|
-
### Minor Changes
|
|
96
|
-
|
|
97
|
-
- [`120460c`](https://github.com/swordev/datatruck/commit/120460c8824cef4184e43f571a4cc0798b899b66) Thanks [@juanrgm](https://github.com/juanrgm)! - Enable `include` option in restic repository
|
|
98
|
-
|
|
99
|
-
### Patch Changes
|
|
100
|
-
|
|
101
|
-
- [`e30ede3`](https://github.com/swordev/datatruck/commit/e30ede371bc7ab3fc1cd47758fdac7a28e8e2705) Thanks [@juanrgm](https://github.com/juanrgm)! - Resolve `RESTIC_PASSWORD_FILE` path
|
|
102
|
-
|
|
103
|
-
* [`8539d28`](https://github.com/swordev/datatruck/commit/8539d285b2c51d700aa811cd772d573fa0d613eb) Thanks [@juanrgm](https://github.com/juanrgm)! - Allow empty backup in restic repository
|
|
104
|
-
|
|
105
|
-
## 0.1.0
|
|
106
|
-
|
|
107
|
-
### Minor Changes
|
|
108
|
-
|
|
109
|
-
- [`88d46cd`](https://github.com/swordev/datatruck/commit/88d46cd56293df4c6fc21a9ad61d6236ac91f325) Thanks [@juanrgm](https://github.com/juanrgm)! - Add `custom` output format
|
|
110
|
-
|
|
111
|
-
### Patch Changes
|
|
112
|
-
|
|
113
|
-
- [`24a1e5e`](https://github.com/swordev/datatruck/commit/24a1e5e86336e7a92556287e49548dc542f0e579) Thanks [@juanrgm](https://github.com/juanrgm)! - Update dependencies
|
|
114
|
-
|
|
115
|
-
## 0.0.6
|
|
116
|
-
|
|
117
|
-
### Patch Changes
|
|
118
|
-
|
|
119
|
-
- [`8de6e6c`](https://github.com/swordev/datatruck/commit/8de6e6ceddb59635cb4634d884e7690eeaf59bac) Thanks [@juanrgm](https://github.com/juanrgm)! - Publish migrations
|
|
120
|
-
|
|
121
|
-
## 0.0.5
|
|
122
|
-
|
|
123
|
-
### Patch Changes
|
|
124
|
-
|
|
125
|
-
- [`78cb0c1`](https://github.com/swordev/datatruck/commit/78cb0c17558543841cd7080dc4c672e6cbfd5634) Thanks [@juanrgm](https://github.com/juanrgm)! - Fix docker image
|
|
126
|
-
|
|
127
|
-
## 0.0.4
|
|
128
|
-
|
|
129
|
-
### Patch Changes
|
|
130
|
-
|
|
131
|
-
- [`d9e534b`](https://github.com/swordev/datatruck/commit/d9e534bd968acf9cd1c93f20e6152c004cb1f23b) Thanks [@juanrgm](https://github.com/juanrgm)! - Fix package file read
|
|
132
|
-
|
|
133
|
-
* [`b882c58`](https://github.com/swordev/datatruck/commit/b882c58183e9a75abc876645e18d7b67186dd662) Thanks [@juanrgm](https://github.com/juanrgm)! - Fix read of migrations
|
|
134
|
-
|
|
135
|
-
## 0.0.3
|
|
136
|
-
|
|
137
|
-
### Patch Changes
|
|
138
|
-
|
|
139
|
-
- [`051a7da`](https://github.com/swordev/datatruck/commit/051a7da225fcfea1c30a4fbfa8aea1b8f5538367) Thanks [@juanrgm](https://github.com/juanrgm)! - Fix dist files
|
|
140
|
-
|
|
141
|
-
## 0.0.2
|
|
142
|
-
|
|
143
|
-
### Patch Changes
|
|
144
|
-
|
|
145
|
-
- [`0911351`](https://github.com/swordev/datatruck/commit/09113517e1a77f2d2a1e19e4c3d9af7da1e28415) Thanks [@juanrgm](https://github.com/juanrgm)! - Publish docker image
|