serverless-plugin-go 0.0.3 → 0.1.1
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/.cz.toml +1 -1
- package/CHANGELOG.md +12 -0
- package/README.md +18 -0
- package/index.js +54 -10
- package/index.test.js +153 -0
- package/package.json +1 -1
package/.cz.toml
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## v0.1.1 (2026-01-21)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
- chore: implements trusted publisher and bump node 20 -> 24 (#9)
|
|
5
|
+
|
|
6
|
+
## v0.1.0 (2025-08-12)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
- feat: build hooks (#8)
|
|
10
|
+
- * feat: add executable list of build hooks before build
|
|
11
|
+
- * fix: remove .idea folder
|
|
12
|
+
|
|
1
13
|
## v0.0.3 (2024-08-19)
|
|
2
14
|
|
|
3
15
|
|
package/README.md
CHANGED
|
@@ -62,6 +62,10 @@ custom:
|
|
|
62
62
|
env:
|
|
63
63
|
GOOS: 'linux' # Default compile OS
|
|
64
64
|
CGO_ENABLED: '0' # By default CGO is disabled
|
|
65
|
+
|
|
66
|
+
# Bash commands to execute before compilation
|
|
67
|
+
# These commands will be executed once before all compilations
|
|
68
|
+
beforeBuild: []
|
|
65
69
|
```
|
|
66
70
|
|
|
67
71
|
### How does it work?
|
|
@@ -93,6 +97,20 @@ functions:
|
|
|
93
97
|
handler: test/main.go
|
|
94
98
|
```
|
|
95
99
|
|
|
100
|
+
### How to execute commands before compilation?
|
|
101
|
+
|
|
102
|
+
You can define bash commands to be executed before any compilation action using the `beforeBuild` configuration:
|
|
103
|
+
|
|
104
|
+
```yaml
|
|
105
|
+
custom:
|
|
106
|
+
go:
|
|
107
|
+
beforeBuild:
|
|
108
|
+
- 'go generate ./...'
|
|
109
|
+
- 'go mod tidy'
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
These commands will be executed once before all compilations, not for each function individually. This applies whether you're using `serverless deploy`, `serverless deploy function`, or `serverless invoke local`.
|
|
113
|
+
|
|
96
114
|
## Caveats
|
|
97
115
|
|
|
98
116
|
This implementation doesn't allow to add any other files to the lambda artifact apart from the binary. To address this problem you should
|
package/index.js
CHANGED
|
@@ -31,6 +31,7 @@ export default class Go {
|
|
|
31
31
|
cmd: 'go build -ldflags="-s -w"',
|
|
32
32
|
monorepo: false,
|
|
33
33
|
concurrency: 5,
|
|
34
|
+
beforeBuild: [],
|
|
34
35
|
};
|
|
35
36
|
|
|
36
37
|
this.config = this.getConfig();
|
|
@@ -39,6 +40,7 @@ export default class Go {
|
|
|
39
40
|
"before:deploy:function:packageFunction": this.compileFunction.bind(this),
|
|
40
41
|
"before:package:createDeploymentArtifacts":
|
|
41
42
|
this.compileFunctions.bind(this),
|
|
43
|
+
|
|
42
44
|
// Because of https://github.com/serverless/serverless/blob/master/lib/plugins/aws/invokeLocal/index.js#L361
|
|
43
45
|
// plugin needs to compile a function and then ignore packaging.
|
|
44
46
|
"before:invoke:local:invoke": this.compileToInvoke.bind(this),
|
|
@@ -60,7 +62,7 @@ export default class Go {
|
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
/**
|
|
63
|
-
* Execute single function compilation and package.
|
|
65
|
+
* Execute a single function compilation and package.
|
|
64
66
|
*/
|
|
65
67
|
async compileFunction() {
|
|
66
68
|
const name = this.options.function;
|
|
@@ -69,6 +71,10 @@ export default class Go {
|
|
|
69
71
|
this.logInfo(`Starting compilation...`);
|
|
70
72
|
|
|
71
73
|
const timeStart = process.hrtime();
|
|
74
|
+
|
|
75
|
+
// Execute beforeBuild commands once before compilation
|
|
76
|
+
await this.execBeforeBuildCommands(this.config.baseDir, this.config.env);
|
|
77
|
+
|
|
72
78
|
await this.compile(name, func);
|
|
73
79
|
const timeEnd = process.hrtime(timeStart);
|
|
74
80
|
|
|
@@ -85,6 +91,9 @@ export default class Go {
|
|
|
85
91
|
|
|
86
92
|
const timeStart = process.hrtime();
|
|
87
93
|
|
|
94
|
+
// Execute beforeBuild commands once before all compilations
|
|
95
|
+
await this.execBeforeBuildCommands(this.config.baseDir, this.config.env);
|
|
96
|
+
|
|
88
97
|
this.logDebug(`using concurrency limit ${this.config.concurrency}...`);
|
|
89
98
|
|
|
90
99
|
const limit = plimit(this.config.concurrency);
|
|
@@ -102,8 +111,8 @@ export default class Go {
|
|
|
102
111
|
}
|
|
103
112
|
|
|
104
113
|
/**
|
|
105
|
-
* Execute single function compilation and do not create the final artifact.
|
|
106
|
-
* This is used when `invoke` command is performed.
|
|
114
|
+
* Execute a single function compilation and do not create the final artifact.
|
|
115
|
+
* This is used when the ` invoke ` command is performed.
|
|
107
116
|
*/
|
|
108
117
|
async compileToInvoke() {
|
|
109
118
|
const name = this.options.function;
|
|
@@ -112,6 +121,10 @@ export default class Go {
|
|
|
112
121
|
this.logInfo(`Starting compilation...`);
|
|
113
122
|
|
|
114
123
|
const timeStart = process.hrtime();
|
|
124
|
+
|
|
125
|
+
// Execute beforeBuild commands once before compilation
|
|
126
|
+
await this.execBeforeBuildCommands(this.config.baseDir, this.config.env);
|
|
127
|
+
|
|
115
128
|
await this.compile(name, func, false);
|
|
116
129
|
const timeEnd = process.hrtime(timeStart);
|
|
117
130
|
|
|
@@ -136,7 +149,7 @@ export default class Go {
|
|
|
136
149
|
return;
|
|
137
150
|
}
|
|
138
151
|
|
|
139
|
-
if (arch
|
|
152
|
+
if (arch === "arm64") {
|
|
140
153
|
config.env["GOARCH"] = "arm64";
|
|
141
154
|
}
|
|
142
155
|
|
|
@@ -187,6 +200,34 @@ export default class Go {
|
|
|
187
200
|
}
|
|
188
201
|
}
|
|
189
202
|
|
|
203
|
+
/**
|
|
204
|
+
* Execute bash commands from beforeBuild configuration.
|
|
205
|
+
*
|
|
206
|
+
* @param {string} cwd Working directory
|
|
207
|
+
* @param {Object} env Set of environment variables
|
|
208
|
+
*/
|
|
209
|
+
async execBeforeBuildCommands(cwd, env) {
|
|
210
|
+
if (!this.config.beforeBuild || !this.config.beforeBuild.length) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const execOpts = { cwd: cwd, env: { ...process.env, ...env } };
|
|
215
|
+
|
|
216
|
+
for (const cmd of this.config.beforeBuild) {
|
|
217
|
+
this.logDebug(`Executing beforeBuild command: ${cmd}`);
|
|
218
|
+
try {
|
|
219
|
+
await this.exec(cmd, execOpts);
|
|
220
|
+
} catch (e) {
|
|
221
|
+
this.logError(
|
|
222
|
+
`Error executing beforeBuild command (cwd: ${cwd}): ${e.message}`,
|
|
223
|
+
);
|
|
224
|
+
throw new Error(
|
|
225
|
+
`error executing beforeBuild command '${cmd}' (cwd: ${cwd})`,
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
190
231
|
/**
|
|
191
232
|
* Execute compilation command from collected configuration.
|
|
192
233
|
*
|
|
@@ -212,11 +253,11 @@ export default class Go {
|
|
|
212
253
|
}
|
|
213
254
|
|
|
214
255
|
/**
|
|
215
|
-
*
|
|
256
|
+
* Packages a bootstrap file into a zip archive and updates the service function's package configuration.
|
|
216
257
|
*
|
|
217
|
-
* @param {string} name
|
|
218
|
-
* @param {
|
|
219
|
-
* @
|
|
258
|
+
* @param {string} name - The name of the serverless function to update the package for.
|
|
259
|
+
* @param {string} binPath - The path to the bootstrap binary file.
|
|
260
|
+
* @return {void} This method does not return any value.
|
|
220
261
|
*/
|
|
221
262
|
packageBootstrap(name, binPath) {
|
|
222
263
|
this.zip.addFile("bootstrap", this.readFileSync(binPath), "", 0o755);
|
|
@@ -231,8 +272,11 @@ export default class Go {
|
|
|
231
272
|
}
|
|
232
273
|
|
|
233
274
|
/**
|
|
234
|
-
*
|
|
235
|
-
*
|
|
275
|
+
* Retrieves and consolidates the configuration by merging the default configuration
|
|
276
|
+
* with user-defined custom configurations and environment variables.
|
|
277
|
+
*
|
|
278
|
+
* @return {Object} The final configuration object containing merged settings,
|
|
279
|
+
* environment variables as strings, and concurrency settings.
|
|
236
280
|
*/
|
|
237
281
|
getConfig() {
|
|
238
282
|
let config = { ...this.defaultConfig };
|
package/index.test.js
CHANGED
|
@@ -400,4 +400,157 @@ describe("Go Plugin", () => {
|
|
|
400
400
|
|
|
401
401
|
delete process.env["SP_GO_CONCURRENCY"];
|
|
402
402
|
});
|
|
403
|
+
|
|
404
|
+
it("Should execute beforeBuild commands once before all compilations", async () => {
|
|
405
|
+
config.service
|
|
406
|
+
.setCustom({
|
|
407
|
+
go: {
|
|
408
|
+
beforeBuild: ["echo 'before build command'", "go mod tidy"],
|
|
409
|
+
},
|
|
410
|
+
})
|
|
411
|
+
.setFunctions({
|
|
412
|
+
testFunc1: {
|
|
413
|
+
name: "testFunc1",
|
|
414
|
+
runtime: "provided.al2",
|
|
415
|
+
handler: "functions/func1/main.go",
|
|
416
|
+
},
|
|
417
|
+
testFunc2: {
|
|
418
|
+
name: "testFunc2",
|
|
419
|
+
runtime: "provided.al2",
|
|
420
|
+
handler: "functions/func2/main.go",
|
|
421
|
+
},
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
const plugin = new Go(config);
|
|
425
|
+
plugin.exec = execStub;
|
|
426
|
+
plugin.readFileSync = readFileSyncStub;
|
|
427
|
+
plugin.zip = admZipStub;
|
|
428
|
+
|
|
429
|
+
// when
|
|
430
|
+
await plugin.compileFunctions();
|
|
431
|
+
|
|
432
|
+
// then
|
|
433
|
+
// Verify beforeBuild commands were executed once
|
|
434
|
+
expect(execStub).to.have.been.calledWith("echo 'before build command'", {
|
|
435
|
+
cwd: ".",
|
|
436
|
+
env: { ...process.env, ...{ CGO_ENABLED: "0", GOOS: "linux" } },
|
|
437
|
+
});
|
|
438
|
+
expect(execStub).to.have.been.calledWith("go mod tidy", {
|
|
439
|
+
cwd: ".",
|
|
440
|
+
env: { ...process.env, ...{ CGO_ENABLED: "0", GOOS: "linux" } },
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
// Verify compilation commands were executed for each function
|
|
444
|
+
expect(execStub).to.have.been.calledWith(
|
|
445
|
+
`go build -ldflags="-s -w" -o .bin/testFunc1 functions/func1/main.go`,
|
|
446
|
+
{
|
|
447
|
+
cwd: ".",
|
|
448
|
+
env: { ...process.env, ...{ CGO_ENABLED: "0", GOOS: "linux" } },
|
|
449
|
+
},
|
|
450
|
+
);
|
|
451
|
+
expect(execStub).to.have.been.calledWith(
|
|
452
|
+
`go build -ldflags="-s -w" -o .bin/testFunc2 functions/func2/main.go`,
|
|
453
|
+
{
|
|
454
|
+
cwd: ".",
|
|
455
|
+
env: { ...process.env, ...{ CGO_ENABLED: "0", GOOS: "linux" } },
|
|
456
|
+
},
|
|
457
|
+
);
|
|
458
|
+
|
|
459
|
+
// Total calls should be 4: 2 beforeBuild commands + 2 compilation commands
|
|
460
|
+
expect(execStub.callCount).to.equal(4);
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
it("Should execute beforeBuild commands once for compileFunction", async () => {
|
|
464
|
+
config.service
|
|
465
|
+
.setCustom({
|
|
466
|
+
go: {
|
|
467
|
+
beforeBuild: ["echo 'before build command'", "go mod tidy"],
|
|
468
|
+
},
|
|
469
|
+
})
|
|
470
|
+
.setFunctions({
|
|
471
|
+
testFunc1: {
|
|
472
|
+
name: "testFunc1",
|
|
473
|
+
runtime: "provided.al2",
|
|
474
|
+
handler: "functions/func1/main.go",
|
|
475
|
+
},
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
const plugin = new Go(config, { function: "testFunc1" });
|
|
479
|
+
plugin.exec = execStub;
|
|
480
|
+
plugin.readFileSync = readFileSyncStub;
|
|
481
|
+
plugin.zip = admZipStub;
|
|
482
|
+
|
|
483
|
+
// when
|
|
484
|
+
await plugin.compileFunction();
|
|
485
|
+
|
|
486
|
+
// then
|
|
487
|
+
// Verify beforeBuild commands were executed once
|
|
488
|
+
expect(execStub).to.have.been.calledWith("echo 'before build command'", {
|
|
489
|
+
cwd: ".",
|
|
490
|
+
env: { ...process.env, ...{ CGO_ENABLED: "0", GOOS: "linux" } },
|
|
491
|
+
});
|
|
492
|
+
expect(execStub).to.have.been.calledWith("go mod tidy", {
|
|
493
|
+
cwd: ".",
|
|
494
|
+
env: { ...process.env, ...{ CGO_ENABLED: "0", GOOS: "linux" } },
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
// Verify the compilation command was executed
|
|
498
|
+
expect(execStub).to.have.been.calledWith(
|
|
499
|
+
`go build -ldflags="-s -w" -o .bin/testFunc1 functions/func1/main.go`,
|
|
500
|
+
{
|
|
501
|
+
cwd: ".",
|
|
502
|
+
env: { ...process.env, ...{ CGO_ENABLED: "0", GOOS: "linux" } },
|
|
503
|
+
},
|
|
504
|
+
);
|
|
505
|
+
|
|
506
|
+
// Total calls should be 3: 2 beforeBuild commands + 1 compilation command
|
|
507
|
+
expect(execStub.callCount).to.equal(3);
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
it("Should execute beforeBuild commands once for compileToInvoke", async () => {
|
|
511
|
+
config.service
|
|
512
|
+
.setCustom({
|
|
513
|
+
go: {
|
|
514
|
+
beforeBuild: ["echo 'before build command'", "go mod tidy"],
|
|
515
|
+
},
|
|
516
|
+
})
|
|
517
|
+
.setFunctions({
|
|
518
|
+
testFunc1: {
|
|
519
|
+
name: "testFunc1",
|
|
520
|
+
runtime: "provided.al2",
|
|
521
|
+
handler: "functions/func1/main.go",
|
|
522
|
+
},
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
const plugin = new Go(config, { function: "testFunc1" });
|
|
526
|
+
plugin.exec = execStub;
|
|
527
|
+
plugin.readFileSync = readFileSyncStub;
|
|
528
|
+
plugin.zip = admZipStub;
|
|
529
|
+
|
|
530
|
+
// when
|
|
531
|
+
await plugin.compileToInvoke();
|
|
532
|
+
|
|
533
|
+
// then
|
|
534
|
+
// Verify beforeBuild commands were executed once
|
|
535
|
+
expect(execStub).to.have.been.calledWith("echo 'before build command'", {
|
|
536
|
+
cwd: ".",
|
|
537
|
+
env: { ...process.env, ...{ CGO_ENABLED: "0", GOOS: "linux" } },
|
|
538
|
+
});
|
|
539
|
+
expect(execStub).to.have.been.calledWith("go mod tidy", {
|
|
540
|
+
cwd: ".",
|
|
541
|
+
env: { ...process.env, ...{ CGO_ENABLED: "0", GOOS: "linux" } },
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
// Verify compilation command was executed
|
|
545
|
+
expect(execStub).to.have.been.calledWith(
|
|
546
|
+
`go build -ldflags="-s -w" -o .bin/testFunc1 functions/func1/main.go`,
|
|
547
|
+
{
|
|
548
|
+
cwd: ".",
|
|
549
|
+
env: { ...process.env, ...{ CGO_ENABLED: "0", GOOS: "linux" } },
|
|
550
|
+
},
|
|
551
|
+
);
|
|
552
|
+
|
|
553
|
+
// Total calls should be 3: 2 beforeBuild commands + 1 compilation command
|
|
554
|
+
expect(execStub.callCount).to.equal(3);
|
|
555
|
+
});
|
|
403
556
|
});
|