@dotenvx/dotenvx 1.61.3 → 1.61.5
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 +13 -1
- package/README.md +17 -11
- package/package.json +1 -1
- package/src/cli/dotenvx.js +1 -0
- package/src/lib/helpers/executeCommand.js +79 -15
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
-
[Unreleased](https://github.com/dotenvx/dotenvx/compare/v1.61.
|
|
5
|
+
[Unreleased](https://github.com/dotenvx/dotenvx/compare/v1.61.5...main)
|
|
6
|
+
|
|
7
|
+
## [1.61.5](https://github.com/dotenvx/dotenvx/compare/v1.61.4...v1.61.5) (2026-04-22)
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
* Support `--hostname` flag to `dotenvx-ops.login` ([#801](https://github.com/dotenvx/dotenvx/pull/801))
|
|
12
|
+
|
|
13
|
+
## [1.61.4](https://github.com/dotenvx/dotenvx/compare/v1.61.3...v1.61.4) (2026-04-21)
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
* Respect SIGINT handler completion ([#798](https://github.com/dotenvx/dotenvx/pull/798))
|
|
6
18
|
|
|
7
19
|
## [1.61.3](https://github.com/dotenvx/dotenvx/compare/v1.61.2...v1.61.3) (2026-04-21)
|
|
8
20
|
|
package/README.md
CHANGED
|
@@ -349,11 +349,11 @@ $ docker run -it --rm -v $(pwd):/app dotenv/dotenvx run -- node index.js
|
|
|
349
349
|
|
|
350
350
|
Or in any image:
|
|
351
351
|
|
|
352
|
-
```
|
|
352
|
+
```Containerfile
|
|
353
353
|
FROM node:latest
|
|
354
354
|
RUN echo "HELLO=Dotenvx" > .env && echo "console.log('Hello ' + process.env.HELLO)" > index.js
|
|
355
355
|
RUN curl -fsS https://dotenvx.sh/install.sh | sh
|
|
356
|
-
CMD ["dotenvx", "run", "--", "echo", "Hello $HELLO"]
|
|
356
|
+
CMD ["/usr/local/bin/dotenvx", "run", "--", "echo", "Hello $HELLO"]
|
|
357
357
|
```
|
|
358
358
|
|
|
359
359
|
see [docker guide](https://dotenvx.com/docs/platforms/docker)
|
|
@@ -388,7 +388,7 @@ see [github actions guide](https://dotenvx.com/docs/cis/github-actions)
|
|
|
388
388
|
heroku buildpacks:add https://github.com/dotenvx/heroku-buildpack-dotenvx
|
|
389
389
|
|
|
390
390
|
# docker
|
|
391
|
-
RUN curl -fsS https://dotenvx.sh
|
|
391
|
+
RUN curl -fsS https://dotenvx.sh | sh
|
|
392
392
|
|
|
393
393
|
# vercel
|
|
394
394
|
npm install @dotenvx/dotenvx --save
|
|
@@ -2251,14 +2251,17 @@ Prevent `.env` files from being built into your docker containers.
|
|
|
2251
2251
|
|
|
2252
2252
|
Add it to your `Dockerfile`.
|
|
2253
2253
|
|
|
2254
|
-
```
|
|
2255
|
-
#
|
|
2254
|
+
```Containerfile
|
|
2255
|
+
# Install via script
|
|
2256
2256
|
RUN curl -fsS https://dotenvx.sh | sh
|
|
2257
2257
|
|
|
2258
|
-
|
|
2258
|
+
# Or copy binary from official image
|
|
2259
|
+
COPY --from=dotenv/dotenvx:latest /usr/local/bin/dotenvx /bin/local/bin
|
|
2260
|
+
|
|
2261
|
+
# ... orther container commands
|
|
2259
2262
|
|
|
2260
2263
|
RUN dotenvx ext prebuild
|
|
2261
|
-
CMD ["dotenvx", "run", "--", "node", "index.js"]
|
|
2264
|
+
CMD ["/usr/local/bin/dotenvx", "run", "--", "node", "index.js"]
|
|
2262
2265
|
```
|
|
2263
2266
|
|
|
2264
2267
|
</details>
|
|
@@ -2268,14 +2271,17 @@ Prevent `.env` files from being built into your docker containers inside a speci
|
|
|
2268
2271
|
|
|
2269
2272
|
Add it to your `Dockerfile`.
|
|
2270
2273
|
|
|
2271
|
-
```
|
|
2272
|
-
#
|
|
2274
|
+
```Containerfile
|
|
2275
|
+
# Install via script
|
|
2273
2276
|
RUN curl -fsS https://dotenvx.sh | sh
|
|
2274
2277
|
|
|
2275
|
-
|
|
2278
|
+
# Or copy binary from official image
|
|
2279
|
+
COPY --from=dotenv/dotenvx:latest /usr/local/bin/dotenvx /bin/local/bin
|
|
2280
|
+
|
|
2281
|
+
# ... orther container commands
|
|
2276
2282
|
|
|
2277
2283
|
RUN dotenvx ext prebuild apps/backend
|
|
2278
|
-
CMD ["dotenvx", "run", "--", "node", "apps/backend/index.js"]
|
|
2284
|
+
CMD ["/usr/local/bin/dotenvx", "run", "--", "node", "apps/backend/index.js"]
|
|
2279
2285
|
```
|
|
2280
2286
|
|
|
2281
2287
|
</details>
|
package/package.json
CHANGED
package/src/cli/dotenvx.js
CHANGED
|
@@ -189,6 +189,7 @@ program.command('ls')
|
|
|
189
189
|
// dotenvx login
|
|
190
190
|
program.command('login')
|
|
191
191
|
.description('log in to unlock ⛨ ARMORED KEYS ✦ BETA')
|
|
192
|
+
.allowUnknownOption()
|
|
192
193
|
.action(() => {
|
|
193
194
|
const rawArgs = ['ops', 'login', ...process.argv.slice(3)]
|
|
194
195
|
executeDynamic(program, 'ops', rawArgs)
|
|
@@ -5,6 +5,8 @@ const { logger } = require('./../../shared/logger')
|
|
|
5
5
|
const Errors = require('./errors')
|
|
6
6
|
|
|
7
7
|
async function executeCommand (commandArgs, env) {
|
|
8
|
+
const FORWARD_SIGNAL_GRACE_MS = 1000
|
|
9
|
+
const FORCE_KILL_GRACE_MS = 1000
|
|
8
10
|
const signals = [
|
|
9
11
|
'SIGHUP', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT',
|
|
10
12
|
'SIGBUS', 'SIGFPE', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2'
|
|
@@ -14,6 +16,51 @@ async function executeCommand (commandArgs, env) {
|
|
|
14
16
|
|
|
15
17
|
let child
|
|
16
18
|
let signalSent
|
|
19
|
+
let sigintCount = 0
|
|
20
|
+
const signalForwardTimers = new Set()
|
|
21
|
+
const otherSignalHandlers = new Map()
|
|
22
|
+
const isInteractiveTTY = Boolean(process.stdin && process.stdin.isTTY)
|
|
23
|
+
|
|
24
|
+
const isChildRunning = () => {
|
|
25
|
+
return child && child.exitCode === null && child.signalCode === null
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const queueSignalForward = (signal) => {
|
|
29
|
+
logger.debug(`queueing ${signal} to command process after ${FORWARD_SIGNAL_GRACE_MS}ms`)
|
|
30
|
+
const timer = setTimeout(() => {
|
|
31
|
+
signalForwardTimers.delete(timer)
|
|
32
|
+
|
|
33
|
+
if (!isChildRunning()) {
|
|
34
|
+
logger.debug(`skipping ${signal} forward because command process is already exiting`)
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
logger.debug(`sending ${signal} to command process`)
|
|
39
|
+
signalSent = signal
|
|
40
|
+
child.kill(signal)
|
|
41
|
+
}, FORWARD_SIGNAL_GRACE_MS)
|
|
42
|
+
|
|
43
|
+
if (typeof timer.unref === 'function') timer.unref()
|
|
44
|
+
signalForwardTimers.add(timer)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const queueForceKill = () => {
|
|
48
|
+
logger.debug(`queueing SIGKILL to command process after ${FORCE_KILL_GRACE_MS}ms`)
|
|
49
|
+
const timer = setTimeout(() => {
|
|
50
|
+
signalForwardTimers.delete(timer)
|
|
51
|
+
|
|
52
|
+
if (!isChildRunning()) {
|
|
53
|
+
logger.debug('skipping SIGKILL because command process is already exiting')
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
logger.debug('sending SIGKILL to command process')
|
|
58
|
+
child.kill('SIGKILL')
|
|
59
|
+
}, FORCE_KILL_GRACE_MS)
|
|
60
|
+
|
|
61
|
+
if (typeof timer.unref === 'function') timer.unref()
|
|
62
|
+
signalForwardTimers.add(timer)
|
|
63
|
+
}
|
|
17
64
|
|
|
18
65
|
/* c8 ignore start */
|
|
19
66
|
const sigintHandler = () => {
|
|
@@ -21,13 +68,25 @@ async function executeCommand (commandArgs, env) {
|
|
|
21
68
|
logger.debug('checking command process')
|
|
22
69
|
logger.debug(child)
|
|
23
70
|
|
|
24
|
-
if (child)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
71
|
+
if (!child) return
|
|
72
|
+
|
|
73
|
+
sigintCount += 1
|
|
74
|
+
|
|
75
|
+
if (isInteractiveTTY) {
|
|
76
|
+
if (sigintCount === 1) {
|
|
77
|
+
logger.debug('TTY mode: not forwarding first SIGINT to command process')
|
|
78
|
+
return
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
logger.debug('TTY mode: forwarding SIGTERM on second SIGINT to command process')
|
|
82
|
+
signalSent = 'SIGTERM'
|
|
83
|
+
child.kill('SIGTERM')
|
|
84
|
+
|
|
85
|
+
if (sigintCount === 2) queueForceKill()
|
|
86
|
+
return
|
|
30
87
|
}
|
|
88
|
+
|
|
89
|
+
queueSignalForward('SIGINT')
|
|
31
90
|
}
|
|
32
91
|
|
|
33
92
|
const sigtermHandler = () => {
|
|
@@ -35,18 +94,14 @@ async function executeCommand (commandArgs, env) {
|
|
|
35
94
|
logger.debug('checking command process')
|
|
36
95
|
logger.debug(child)
|
|
37
96
|
|
|
38
|
-
if (child)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
child.kill('SIGTERM') // Send SIGTERM to the command process
|
|
42
|
-
} else {
|
|
43
|
-
logger.debug('no command process to send SIGTERM to')
|
|
44
|
-
}
|
|
97
|
+
if (!child) return
|
|
98
|
+
|
|
99
|
+
queueSignalForward('SIGTERM')
|
|
45
100
|
}
|
|
46
101
|
|
|
47
102
|
const handleOtherSignal = (signal) => {
|
|
48
103
|
logger.debug(`received ${signal}`)
|
|
49
|
-
child.kill(signal)
|
|
104
|
+
if (child) child.kill(signal)
|
|
50
105
|
}
|
|
51
106
|
/* c8 ignore stop */
|
|
52
107
|
|
|
@@ -84,7 +139,9 @@ async function executeCommand (commandArgs, env) {
|
|
|
84
139
|
process.on('SIGTERM', sigtermHandler)
|
|
85
140
|
|
|
86
141
|
signals.forEach(signal => {
|
|
87
|
-
|
|
142
|
+
const handler = () => handleOtherSignal(signal)
|
|
143
|
+
otherSignalHandlers.set(signal, handler)
|
|
144
|
+
process.on(signal, handler)
|
|
88
145
|
})
|
|
89
146
|
|
|
90
147
|
// Wait for the command process to finish
|
|
@@ -107,10 +164,17 @@ async function executeCommand (commandArgs, env) {
|
|
|
107
164
|
// Exit with the error code from the command process, or 1 if unavailable
|
|
108
165
|
process.exit(error.exitCode || 1)
|
|
109
166
|
} finally {
|
|
167
|
+
signalForwardTimers.forEach(timer => clearTimeout(timer))
|
|
168
|
+
signalForwardTimers.clear()
|
|
169
|
+
|
|
110
170
|
// Clean up: Remove the SIGINT handler
|
|
111
171
|
process.removeListener('SIGINT', sigintHandler)
|
|
112
172
|
// Clean up: Remove the SIGTERM handler
|
|
113
173
|
process.removeListener('SIGTERM', sigtermHandler)
|
|
174
|
+
|
|
175
|
+
otherSignalHandlers.forEach((handler, signal) => {
|
|
176
|
+
process.removeListener(signal, handler)
|
|
177
|
+
})
|
|
114
178
|
}
|
|
115
179
|
}
|
|
116
180
|
|