Compare commits

...

74 Commits

Author SHA1 Message Date
eed4a385a9 wip 2024-02-21 16:38:14 -03:00
9e4dd3fce2 v18.0.0 2024-02-06 12:19:41 +00:00
b2590136fc Merge pull request #2720 from balena-io/bump-node-20
Update to Node 20
2024-02-06 12:18:34 +00:00
bf5e61a61c Update to Node 20
Change-type: major
2024-02-05 18:29:02 -03:00
f550d0c596 v17.5.1 2024-01-31 01:05:23 +00:00
54302669b8 Merge pull request #2725 from balena-io/livepush-fix
Fix target state construction with livepush
2024-01-30 20:04:28 -05:00
a4a4e33d7b Dedupe dependencies 2024-01-30 11:17:21 -03:00
8d6a621bfb Fix target state construction with livepush
When constructing the target state after a reported change from livepush, the
handler function would not pass all build tasks to the function that
constructs the target state, causing a TypeError when trying to obtain
the target image name for each service. This updates the handler to pass
all build tasks, ensuring the information is available to construct the
target state.

Relates-to: #2724
Change-type: patch
2024-01-30 11:03:37 -03:00
4b2602676b v17.5.0 2024-01-23 15:52:54 +00:00
b0810c0f85 Merge pull request #2722 from balena-io/draft-hup
device os-update: Enable updates to pre-release versions of higher base semver
2024-01-23 17:51:54 +02:00
97a6013537 Deduplicate dependencies 2024-01-23 16:55:36 +02:00
1ba8db1459 os versions: Add the --include-draft option
Change-type: minor
2024-01-23 16:55:36 +02:00
cdada0aec8 device os-update: Add option for including pre-release versions in the list
Change-type: minor
2024-01-23 16:55:36 +02:00
1166533482 device os-update: Enable updates to pre-release versions of higher base semver
Change-type: minor
Depends-on: https://github.com/balena-io/balena-sdk/pull/1398
See: https://balena.fibery.io/Work/Task/cli-Enable-OS-Updates-to-pre-release-OS-versions-1751
2024-01-23 16:55:36 +02:00
01538728cd Update balena-sdk to 19.4.0
Update balena-sdk from 19.0.1 to 19.4.0

Change-type: minor
2024-01-23 16:55:36 +02:00
3a7f6d78b0 v17.4.12 2024-01-18 10:55:53 +00:00
dce48c90e9 Merge pull request #2719 from balena-io/revert_dockerode
Revert upgrade to dockerode to avoid regression
2024-01-18 05:54:22 -05:00
fe70d164c1 Deduplicate dependencies 2024-01-15 22:38:12 +00:00
09e2550b32 Regression described in GitHub Issue 2715; balena push hangs in
local mode.

Change-type: patch
Signed-off-by: Ken Bannister <kb2ma@runbox.com>
2024-01-15 22:05:05 +00:00
07854c3d42 v17.4.11 2024-01-05 23:01:11 +00:00
858a455501 Merge pull request #2717 from balena-io/update-oclif-patch
Mark the oclif package patch as a dev only one
2024-01-05 23:00:17 +00:00
4e5eb4bcee Exclude the oclif package patch from the published files
Change-type: patch
2024-01-06 00:25:56 +02:00
696bad3ed6 Update the @oclif/core patch
Change-type: patch
2024-01-06 00:25:34 +02:00
9a9d0f02ef Deduplicate dependencies 2024-01-06 00:25:34 +02:00
f46d00640b v17.4.10 2024-01-02 12:41:44 +00:00
e369bd3599 Merge pull request #2716 from balena-io/normalize-v-version-prefix
Normalize v prefixes in the --version parameter of all commands
2024-01-02 14:40:45 +02:00
75b29112a7 Deduplicate dependencies 2024-01-02 13:55:40 +02:00
b7b01ecd53 Normalize v prefixes in the --version parameter of all commands
Change-type: patch
2024-01-02 13:33:38 +02:00
801a25995c v17.4.9 2023-12-19 23:02:33 +00:00
8296dea78c Merge pull request #2713 from balena-io/fix-ci
Fix publishing artifacts to gh release
2023-12-19 23:01:35 +00:00
1da5a75c14 Fix publishing artifacts to gh release
Change-type: patch
2023-12-19 19:10:06 -03:00
166de57179 v17.4.8 2023-12-19 21:59:10 +00:00
85dece9e95 Merge pull request #2714 from balena-io/kyle/patch
Remove repo config from flowzone.yml
2023-12-19 21:58:24 +00:00
bfbc71215c Remove repo config from flowzone.yml
This functionality is being deprecated in Flowzone.

See: https://github.com/product-os/flowzone/pull/833

Change-type: patch
Signed-off-by: Kyle Harding <kyle@balena.io>
2023-12-19 15:20:04 -05:00
d243c14d74 v17.4.7 2023-12-19 14:26:31 +00:00
804eb27551 Merge pull request #2712 from balena-io/add-request-rerties-to-balena-deploy
deploy: Add rate-limiting aware retries for failed requests
2023-12-19 14:25:32 +00:00
4266dc6951 deploy: Add rate-limiting aware retries for failed requests
Change-type: patch
2023-12-19 01:16:42 +02:00
0ba3522584 Update dependencies
Update @balena/compose from 3.0.5 to 3.2.0

Also updates pinejs-client-request to support
using the Retry-After header and dockerode
to 3.3.5 to be aligned with @balena/compose.

Change-type: patch
2023-12-19 01:16:42 +02:00
19b0e9489d Deduplicate node modules 2023-12-19 01:16:42 +02:00
d9fed9c34c v17.4.6 2023-12-08 15:55:53 +00:00
81ee9f397f Merge pull request #2711 from balena-io/bump-oclif-core
Bump oclif core & use default missing flag handler
2023-12-08 15:54:47 +00:00
b9722c6796 Bump oclif core & use default missing flag handler
Change-type: patch
2023-12-08 12:06:54 -03:00
29ade0f696 v17.4.5 2023-12-04 14:08:31 +00:00
d5ae612513 Merge pull request #2707 from balena-io/bump-ts
Update TypeScript to 5.3.2
2023-12-04 14:07:30 +00:00
65ba63d1a8 Stop testing dependency deduplication on the custom test runners
That's since we already run that test as part of
flowzone's default "Test npm (18.x)", and the
custom tests are using the latest node & npm
version of the selected major.

Change-type: patch
2023-12-04 15:39:10 +02:00
f5ffa7d84f Temporarily pin oclif-core to ~3.11.0 to deduplicate the dependencies
Change-type: patch
2023-12-04 15:36:43 +02:00
dac3ace61d Update TypeScript to 5.3.2
Change-type: patch
2023-11-30 00:07:17 +02:00
72459a04d1 v17.4.4 2023-11-20 17:57:23 +00:00
1e83fcf1e3 Merge pull request #2706 from balena-io/fix-balena-block-create
Fix balena block create to actually create a block
2023-11-20 17:56:32 +00:00
b8769bb9e9 Fix balena block create to actually create a block
Change-type: patch
2023-11-20 13:33:35 -03:00
9f52ee8b21 v17.4.3 2023-11-17 15:39:24 +00:00
90b65cd06b Merge pull request #2683 from balena-io/bump-oclif-core-to-v3
Bump oclif-core to v3
2023-11-17 15:38:25 +00:00
72a924f00e Bump oclif-core to v3
Change-type: patch
2023-11-16 15:06:24 -03:00
e4624eda10 v17.4.2 2023-11-15 11:02:24 +00:00
4173cd82e6 Merge pull request #2697 from balena-io/vipul/automate-capitan
Automatically generate Capitano Docs configuration
2023-11-15 11:01:38 +00:00
b393f27e1b Remove authentication directory
Signed-off-by: Vipul Gupta (@vipulgupta2048) <vipulgupta2048@gmail.com>
2023-11-15 15:55:03 +05:30
1a4a0e2439 Move auth commands into command directories
Signed-off-by: Vipul Gupta (@vipulgupta2048) <vipulgupta2048@gmail.com>
2023-11-15 15:10:22 +05:30
4cd8f4c16e Docs: Generate balena auto-completion
Signed-off-by: Vipul Gupta (@vipulgupta2048) <vipulgupta2048@gmail.com>
2023-11-15 13:08:08 +05:30
2de9d526e5 Docs: Move commands to their own directories, away from their categories
Signed-off-by: Vipul Gupta (@vipulgupta2048) <vipulgupta2048@gmail.com>
2023-11-15 13:07:34 +05:30
d9427c3c59 Docs: Generate balenaCLI with automatic configuration
Signed-off-by: Vipul Gupta (@vipulgupta2048) <vipulgupta2048@gmail.com>
2023-11-15 13:07:01 +05:30
fc0cfac475 Docs: Create version command directory
Signed-off-by: Vipul Gupta (@vipulgupta2048) <vipulgupta2048@gmail.com>
2023-11-15 13:06:45 +05:30
99094dbfda Throw error if command directory rules not followed
Signed-off-by: Vipul Gupta (@vipulgupta2048) <vipulgupta2048@gmail.com>
2023-11-15 13:06:35 +05:30
0711eefb7c Update all imports to match new command directory structure
Signed-off-by: Vipul Gupta (@vipulgupta2048) <vipulgupta2048@gmail.com>
2023-11-15 13:06:19 +05:30
dc40b0d969 Docs: Move CLI commands files to command directories
Signed-off-by: Vipul Gupta (@vipulgupta2048) <vipulgupta2048@gmail.com>
2023-11-15 13:05:58 +05:30
4b5def0a8a Docs: Automatically generate Capitano configuration
Change-type: patch
Signed-off-by: Vipul Gupta (@vipulgupta2048) <vipulgupta2048@gmail.com>
2023-11-15 13:05:39 +05:30
f44fa38113 v17.4.1 2023-11-13 19:18:47 +00:00
167dfeb269 Merge pull request #2701 from balena-io/bump-shrinkwrap
Bump shrinkwrap
2023-11-13 19:17:53 +00:00
a816548bb5 Bump shrinkwrap
Change-type: patch
2023-11-13 15:43:13 -03:00
94001efc81 v17.4.0 2023-11-10 16:28:02 +00:00
8bfafe8ecc Merge pull request #2692 from bbugh/device-json
device: Add `--json` option for JSON output
2023-11-10 13:26:59 -03:00
d78045b6ab device: Add --json option for JSON output
change-type: minor
2023-11-10 12:10:53 -03:00
11eabc4b96 v17.3.2 2023-11-10 11:03:00 +00:00
bfaa91c752 Merge pull request #2700 from balena-io/update-@balena/compose-3.0.5
Update @balena/compose to 3.0.5
2023-11-10 13:02:02 +02:00
1b615e4690 Update @balena/compose to 3.0.5
Update @balena/compose from 3.0.2 to 3.0.5

Change-type: patch
2023-11-10 11:05:42 +02:00
72 changed files with 6456 additions and 3283 deletions

View File

@ -18,7 +18,7 @@ inputs:
default: 'accounts+apple@balena.io'
NODE_VERSION:
type: string
default: '18.x'
default: '20.x'
VERBOSE:
type: string
default: 'true'
@ -28,7 +28,7 @@ runs:
using: 'composite'
steps:
- name: Download custom source artifact
uses: actions/download-artifact@v3
uses: actions/download-artifact@f44cd7b40bfd40b6aa1cc1b9b5b7bf03d3c67110 # v4.1.0
with:
name: custom-${{ github.event.pull_request.head.sha || github.event.head_commit.id }}-${{ runner.os }}-${{ runner.arch }}
path: ${{ runner.temp }}
@ -127,8 +127,9 @@ runs:
XCODE_APP_LOADER_TEAM_ID: ${{ inputs.XCODE_APP_LOADER_TEAM_ID }}
- name: Upload artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # v4
with:
name: gh-release-${{ github.event.pull_request.head.sha || github.event.head_commit.id }}
name: gh-release-${{ github.event.pull_request.head.sha || github.event.head_commit.id }}-${{ strategy.job-index }}
path: dist
retention-days: 1
if-no-files-found: error

View File

@ -15,7 +15,7 @@ inputs:
# --- custom environment
NODE_VERSION:
type: string
default: '18.x'
default: '20.x'
VERBOSE:
type: string
default: "true"
@ -51,14 +51,14 @@ runs:
fi
npm run build
npm run test
npm run test:core
- name: Compress custom source
shell: pwsh
run: tar --exclude-vcs -acf ${{ runner.temp }}/custom.tgz .
- name: Upload custom artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # v4
with:
name: custom-${{ github.event.pull_request.head.sha || github.event.head_commit.id }}-${{ runner.os }}-${{ runner.arch }}
path: ${{ runner.temp }}/custom.tgz

View File

@ -1,5 +1,4 @@
name: Flowzone
on:
pull_request:
types: [opened, synchronize, closed]
@ -7,7 +6,6 @@ on:
pull_request_target:
types: [opened, synchronize, closed]
branches: [main, master]
jobs:
flowzone:
name: Flowzone
@ -24,7 +22,5 @@ jobs:
secrets: inherit
with:
custom_runs_on: '[["self-hosted","Linux","distro:focal","X64"],["self-hosted","Linux","distro:focal","ARM64"],["macos-12"],["windows-2019"]]'
repo_config: true
repo_description: "The official balena CLI tool."
github_prerelease: false
restrict_custom_actions: false

View File

@ -1,3 +1,691 @@
- commits:
- subject: Update to Node 20
hash: bf5e61a61c542f0c0a57ae49bb9a9998588d6851
body: ""
footer:
Change-type: major
change-type: major
author: Otávio Jacobi
nested: []
version: 18.0.0
title: ""
date: 2024-02-06T12:19:35.139Z
- commits:
- subject: Fix target state construction with livepush
hash: 8d6a621bfb62147ed0a88f58057e38211e82f841
body: >
When constructing the target state after a reported change from
livepush, the
handler function would not pass all build tasks to the function that
constructs the target state, causing a TypeError when trying to obtain
the target image name for each service. This updates the handler to pass
all build tasks, ensuring the information is available to construct the
target state.
footer:
Relates-to: "#2724"
relates-to: "#2724"
Change-type: patch
change-type: patch
author: Felipe Lalanne
nested: []
version: 17.5.1
title: ""
date: 2024-01-31T01:05:17.796Z
- commits:
- subject: "os versions: Add the --include-draft option"
hash: 1ba8db1459355f6a5887f9106876318bd81f7f02
body: ""
footer:
Change-type: minor
change-type: minor
author: Thodoris Greasidis
nested: []
- subject: "device os-update: Add option for including pre-release versions in the
list"
hash: cdada0aec8e8f7a6c72d629dfa7a36f5d56b1b0d
body: ""
footer:
Change-type: minor
change-type: minor
author: Thodoris Greasidis
nested: []
- subject: "device os-update: Enable updates to pre-release versions of higher
base semver"
hash: 116653348219f9ce8fd896428d690940350f2597
body: ""
footer:
Change-type: minor
change-type: minor
Depends-on: https://github.com/balena-io/balena-sdk/pull/1398
depends-on: https://github.com/balena-io/balena-sdk/pull/1398
See: https://balena.fibery.io/Work/Task/cli-Enable-OS-Updates-to-pre-release-OS-versions-1751
see: https://balena.fibery.io/Work/Task/cli-Enable-OS-Updates-to-pre-release-OS-versions-1751
author: Thodoris Greasidis
nested: []
- subject: Update balena-sdk to 19.4.0
hash: 01538728cd4a0ad512b45c062b4d45f6d1f664e7
body: |
Update balena-sdk from 19.0.1 to 19.4.0
footer:
Change-type: minor
change-type: minor
author: Thodoris Greasidis
nested:
- commits:
- subject: Update the deviceType.getInstructions tests
hash: 3fd5f7d88c6fd335e8ada5c9efd64ddd14c9a992
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: "os.getSupportedOsUpdateVersions: Add the option to include draft
releases"
hash: 87b3187274a5f417ab82855029f517dc99a2f503
body: ""
footer:
Change-type: minor
change-type: minor
author: Thodoris Greasidis
nested: []
- subject: Enable OS Updates to pre-release versions of higher base semver
hash: 38360a84d29f316d3619d3b899538ccdf71635fc
body: |
Update balena-hup-action-utils from 5.0.0 to 6.1.0
footer:
Change-type: minor
change-type: minor
author: Thodoris Greasidis
nested:
- commits:
- subject: Enable OS Updates to pre-release versions of higher base semver
hash: 1b3e83b9519157be1ca9ba7756bba87a08bea04a
body: ""
footer:
Change-type: minor
change-type: minor
author: Thodoris Greasidis
nested: []
version: balena-hup-action-utils-6.1.0
title: ""
date: 2024-01-04T13:32:14.391Z
- commits:
- subject: Drop support for TypeScript < 5.3.3
hash: 7c3430280b47ea9a17f7bb94df068f2a46bfa975
body: ""
footer:
Change-type: major
change-type: major
author: Thodoris Greasidis
nested: []
- subject: Drop support for node < v18
hash: b1eb6844578bff03c05c19bbf6436526a69a8b30
body: ""
footer:
Change-type: major
change-type: major
author: Thodoris Greasidis
nested: []
- subject: Update dependencies
hash: 7413837d3aed9aa54ec5d1e218647f543308b298
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: Move the build step from prepare to prepack
hash: c4480c214c79f4e07cf3b65944b83d11c9c2e267
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: balena-hup-action-utils-6.0.0
title: ""
date: 2023-12-20T13:33:03.867Z
- commits:
- subject: "patch: Update flowzone.yml"
hash: 41a90775219e1b7b144069aea545f8f2141c88f7
body: ""
footer: {}
author: Kyle Harding
nested: []
version: balena-hup-action-utils-5.0.1
title: ""
date: 2023-07-13T19:00:55.217Z
- subject: "os.getAvailableOsVersions: Add the option to include draft releases"
hash: b8e795ac01e2e05c6484cfd492ea9dfd5f16f142
body: ""
footer:
Change-type: minor
change-type: minor
author: Thodoris Greasidis
nested: []
version: balena-sdk-19.4.0
title: ""
date: 2024-01-23T14:37:21.759Z
- commits:
- subject: Update date-fns to v3
hash: f027a467b4fe45884650d2d8c56ce3a361842a6b
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: balena-sdk-19.3.5
title: ""
date: 2023-12-21T13:16:48.448Z
- commits:
- subject: "types/Device: Deprecate the non-existent vpn_address property"
hash: 0a9d79b71f7c97813831649d18a4bc1703d71307
body: ""
footer:
Change-type: patch
change-type: patch
author: Otávio Jacobi
nested: []
version: balena-sdk-19.3.4
title: ""
date: 2023-12-15T13:34:05.193Z
- commits:
- subject: "types/Device: Deprecate the non-existent state & status_sort_index
properties"
hash: 7013d15352906ae815f5cd630086222f5c9853df
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: balena-sdk-19.3.3
title: ""
date: 2023-12-15T12:02:22.609Z
- commits:
- subject: "test:fast: Run the tests ignoring any linting errors"
hash: 59811c2f19a2044b4a1a0d1068ba90ee1587f9a3
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: "tests: Re-enable the explicit error checks for non-tarball DWB
requests"
hash: cb7c1a2d842e53255975a91457da00bd7070d8f7
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: balena-sdk-19.3.2
title: ""
date: 2023-12-08T15:49:54.842Z
- commits:
- subject: Update TypeScript to 5.3.2
hash: d66ee5c290df275e18bbdcf8bd5cf9475e6db768
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: balena-sdk-19.3.1
title: ""
date: 2023-11-30T15:10:55.747Z
- commits:
- subject: "tests: Remove the explicit error checks for non-tarball DWB requests"
hash: 0ca96b7440af76a1b7c52899d880dc817cf69278
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: "tests: Properly cleanup the test orgs"
hash: 431acbfa773b271b614c619595abc61f3c6e791c
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: "tests: Reduce the request batching chunk size to speed up tests"
hash: d3397cb6fdf6fd7edb4247d0d5980086e9338c1d
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: Add option for configuring the request batching chunk size
hash: 94e5d7816ac813e9b8468b73e3d365f735182f4b
body: ""
footer:
Change-type: minor
change-type: minor
author: Thodoris Greasidis
nested: []
version: balena-sdk-19.3.0
title: ""
date: 2023-11-30T13:54:32.874Z
- commits:
- subject: Add organization logo to organization
hash: 251e835ad6fe778024bbe358fa70aa73c8e250b8
body: ""
footer:
Change-type: minor
change-type: minor
author: Otávio Jacobi
nested: []
version: balena-sdk-19.2.0
title: ""
date: 2023-11-13T11:20:58.418Z
- commits:
- subject: Add the retryRateLimitedRequests sdk option for retrying after HTTP
429s
hash: 25e83b67f6f7c3f20982c97d4e561dd81c37a672
body: ""
footer:
Change-type: minor
change-type: minor
author: Thodoris Greasidis
nested: []
version: balena-sdk-19.1.0
title: ""
date: 2023-11-06T13:49:10.660Z
version: 17.5.0
title: ""
date: 2024-01-23T15:52:49.156Z
- commits:
- subject: Regression described in GitHub Issue 2715; balena push hangs in local
mode.
hash: 09e2550b32f628f8e5b5cb8be0cafe4b40c7ce10
body: ""
footer:
Change-type: patch
change-type: patch
Signed-off-by: Ken Bannister <kb2ma@runbox.com>
signed-off-by: Ken Bannister <kb2ma@runbox.com>
author: Ken Bannister
nested: []
version: 17.4.12
title: ""
date: 2024-01-18T10:55:45.599Z
- commits:
- subject: Exclude the oclif package patch from the published files
hash: 4e5eb4bcee8e33a1aac337401c0180817e152b69
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: Update the @oclif/core patch
hash: 696bad3ed6f27832bf10f096c088367a57902920
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: 17.4.11
title: ""
date: 2024-01-05T23:01:07.859Z
- commits:
- subject: Normalize v prefixes in the --version parameter of all commands
hash: b7b01ecd5314bddae73b7b062f9d034b3661bcef
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: 17.4.10
title: ""
date: 2024-01-02T12:41:38.978Z
- commits:
- subject: Fix publishing artifacts to gh release
hash: 1da5a75c1411bdfece2b60f83095082f6ce68ace
body: ""
footer:
Change-type: patch
change-type: patch
author: Otávio Jacobi
nested: []
version: 17.4.9
title: ""
date: 2023-12-19T23:02:29.500Z
- commits:
- subject: Remove repo config from flowzone.yml
hash: bfbc71215c376e815e7d86561d87c5b697ba7482
body: |
This functionality is being deprecated in Flowzone.
See: https://github.com/product-os/flowzone/pull/833
footer:
Change-type: patch
change-type: patch
Signed-off-by: Kyle Harding <kyle@balena.io>
signed-off-by: Kyle Harding <kyle@balena.io>
author: Kyle Harding
nested: []
version: 17.4.8
title: ""
date: 2023-12-19T21:59:06.220Z
- commits:
- subject: "deploy: Add rate-limiting aware retries for failed requests"
hash: 4266dc69514c2177399fc605985196a436d75740
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: Update dependencies
hash: 0ba352258482048bbdb840be7ee9958b491f9b6c
body: |
Update @balena/compose from 3.0.5 to 3.2.0
Also updates pinejs-client-request to support
using the Retry-After header and dockerode
to 3.3.5 to be aligned with @balena/compose.
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested:
- commits:
- subject: 'release/createClient: Allow specifying the "retry" options'
hash: b89b42a838ed2c3a7a8319cbd1b2a7c66a8210ef
body: ""
footer:
Change-type: minor
change-type: minor
author: Thodoris Greasidis
nested: []
version: balena-compose-3.2.0
title: ""
date: 2023-12-05T15:26:57.394Z
- commits:
- subject: Update dockerode to 3.3.5
hash: f5fc932f3203df4df66d38363974e62788e468ff
body: ""
footer:
Change-type: patch
change-type: patch
author: Pagan Gazzard
nested: []
version: balena-compose-3.1.3
title: ""
date: 2023-11-29T14:49:55.816Z
- commits:
- subject: Use the JSONStream typings from @types/jsonstream
hash: 155fdcc8e4e7df67d41152b494e1a80493bb0439
body: ""
footer:
Change-type: patch
change-type: patch
author: Pagan Gazzard
nested: []
version: balena-compose-3.1.2
title: ""
date: 2023-11-29T13:33:49.557Z
- commits:
- subject: Make use of `pipeline` for piping streams together
hash: 1d98cd535a20fa67869da242b0ec7ddd713a4c7b
body: ""
footer:
Change-type: patch
change-type: patch
author: Pagan Gazzard
nested: []
version: balena-compose-3.1.1
title: ""
date: 2023-11-27T12:43:23.880Z
- commits:
- subject: Allow injecting any PinejsClientCore compatible API client
hash: e0ab3ef95f8bc51d2e9055a1f822b8d340f0c587
body: ""
footer:
Change-type: minor
change-type: minor
author: Thodoris Greasidis
nested: []
version: balena-compose-3.1.0
title: ""
date: 2023-11-13T16:27:44.317Z
- commits:
- subject: "NodeResolver: Refactor the recursion to an async-await loop"
hash: bde40f4430bc26a058598a64eeeedbb5ab35eb57
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: Drop bluebird & bluebird-lru-cache in favor of memoizee
hash: 82f90b210d73ff866f5d0546e73d8779db85a504
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: balena-compose-3.0.7
title: ""
date: 2023-11-10T16:10:01.859Z
- commits:
- subject: Fix the remaining linting errors
hash: 51b7893bc6156d0fa7a7821cc583032694ccda98
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: Remove unnecessary regex escaping
hash: 96b76abbcf78abd05157d49a5672a2621124bfe5
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: Replace the {} type with object
hash: dcf907ff124a638f591ae8e3fd80157eae1d1837
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: Update TypeScript to 5.2.2 and @blaena/lint to v7.2.1
hash: b583dd7ce8e964bef47f73dee53e08b7c1286532
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: balena-compose-3.0.6
title: ""
date: 2023-11-10T14:08:35.300Z
version: 17.4.7
title: ""
date: 2023-12-19T14:26:26.818Z
- commits:
- subject: Bump oclif core & use default missing flag handler
hash: b9722c67963c9b90e94aec7653ee488957ecd690
body: ""
footer:
Change-type: patch
change-type: patch
author: Otávio Jacobi
nested: []
version: 17.4.6
title: ""
date: 2023-12-08T15:55:47.078Z
- commits:
- subject: Stop testing dependency deduplication on the custom test runners
hash: 65ba63d1a8d231851634830be6d48fbf0e085e47
body: |
That's since we already run that test as part of
flowzone's default "Test npm (18.x)", and the
custom tests are using the latest node & npm
version of the selected major.
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: Temporarily pin oclif-core to ~3.11.0 to deduplicate the dependencies
hash: f5ffa7d84f58047e1f262b2b1e1719fd4164d5de
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: Update TypeScript to 5.3.2
hash: dac3ace61d80dfd000a4a69dfa51d141d34ebc0a
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: 17.4.5
title: ""
date: 2023-12-04T14:08:25.597Z
- commits:
- subject: Fix balena block create to actually create a block
hash: b8769bb9e9dafac8a52eef477bc763551cf0d0b0
body: ""
footer:
Change-type: patch
change-type: patch
author: Otávio Jacobi
nested: []
version: 17.4.4
title: ""
date: 2023-11-20T17:57:18.485Z
- commits:
- subject: Bump oclif-core to v3
hash: 72a924f00eabd13d3663e9cfa4d8feb11aa1aecd
body: ""
footer:
Change-type: patch
change-type: patch
author: Otávio Jacobi
nested: []
version: 17.4.3
title: ""
date: 2023-11-17T15:39:17.941Z
- commits:
- subject: "Docs: Automatically generate Capitano configuration"
hash: 4b5def0a8a632a9aed827319c1dcbe6ccf8efc32
body: ""
footer:
Change-type: patch
change-type: patch
Signed-off-by: Vipul Gupta (@vipulgupta2048) <vipulgupta2048@gmail.com>
signed-off-by: Vipul Gupta (@vipulgupta2048) <vipulgupta2048@gmail.com>
author: Vipul Gupta (@vipulgupta2048)
nested: []
version: 17.4.2
title: ""
date: 2023-11-15T11:02:20.523Z
- commits:
- subject: Bump shrinkwrap
hash: a816548bb5832ad907c02a0cb126cbd7d0ebddf5
body: ""
footer:
Change-type: patch
change-type: patch
author: Otávio Jacobi
nested: []
version: 17.4.1
title: ""
date: 2023-11-13T19:18:43.914Z
- commits:
- subject: "device: Add `--json` option for JSON output"
hash: d78045b6ab0c78a1383fd240bf0f9e11b1af777f
body: ""
footer:
change-type: minor
author: Brian Bugh
nested: []
version: 17.4.0
title: ""
date: 2023-11-10T16:27:56.520Z
- commits:
- subject: Update @balena/compose to 3.0.5
hash: 1b615e4690f40fce125ca1a5de53d83a519bc852
body: |
Update @balena/compose from 3.0.2 to 3.0.5
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested:
- commits:
- subject: "builder: Fix unawaited buildDir pack() promise"
hash: 76a9cecc44a5c252c9052d1613a8b37ed9cb2dbc
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: balena-compose-3.0.5
title: ""
date: 2023-11-09T16:40:49.186Z
- commits:
- subject: "api: Restore the accidentally removed concurrency limits"
hash: ae349e6c4487ad293766b077faddaacbb2e10007
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: balena-compose-3.0.4
title: ""
date: 2023-11-09T16:23:23.111Z
- commits:
- subject: '.mocharc: Use "exit: true" to workaround hanging on completion on
node20'
hash: db962acc46aab246a42579ddd873f24ea5f9c3ec
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: "tests: Fix the expected error message for Dockerfile syntax errors"
hash: a675b7419876a34d35d6c8b6078e2d9bd54d41dc
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: balena-compose-3.0.3
title: ""
date: 2023-11-09T16:03:42.407Z
version: 17.3.2
title: ""
date: 2023-11-10T11:02:53.751Z
- commits:
- subject: Use `pipeline` instead of `.pipe` when downloading OS image
hash: 56cff464080df51251be94a6ffd6799203d1ca8c

View File

@ -4,6 +4,205 @@ All notable changes to this project will be documented in this file
automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY!
This project adheres to [Semantic Versioning](http://semver.org/).
## 18.0.0 - 2024-02-06
* Update to Node 20 [Otávio Jacobi]
## 17.5.1 - 2024-01-31
* Fix target state construction with livepush [Felipe Lalanne]
## 17.5.0 - 2024-01-23
* os versions: Add the --include-draft option [Thodoris Greasidis]
* device os-update: Add option for including pre-release versions in the list [Thodoris Greasidis]
* device os-update: Enable updates to pre-release versions of higher base semver [Thodoris Greasidis]
<details>
<summary> Update balena-sdk to 19.4.0 [Thodoris Greasidis] </summary>
> ### balena-sdk-19.4.0 - 2024-01-23
>
> * Update the deviceType.getInstructions tests [Thodoris Greasidis]
> * os.getSupportedOsUpdateVersions: Add the option to include draft releases [Thodoris Greasidis]
>
> <details>
> <summary> Enable OS Updates to pre-release versions of higher base semver [Thodoris Greasidis] </summary>
>
>> #### balena-hup-action-utils-6.1.0 - 2024-01-04
>>
>> * Enable OS Updates to pre-release versions of higher base semver [Thodoris Greasidis]
>>
>> #### balena-hup-action-utils-6.0.0 - 2023-12-20
>>
>> * Drop support for TypeScript < 5.3.3 [Thodoris Greasidis]
>> * Drop support for node < v18 [Thodoris Greasidis]
>> * Update dependencies [Thodoris Greasidis]
>> * Move the build step from prepare to prepack [Thodoris Greasidis]
>>
>> #### balena-hup-action-utils-5.0.1 - 2023-07-13
>>
>> * patch: Update flowzone.yml [Kyle Harding]
>>
>
> </details>
>
> * os.getAvailableOsVersions: Add the option to include draft releases [Thodoris Greasidis]
>
> ### balena-sdk-19.3.5 - 2023-12-21
>
> * Update date-fns to v3 [Thodoris Greasidis]
>
> ### balena-sdk-19.3.4 - 2023-12-15
>
> * types/Device: Deprecate the non-existent vpn_address property [Otávio Jacobi]
>
> ### balena-sdk-19.3.3 - 2023-12-15
>
> * types/Device: Deprecate the non-existent state & status_sort_index properties [Thodoris Greasidis]
>
> ### balena-sdk-19.3.2 - 2023-12-08
>
> * test:fast: Run the tests ignoring any linting errors [Thodoris Greasidis]
> * tests: Re-enable the explicit error checks for non-tarball DWB requests [Thodoris Greasidis]
>
> ### balena-sdk-19.3.1 - Invalid date
>
> * Update TypeScript to 5.3.2 [Thodoris Greasidis]
>
> ### balena-sdk-19.3.0 - Invalid date
>
> * tests: Remove the explicit error checks for non-tarball DWB requests [Thodoris Greasidis]
> * tests: Properly cleanup the test orgs [Thodoris Greasidis]
> * tests: Reduce the request batching chunk size to speed up tests [Thodoris Greasidis]
> * Add option for configuring the request batching chunk size [Thodoris Greasidis]
>
> ### balena-sdk-19.2.0 - 2023-11-13
>
> * Add organization logo to organization [Otávio Jacobi]
>
> ### balena-sdk-19.1.0 - 2023-11-06
>
> * Add the retryRateLimitedRequests sdk option for retrying after HTTP 429s [Thodoris Greasidis]
>
</details>
## 17.4.12 - 2024-01-18
* Regression described in GitHub Issue 2715; balena push hangs in local mode. [Ken Bannister]
## 17.4.11 - 2024-01-05
* Exclude the oclif package patch from the published files [Thodoris Greasidis]
* Update the @oclif/core patch [Thodoris Greasidis]
## 17.4.10 - 2024-01-02
* Normalize v prefixes in the --version parameter of all commands [Thodoris Greasidis]
## 17.4.9 - 2023-12-19
* Fix publishing artifacts to gh release [Otávio Jacobi]
## 17.4.8 - 2023-12-19
* Remove repo config from flowzone.yml [Kyle Harding]
## 17.4.7 - 2023-12-19
* deploy: Add rate-limiting aware retries for failed requests [Thodoris Greasidis]
<details>
<summary> Update dependencies [Thodoris Greasidis] </summary>
> ### balena-compose-3.2.0 - 2023-12-05
>
> * release/createClient: Allow specifying the "retry" options [Thodoris Greasidis]
>
> ### balena-compose-3.1.3 - 2023-11-29
>
> * Update dockerode to 3.3.5 [Pagan Gazzard]
>
> ### balena-compose-3.1.2 - 2023-11-29
>
> * Use the JSONStream typings from @types/jsonstream [Pagan Gazzard]
>
> ### balena-compose-3.1.1 - 2023-11-27
>
> * Make use of `pipeline` for piping streams together [Pagan Gazzard]
>
> ### balena-compose-3.1.0 - 2023-11-13
>
> * Allow injecting any PinejsClientCore compatible API client [Thodoris Greasidis]
>
> ### balena-compose-3.0.7 - 2023-11-10
>
> * NodeResolver: Refactor the recursion to an async-await loop [Thodoris Greasidis]
> * Drop bluebird & bluebird-lru-cache in favor of memoizee [Thodoris Greasidis]
>
> ### balena-compose-3.0.6 - 2023-11-10
>
> * Fix the remaining linting errors [Thodoris Greasidis]
> * Remove unnecessary regex escaping [Thodoris Greasidis]
> * Replace the {} type with object [Thodoris Greasidis]
> * Update TypeScript to 5.2.2 and @blaena/lint to v7.2.1 [Thodoris Greasidis]
>
</details>
## 17.4.6 - 2023-12-08
* Bump oclif core & use default missing flag handler [Otávio Jacobi]
## 17.4.5 - 2023-12-04
* Stop testing dependency deduplication on the custom test runners [Thodoris Greasidis]
* Temporarily pin oclif-core to ~3.11.0 to deduplicate the dependencies [Thodoris Greasidis]
* Update TypeScript to 5.3.2 [Thodoris Greasidis]
## 17.4.4 - 2023-11-20
* Fix balena block create to actually create a block [Otávio Jacobi]
## 17.4.3 - 2023-11-17
* Bump oclif-core to v3 [Otávio Jacobi]
## 17.4.2 - 2023-11-15
* Docs: Automatically generate Capitano configuration [Vipul Gupta (@vipulgupta2048)]
## 17.4.1 - 2023-11-13
* Bump shrinkwrap [Otávio Jacobi]
## 17.4.0 - 2023-11-10
* device: Add `--json` option for JSON output [Brian Bugh]
## 17.3.2 - 2023-11-10
<details>
<summary> Update @balena/compose to 3.0.5 [Thodoris Greasidis] </summary>
> ### balena-compose-3.0.5 - 2023-11-09
>
> * builder: Fix unawaited buildDir pack() promise [Thodoris Greasidis]
>
> ### balena-compose-3.0.4 - 2023-11-09
>
> * api: Restore the accidentally removed concurrency limits [Thodoris Greasidis]
>
> ### balena-compose-3.0.3 - 2023-11-09
>
> * .mocharc: Use "exit: true" to workaround hanging on completion on node20 [Thodoris Greasidis]
> * tests: Fix the expected error message for Dockerfile syntax errors [Thodoris Greasidis]
>
</details>
## 17.3.1 - 2023-11-09
* Use `pipeline` instead of `.pipe` when downloading OS image [Pagan Gazzard]

View File

@ -78,8 +78,8 @@ If you are a Node.js developer, you may wish to install the balena CLI via [npm]
The npm installation involves building native (platform-specific) binary modules, which require
some development tools to be installed first, as follows.
> **The balena CLI currently requires Node.js version 18.**
> **Versions 19 and later are not yet fully supported.**
> **The balena CLI currently requires Node.js version 20.**
> **Versions 21 and later are not yet fully supported.**
### Install development tools
@ -89,7 +89,7 @@ some development tools to be installed first, as follows.
$ sudo apt-get update && sudo apt-get -y install curl python3 git make g++
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
$ . ~/.bashrc
$ nvm install 18
$ nvm install 20
```
The `curl` command line above uses
@ -106,7 +106,7 @@ recommended.
```sh
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
$ . ~/.bashrc
$ nvm install 18
$ nvm install 20
```
#### **Windows** (not WSL)
@ -114,7 +114,7 @@ $ nvm install 18
Install:
* If you'd like the ability to switch between Node.js versions, install
- Node.js v18 from the [Nodejs.org releases page](https://nodejs.org/en/download/releases/).
- Node.js v20 from the [Nodejs.org releases page](https://nodejs.org/en/download/releases/).
[nvm-windows](https://github.com/coreybutler/nvm-windows#node-version-manager-nvm-for-windows)
instead.
* The [MSYS2 shell](https://www.msys2.org/), which provides `git`, `make`, `g++` and more:

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
import type { JsonVersions } from '../lib/commands/version';
import type { JsonVersions } from '../lib/commands/version/index';
import { run as oclifRun } from '@oclif/core';
import * as archiver from 'archiver';
@ -155,7 +155,7 @@ ${sep}
* messages (stdout and stderr) in order to call diffPkgOutput().
*/
async function execPkg(...args: any[]) {
const { exec: pkgExec } = await import('pkg');
const { exec: pkgExec } = await import('@yao-pkg/pkg');
const outTap = new StdOutTap(true);
try {
outTap.tap();

View File

@ -17,6 +17,7 @@
import * as path from 'path';
import { MarkdownFileParser } from './utils';
import { GlobSync } from 'glob';
/**
* This is the skeleton of CLI documentation/reference web page at:
@ -27,224 +28,111 @@ import { MarkdownFileParser } from './utils';
*
* IMPORTANT
*
* Only build files listed here will be documented by Capitano
* Make sure to add your files in alphabetical order
* All commands need to be stored under a folder in lib/commands to maintain uniformity
* Generating docs will error out if directive not followed
* To add a custom heading for command docs, add the heading next to the folder name
* in the `commandHeadings` dictionary.
*
* This dictionary is the source of truth that creates the docs config which is used
* to generate the CLI documentation. By default, the folder name will be used.
*
* Resources with plural names needs to have 2 sections if they have commands like:
* "fleet, fleets" or "device, devices" or "tag, tags"
*
*/
const capitanoDoc = {
title: 'balena CLI Documentation',
introduction: '',
categories: [
{
title: 'API Key',
files: ['build/commands/api-keys/index.js'],
},
{
title: 'API Keys',
files: [
'build/commands/api-key/generate.js',
'build/commands/api-key/revoke.js',
],
},
{
title: 'App',
files: ['build/commands/app/create.js'],
},
{
title: 'Authentication',
files: [
'build/commands/login.js',
'build/commands/logout.js',
'build/commands/whoami.js',
],
},
{
title: 'Block',
files: ['build/commands/app/create.js'],
},
{
title: 'Config',
files: [
'build/commands/config/generate.js',
'build/commands/config/inject.js',
'build/commands/config/read.js',
'build/commands/config/reconfigure.js',
'build/commands/config/write.js',
],
},
{
title: 'Deploy',
files: ['build/commands/build.js', 'build/commands/deploy.js'],
},
{
title: 'Device',
files: [
'build/commands/device/deactivate.js',
'build/commands/device/identify.js',
'build/commands/device/index.js',
'build/commands/device/init.js',
'build/commands/device/local-mode.js',
'build/commands/device/move.js',
'build/commands/device/os-update.js',
'build/commands/device/pin.js',
'build/commands/device/public-url.js',
'build/commands/device/purge.js',
'build/commands/device/reboot.js',
'build/commands/device/register.js',
'build/commands/device/rename.js',
'build/commands/device/restart.js',
'build/commands/device/rm.js',
'build/commands/device/shutdown.js',
'build/commands/device/track-fleet.js',
'build/commands/device/start-service.js',
'build/commands/device/stop-service.js',
],
},
{
title: 'Devices',
files: [
'build/commands/devices/index.js',
'build/commands/devices/supported.js',
],
},
{
title: 'Environment Variable',
files: [
'build/commands/env/add.js',
'build/commands/env/rename.js',
'build/commands/env/rm.js',
],
},
{
title: 'Environment Variables',
files: ['build/commands/envs.js'],
},
{
title: 'Fleet',
files: [
'build/commands/fleet/create.js',
'build/commands/fleet/index.js',
'build/commands/fleet/pin.js',
'build/commands/fleet/purge.js',
'build/commands/fleet/rename.js',
'build/commands/fleet/restart.js',
'build/commands/fleet/rm.js',
'build/commands/fleet/track-latest.js',
],
},
{
title: 'Fleets',
files: ['build/commands/fleets.js'],
},
{
title: 'Help and Version',
files: ['help', 'build/commands/version.js'],
},
{
title: 'Local',
files: [
'build/commands/local/configure.js',
'build/commands/local/flash.js',
],
},
{
title: 'Logs',
files: ['build/commands/logs.js'],
},
{
title: 'Network',
files: [
'build/commands/scan.js',
'build/commands/ssh.js',
'build/commands/tunnel.js',
],
},
{
title: 'Notes',
files: ['build/commands/note.js'],
},
{
title: 'Organizations',
files: ['build/commands/orgs.js'],
},
{
title: 'OS',
files: [
'build/commands/os/build-config.js',
'build/commands/os/configure.js',
'build/commands/os/download.js',
'build/commands/os/initialize.js',
'build/commands/os/versions.js',
],
},
{
title: 'Preload',
files: ['build/commands/preload.js'],
},
{
title: 'Push',
files: ['build/commands/push.js'],
},
{
title: 'Platform',
files: ['build/commands/join.js', 'build/commands/leave.js'],
},
{
title: 'Release',
files: [
'build/commands/release/finalize.js',
'build/commands/release/index.js',
'build/commands/release/invalidate.js',
'build/commands/release/validate.js',
],
},
{
title: 'Releases',
files: ['build/commands/releases.js'],
},
{
title: 'Settings',
files: ['build/commands/settings.js'],
},
{
title: 'Support',
files: ['build/commands/support.js'],
},
{
title: 'SSH Key',
files: [
'build/commands/key/add.js',
'build/commands/key/index.js',
'build/commands/key/rm.js',
],
},
{
title: 'SSH Keys',
files: ['build/commands/keys.js'],
},
{
title: 'Tags',
files: ['build/commands/tag/rm.js', 'build/commands/tag/set.js'],
},
{
title: 'Tags',
files: ['build/commands/tags.js'],
},
{
title: 'Utilities',
files: ['build/commands/util/available-drives.js'],
},
],
interface Category {
title: string;
files: string[];
}
interface Documentation {
title: string;
introduction: string;
categories: Category[];
}
// Mapping folders names to custom headings in the docs
const commandHeadings: { [key: string]: string } = {
'api-key': 'API Key',
'api-keys': 'API Keys',
login: 'Authentication',
whoami: 'Authentication',
logout: 'Authentication',
env: 'Environment Variable',
envs: 'Environment Variables',
help: 'Help and Version',
key: 'SSH Key',
keys: 'SSH Keys',
orgs: 'Organizations',
os: 'OS',
util: 'Utilities',
ssh: 'Network',
scan: 'Network',
tunnel: 'Network',
build: 'Deploy',
join: 'Platform',
leave: 'Platform',
};
// Fetch all available commands
const allCommandsPaths = new GlobSync('build/commands/**/*.js', {
ignore: 'build/commands/internal/**',
}).found;
// Throw error if any commands found outside of command directories
const illegalCommandPaths = allCommandsPaths.filter((commandPath: string) =>
/^build\/commands\/[^/]+\.js$/.test(commandPath),
);
if (illegalCommandPaths.length !== 0) {
throw new Error(
`Found the following commands without a command directory: ${illegalCommandPaths}\n
To resolve this error, move the respective commands to their resource directories or create new ones.\n
Refer to the automation/capitanodoc/capitanodoc.ts file for more information.`,
);
}
// Docs config template
const capitanoDoc: Documentation = {
title: 'balena CLI Documentation',
introduction: '',
categories: [],
};
// Helper function to capitalize each word of directory name
function formatTitle(dir: string): string {
return dir.replace(/(^\w|\s\w)/g, (word) => word.toUpperCase());
}
// Create a map to track the categories for faster lookup
const categoriesMap: { [key: string]: Category } = {};
for (const commandPath of allCommandsPaths) {
const commandDir = path.basename(path.dirname(commandPath));
const heading = commandHeadings[commandDir] || formatTitle(commandDir);
if (!categoriesMap[heading]) {
categoriesMap[heading] = { title: heading, files: [] };
capitanoDoc.categories.push(categoriesMap[heading]);
}
categoriesMap[heading].files.push(commandPath);
}
// Sort Category titles alphabetically
capitanoDoc.categories = capitanoDoc.categories.sort((a, b) =>
a.title.localeCompare(b.title),
);
// Sort Category file paths alphabetically
capitanoDoc.categories.forEach((category) => {
category.files.sort((a, b) => a.localeCompare(b));
});
/**
* Modify and return the `capitanoDoc` object above in order to render the
* CLI documentation/reference web page at:
* https://www.balena.io/docs/reference/cli/
* Modify and return the `capitanoDoc` object above in order to generate the
* CLI documentation at docs/balena-cli.md
*
* This function parses the README.md file to extract relevant sections
* for the documentation web page.

View File

@ -15,7 +15,7 @@ async function run() {
require('@balena/es-version').set('es2018');
// Run the CLI
await require('../build/app').run();
await require('../build/app').run(undefined, { dir: __dirname });
}
run();

View File

@ -57,7 +57,7 @@ require('ts-node').register({
project: path.join(rootDir, 'tsconfig.json'),
transpileOnly: true,
});
require('../lib/app').run();
require('../lib/app').run(undefined, { dir: __dirname, development: true });
// Modify package.json oclif paths from build/ -> lib/, or vice versa
function modifyOclifPaths(revert) {

View File

@ -8,7 +8,7 @@ _balena() {
local context state line curcontext="$curcontext"
# Valid top-level completions
main_commands=( build deploy envs fleets join keys leave login logout logs note orgs preload push releases scan settings ssh support tags tunnel version whoami api-key api-keys app block config device device devices env fleet fleet internal key key local os release release tag util )
main_commands=( api-key api-keys app block build config deploy device device devices env envs fleet fleet fleets internal join key key keys leave local login logout logs notes orgs os preload push release release releases scan settings ssh support tag tags tunnel util version whoami )
# Sub-completions
api_key_cmds=( generate revoke )
app_cmds=( create )

View File

@ -7,7 +7,7 @@ _balena_complete()
local cur prev
# Valid top-level completions
main_commands="build deploy envs fleets join keys leave login logout logs note orgs preload push releases scan settings ssh support tags tunnel version whoami api-key api-keys app block config device device devices env fleet fleet internal key key local os release release tag util"
main_commands="api-key api-keys app block build config deploy device device devices env envs fleet fleet fleets internal join key key keys leave local login logout logs notes orgs os preload push release release releases scan settings ssh support tag tags tunnel util version whoami"
# Sub-completions
api_key_cmds="generate revoke"
app_cmds="create"

View File

@ -162,12 +162,12 @@ are encouraged to regularly update the balena CLI to the latest version.
- API Key
- [api-keys](#api-keys)
- [api-key generate &#60;name&#62;](#api-key-generate-name)
- [api-key revoke &#60;ids&#62;](#api-key-revoke-ids)
- API Keys
- [api-key generate &#60;name&#62;](#api-key-generate-name)
- [api-key revoke &#60;ids&#62;](#api-key-revoke-ids)
- [api-keys](#api-keys)
- App
@ -181,7 +181,7 @@ are encouraged to regularly update the balena CLI to the latest version.
- Block
- [app create &#60;name&#62;](#app-create-name)
- [block create &#60;name&#62;](#block-create-name)
- Config
@ -214,9 +214,9 @@ are encouraged to regularly update the balena CLI to the latest version.
- [device restart &#60;uuid&#62;](#device-restart-uuid)
- [device rm &#60;uuid(s)&#62;](#device-rm-uuid-s)
- [device shutdown &#60;uuid&#62;](#device-shutdown-uuid)
- [device track-fleet &#60;uuid&#62;](#device-track-fleet-uuid)
- [device start-service &#60;uuid&#62;](#device-start-service-uuid)
- [device stop-service &#60;uuid&#62;](#device-stop-service-uuid)
- [device track-fleet &#60;uuid&#62;](#device-track-fleet-uuid)
- Devices
@ -248,11 +248,6 @@ are encouraged to regularly update the balena CLI to the latest version.
- [fleets](#fleets)
- Help and Version
- [help [command]](#help-command)
- [version](#version)
- Local
- [local configure &#60;target&#62;](#local-configure-target)
@ -284,6 +279,11 @@ are encouraged to regularly update the balena CLI to the latest version.
- [os configure &#60;image&#62;](#os-configure-image)
- [os initialize &#60;image&#62;](#os-initialize-image)
- Platform
- [join [deviceiporhostname]](#join-deviceiporhostname)
- [leave [deviceiporhostname]](#leave-deviceiporhostname)
- Preload
- [preload &#60;image&#62;](#preload-image)
@ -292,11 +292,6 @@ are encouraged to regularly update the balena CLI to the latest version.
- [push &#60;fleetordevice&#62;](#push-fleetordevice)
- Platform
- [join [deviceiporhostname]](#join-deviceiporhostname)
- [leave [deviceiporhostname]](#leave-deviceiporhostname)
- Release
- [release finalize &#60;commitorid&#62;](#release-finalize-commitorid)
@ -312,10 +307,6 @@ are encouraged to regularly update the balena CLI to the latest version.
- [settings](#settings)
- Support
- [support &#60;action&#62;](#support-action)
- SSH Key
- [key add &#60;name&#62; [path]](#key-add-name-path)
@ -326,7 +317,11 @@ are encouraged to regularly update the balena CLI to the latest version.
- [keys](#keys)
- Tags
- Support
- [support &#60;action&#62;](#support-action)
- Tag
- [tag rm &#60;tagkey&#62;](#tag-rm-tagkey)
- [tag set &#60;tagkey&#62; [value]](#tag-set-tagkey-value)
@ -339,30 +334,12 @@ are encouraged to regularly update the balena CLI to the latest version.
- [util available-drives](#util-available-drives)
- Version
- [version](#version)
# API Key
## api-keys
Print a list of balenaCloud API keys.
Print a list of balenaCloud API keys for the current user or for a specific fleet with the `--fleet` option.
Examples:
$ balena api-keys
### Options
#### -u, --user
show API keys for your user
#### -f, --fleet FLEET
fleet name or slug (preferred)
# API Keys
## api-key generate &#60;name&#62;
Generate a new balenaCloud API key for the current user, with the given
@ -403,6 +380,28 @@ the API key ids
### Options
# API Keys
## api-keys
Print a list of balenaCloud API keys.
Print a list of balenaCloud API keys for the current user or for a specific fleet with the `--fleet` option.
Examples:
$ balena api-keys
### Options
#### -u, --user
show API keys for your user
#### -f, --fleet FLEET
fleet name or slug (preferred)
# App
## app create &#60;name&#62;
@ -527,16 +526,16 @@ Examples:
# Block
## app create &#60;name&#62;
## block create &#60;name&#62;
Create a new balena app.
Create a new balena block.
You can specify the organization the app should belong to using
You can specify the organization the block should belong to using
the `--organization` option. The organization's handle, not its name,
should be provided. Organization handles can be listed with the
`balena orgs` command.
The app's default device type is specified with the `--type` option.
The block's default device type is specified with the `--type` option.
The `balena devices supported` command can be used to list the available
device types.
@ -548,25 +547,25 @@ type and organization.
Examples:
$ balena app create MyApp
$ balena app create MyApp --organization mmyorg
$ balena app create MyApp -o myorg --type raspberry-pi
$ balena block create MyBlock
$ balena block create MyBlock --organization mmyorg
$ balena block create MyBlock -o myorg --type raspberry-pi
### Arguments
#### NAME
app name
block name
### Options
#### -o, --organization ORGANIZATION
handle of the organization the app should belong to
handle of the organization the block should belong to
#### -t, --type TYPE
app device type (Check available types with `balena devices supported`)
block device type (Check available types with `balena devices supported`)
# Config
@ -883,6 +882,7 @@ Examples:
$ balena build --fleet myFleet
$ balena build ./source/ --fleet myorg/myfleet
$ balena build ./source/ --fleet myorg/myfleet --docker-compose my-custom-compose.yml
$ balena build --deviceType raspberrypi3 --arch armv7hf --emulated
$ balena build --docker /var/run/docker.sock --fleet myFleet # Linux, Mac
$ balena build --docker //./pipe/docker_engine --fleet myFleet # Windows
@ -916,6 +916,10 @@ Use QEMU for ARM architecture emulation during the image build
Alternative Dockerfile name/path, relative to the source folder
#### --docker-compose DOCKER-COMPOSE
Alternative compose yml file, relative to the source folder
#### --nologs
Hide the image build log output (produce less verbose output)
@ -1088,6 +1092,7 @@ Examples:
$ balena deploy myFleet
$ balena deploy myorg/myfleet --build --source myBuildDir/
$ balena deploy myorg/myfleet --builld --source myBuildDir/ --docker-compose my-custom-compose.yml
$ balena deploy myorg/myfleet --build --source myBuildDir/ --note "this is the note for this release"
$ balena deploy myorg/myfleet myRepo/myImage
$ balena deploy myFleet myRepo/myImage --release-tag key1 "" key2 "value2 with spaces"
@ -1141,6 +1146,10 @@ Use QEMU for ARM architecture emulation during the image build
Alternative Dockerfile name/path, relative to the source folder
#### --docker-compose DOCKER-COMPOSE
Alternative compose yml file, relative to the source folder
#### --nologs
Hide the image build log output (produce less verbose output)
@ -1261,10 +1270,17 @@ the uuid of the device to identify
Show information about a single device.
The --json option is recommended when scripting the output of this command,
because field names are less likely to change in JSON format and because it
better represents data types like arrays, empty strings and null values.
The 'jq' utility may be helpful for querying JSON fields in shell scripts
(https://stedolan.github.io/jq/manual/).
Examples:
$ balena device 7cf02a6
$ balena device 7cf02a6 --view
$ balena device 7cf02a6 --json
### Arguments
@ -1274,6 +1290,10 @@ the device uuid
### Options
#### -j, --json
produce JSON output instead of tabular output
#### --view
open device dashboard page
@ -1444,6 +1464,7 @@ Examples:
$ balena device os-update 23c73a1
$ balena device os-update 23c73a1 --version 2.101.7
$ balena device os-update 23c73a1 --version 2.31.0+rev1.prod
$ balena device os-update 23c73a1 --include-draft
### Arguments
@ -1457,6 +1478,10 @@ the uuid of the device to update
a balenaOS version
#### --include-draft
include pre-release balenaOS versions
#### -y, --yes
answer "yes" to all questions (non interactive use)
@ -1695,22 +1720,6 @@ the uuid of the device to shutdown
force action if the update lock is set
## device track-fleet &#60;uuid&#62;
Make a device track the fleet's pinned release.
Examples:
$ balena device track-fleet 7cf02a6
### Arguments
#### UUID
the uuid of the device to make track the fleet's release
### Options
## device start-service &#60;uuid&#62;
Start containers on a device.
@ -1759,6 +1768,22 @@ comma-separated list (no blank spaces) of service names
### Options
## device track-fleet &#60;uuid&#62;
Make a device track the fleet's pinned release.
Examples:
$ balena device track-fleet 7cf02a6
### Arguments
#### UUID
the uuid of the device to make track the fleet's release
### Options
# Devices
## devices
@ -2390,63 +2415,6 @@ do not truncate output to fit screen
field to sort by (prepend '-' for descending order)
# Help and Version
## help [command]
List balena commands, or get detailed help for a specific command.
Examples:
$ balena help
$ balena help login
$ balena help os download
### Arguments
#### COMMAND
command to show help for
### Options
#### --v, --verbose
show additional commands
## version
Display version information for the balena CLI and/or Node.js. Note that the
balena CLI executable installers for Windows and macOS, and the standalone
zip packages, ship with a built-in copy of Node.js. In this case, the
reported version of Node.js regards this built-in copy, rather than any
other `node` engine that may also be available on the command prompt.
The --json option is recommended when scripting the output of this command,
because the JSON format is less likely to change and it better represents
data types like lists and empty strings. The 'jq' utility may be helpful
in shell scripts (https://stedolan.github.io/jq/manual/).
This command can also be invoked with 'balena --version' or 'balena -v'.
Examples:
$ balena version
$ balena version -a
$ balena version -j
$ balena --version
$ balena -v
### Options
#### -a, --all
include version information for additional components (Node.js)
#### -j, --json
output version information in JSON format for programmatic use
# Local
## local configure &#60;target&#62;
@ -2770,6 +2738,10 @@ device type
select balenaOS ESR versions
#### --include-draft
include pre-release balenaOS versions
## os download &#60;type&#62;
Download an unconfigured OS image for the specified device type.
@ -3022,6 +2994,87 @@ Check `balena util available-drives` for available options.
answer "yes" to all questions (non interactive use)
# Platform
## join [deviceIpOrHostname]
Move a local device to a fleet on another balena server, causing
the device to "join" the new server. The device must be running balenaOS.
For example, you could provision a device against an openBalena installation
where you perform end-to-end tests and then move it to balenaCloud when it's
ready for production.
To move a device between fleets on the same server, use the
`balena device move` command instead of `balena join`.
If you don't specify a device hostname or IP, this command will automatically
scan the local network for balenaOS devices and prompt you to select one
from an interactive picker. This may require administrator/root privileges.
Likewise, if the fleet option is not provided then a picker will be shown.
Fleets may be specified by fleet name or slug. Fleet slugs are
the recommended option, as they are unique and unambiguous. Slugs can be
listed with the `balena fleets` command. Note that slugs may change if the
fleet is renamed. Fleet names are not unique and may result in "Fleet is
ambiguous" errors at any time (even if it "used to work in the past"), for
example if the name clashes with a newly created public fleet, or with fleets
from other balena accounts that you may be invited to join under any role.
For this reason, fleet names are especially discouraged in scripts (e.g. CI
environments).
Examples:
$ balena join
$ balena join balena.local
$ balena join balena.local --fleet MyFleet
$ balena join balena.local -f myorg/myfleet
$ balena join 192.168.1.25
$ balena join 192.168.1.25 --fleet MyFleet
### Arguments
#### DEVICEIPORHOSTNAME
the IP or hostname of device
### Options
#### -f, --fleet FLEET
fleet name or slug (preferred)
#### -i, --pollInterval POLLINTERVAL
the interval in minutes to check for updates
## leave [deviceIpOrHostname]
Remove a local device from its balena fleet, causing the device to
"leave" the server it is provisioned on. This effectively makes the device
"unmanaged". The device must be running balenaOS.
The device entry on the server is preserved after running this command,
so the device can subsequently re-join the server if needed.
If you don't specify a device hostname or IP, this command will automatically
scan the local network for balenaOS devices and prompt you to select one
from an interactive picker. This may require administrator/root privileges.
Examples:
$ balena leave
$ balena leave balena.local
$ balena leave 192.168.1.25
### Arguments
#### DEVICEIPORHOSTNAME
the device IP or hostname
### Options
# Preload
## preload &#60;image&#62;
@ -3238,6 +3291,7 @@ Examples:
$ balena push myFleet -s <source directory>
$ balena push myFleet --source <source directory> --note "this is the note for this release"
$ balena push myFleet --release-tag key1 "" key2 "value2 with spaces"
$ balena push myorg/myfleet --docker-compose my-custom-compose.yml
$ balena push myorg/myfleet
$ balena push 10.0.0.1
@ -3272,6 +3326,10 @@ suspected issues with the balenaCloud backend.
Alternative Dockerfile name/path, relative to the source folder
#### --docker-compose DOCKER-COMPOSE
Alternative compose yml file, relative to the source folder
#### -c, --nocache
Don't use cached layers of previously built images for this project. This
@ -3357,87 +3415,6 @@ as final by default unless this option is given.
The notes for this release
# Platform
## join [deviceIpOrHostname]
Move a local device to a fleet on another balena server, causing
the device to "join" the new server. The device must be running balenaOS.
For example, you could provision a device against an openBalena installation
where you perform end-to-end tests and then move it to balenaCloud when it's
ready for production.
To move a device between fleets on the same server, use the
`balena device move` command instead of `balena join`.
If you don't specify a device hostname or IP, this command will automatically
scan the local network for balenaOS devices and prompt you to select one
from an interactive picker. This may require administrator/root privileges.
Likewise, if the fleet option is not provided then a picker will be shown.
Fleets may be specified by fleet name or slug. Fleet slugs are
the recommended option, as they are unique and unambiguous. Slugs can be
listed with the `balena fleets` command. Note that slugs may change if the
fleet is renamed. Fleet names are not unique and may result in "Fleet is
ambiguous" errors at any time (even if it "used to work in the past"), for
example if the name clashes with a newly created public fleet, or with fleets
from other balena accounts that you may be invited to join under any role.
For this reason, fleet names are especially discouraged in scripts (e.g. CI
environments).
Examples:
$ balena join
$ balena join balena.local
$ balena join balena.local --fleet MyFleet
$ balena join balena.local -f myorg/myfleet
$ balena join 192.168.1.25
$ balena join 192.168.1.25 --fleet MyFleet
### Arguments
#### DEVICEIPORHOSTNAME
the IP or hostname of device
### Options
#### -f, --fleet FLEET
fleet name or slug (preferred)
#### -i, --pollInterval POLLINTERVAL
the interval in minutes to check for updates
## leave [deviceIpOrHostname]
Remove a local device from its balena fleet, causing the device to
"leave" the server it is provisioned on. This effectively makes the device
"unmanaged". The device must be running balenaOS.
The device entry on the server is preserved after running this command,
so the device can subsequently re-join the server if needed.
If you don't specify a device hostname or IP, this command will automatically
scan the local network for balenaOS devices and prompt you to select one
from an interactive picker. This may require administrator/root privileges.
Examples:
$ balena leave
$ balena leave balena.local
$ balena leave 192.168.1.25
### Arguments
#### DEVICEIPORHOSTNAME
the device IP or hostname
### Options
# Release
## release finalize &#60;commitOrId&#62;
@ -3587,56 +3564,6 @@ Examples:
### Options
# Support
## support &#60;action&#62;
Grant or revoke balena support agent access to devices or fleets
on balenaCloud. (This command does not apply to openBalena.)
Access will be automatically revoked once the specified duration has elapsed.
Duration defaults to 24h, but can be specified using --duration flag in days
or hours, e.g. '12h', '2d'.
Both --device and --fleet flags accept multiple values, specified as
a comma-separated list (with no spaces).
Fleets may be specified by fleet name or slug. Fleet slugs are
the recommended option, as they are unique and unambiguous. Slugs can be
listed with the `balena fleets` command. Note that slugs may change if the
fleet is renamed. Fleet names are not unique and may result in "Fleet is
ambiguous" errors at any time (even if it "used to work in the past"), for
example if the name clashes with a newly created public fleet, or with fleets
from other balena accounts that you may be invited to join under any role.
For this reason, fleet names are especially discouraged in scripts (e.g. CI
environments).
Examples:
balena support enable --device ab346f,cd457a --duration 3d
balena support enable --fleet myFleet --duration 12h
balena support disable -f myorg/myfleet
### Arguments
#### ACTION
enable|disable support access
### Options
#### -d, --device DEVICE
comma-separated list (no spaces) of device UUIDs
#### -f, --fleet FLEET
comma-separated list (no spaces) of fleet names or slugs (preferred)
#### -t, --duration DURATION
length of time to enable support for, in (h)ours or (d)ays, e.g. 12h, 2d
# SSH Key
## key add &#60;name&#62; [path]
@ -3729,7 +3656,57 @@ Examples:
### Options
# Tags
# Support
## support &#60;action&#62;
Grant or revoke balena support agent access to devices or fleets
on balenaCloud. (This command does not apply to openBalena.)
Access will be automatically revoked once the specified duration has elapsed.
Duration defaults to 24h, but can be specified using --duration flag in days
or hours, e.g. '12h', '2d'.
Both --device and --fleet flags accept multiple values, specified as
a comma-separated list (with no spaces).
Fleets may be specified by fleet name or slug. Fleet slugs are
the recommended option, as they are unique and unambiguous. Slugs can be
listed with the `balena fleets` command. Note that slugs may change if the
fleet is renamed. Fleet names are not unique and may result in "Fleet is
ambiguous" errors at any time (even if it "used to work in the past"), for
example if the name clashes with a newly created public fleet, or with fleets
from other balena accounts that you may be invited to join under any role.
For this reason, fleet names are especially discouraged in scripts (e.g. CI
environments).
Examples:
balena support enable --device ab346f,cd457a --duration 3d
balena support enable --fleet myFleet --duration 12h
balena support disable -f myorg/myfleet
### Arguments
#### ACTION
enable|disable support access
### Options
#### -d, --device DEVICE
comma-separated list (no spaces) of device UUIDs
#### -f, --fleet FLEET
comma-separated list (no spaces) of fleet names or slugs (preferred)
#### -t, --duration DURATION
length of time to enable support for, in (h)ours or (d)ays, e.g. 12h, 2d
# Tag
## tag rm &#60;tagKey&#62;
@ -3872,3 +3849,38 @@ List available drives which are usable for writing an OS image to.
Does not list system drives.
### Options
# Version
## version
Display version information for the balena CLI and/or Node.js. Note that the
balena CLI executable installers for Windows and macOS, and the standalone
zip packages, ship with a built-in copy of Node.js. In this case, the
reported version of Node.js regards this built-in copy, rather than any
other `node` engine that may also be available on the command prompt.
The --json option is recommended when scripting the output of this command,
because the JSON format is less likely to change and it better represents
data types like lists and empty strings. The 'jq' utility may be helpful
in shell scripts (https://stedolan.github.io/jq/manual/).
This command can also be invoked with 'balena --version' or 'balena -v'.
Examples:
$ balena version
$ balena version -a
$ balena version -j
$ balena --version
$ balena -v
### Options
#### -a, --all
include version information for additional components (Node.js)
#### -j, --json
output version information in JSON format for programmatic use

View File

@ -24,7 +24,7 @@ import {
} from './preparser';
import { CliSettings } from './utils/bootstrap';
import { onceAsync } from './utils/lazy';
import { run as mainRun } from '@oclif/core';
import { run as mainRun, settings } from '@oclif/core';
/**
* Sentry.io setup
@ -117,7 +117,14 @@ async function oclifRun(command: string[], options: AppOptions) {
const runPromise = (async function (shouldFlush: boolean) {
let isEEXIT = false;
try {
await mainRun(command, options.configPath);
if (options.development) {
// In dev mode -> use ts-node and dev plugins
process.env.NODE_ENV = 'development';
settings.debug = true;
}
// For posteriority: We can't use default oclif 'execute' as
// We customize error handling and flushing
await mainRun(command, options.loadOptions ?? options.dir);
} catch (error) {
// oclif sometimes exits with ExitError code EEXIT 0 (not an error),
// for example the `balena help` command.
@ -151,7 +158,7 @@ async function oclifRun(command: string[], options: AppOptions) {
}
/** CLI entrypoint. Called by the `bin/balena` and `bin/balena-dev` scripts. */
export async function run(cliArgs = process.argv, options: AppOptions = {}) {
export async function run(cliArgs = process.argv, options: AppOptions) {
try {
const { setOfflineModeEnvVars, normalizeEnvVars, pkgExec } = await import(
'./utils/bootstrap'

View File

@ -16,20 +16,20 @@
*/
import { Args, Flags } from '@oclif/core';
import Command from '../command';
import { getBalenaSdk } from '../utils/lazy';
import * as cf from '../utils/common-flags';
import * as compose from '../utils/compose';
import Command from '../../command';
import { getBalenaSdk } from '../../utils/lazy';
import * as cf from '../../utils/common-flags';
import * as compose from '../../utils/compose';
import type { ApplicationType, BalenaSDK } from 'balena-sdk';
import {
buildArgDeprecation,
dockerignoreHelp,
registrySecretsHelp,
} from '../utils/messages';
import type { ComposeCliFlags, ComposeOpts } from '../utils/compose-types';
import { buildProject, composeCliFlags } from '../utils/compose_ts';
import type { BuildOpts, DockerCliFlags } from '../utils/docker';
import { dockerCliFlags } from '../utils/docker';
} from '../../utils/messages';
import type { ComposeCliFlags, ComposeOpts } from '../../utils/compose-types';
import { buildProject, composeCliFlags } from '../../utils/compose_ts';
import type { BuildOpts, DockerCliFlags } from '../../utils/docker';
import { dockerCliFlags } from '../../utils/docker';
// TODO: For this special one we can't use Interfaces.InferredFlags/InferredArgs
// because of the 'registry-secrets' type which is defined in the actual code
@ -67,6 +67,7 @@ ${dockerignoreHelp}
public static examples = [
'$ balena build --fleet myFleet',
'$ balena build ./source/ --fleet myorg/myfleet',
'$ balena build ./source/ --fleet myorg/myfleet --docker-compose my-custom-compose.yml',
'$ balena build --deviceType raspberrypi3 --arch armv7hf --emulated',
'$ balena build --docker /var/run/docker.sock --fleet myFleet # Linux, Mac',
'$ balena build --docker //./pipe/docker_engine --fleet myFleet # Windows',
@ -148,14 +149,14 @@ ${dockerignoreHelp}
(opts.fleet == null && (opts.arch == null || opts.deviceType == null)) ||
(opts.fleet != null && (opts.arch != null || opts.deviceType != null))
) {
const { ExpectedError } = await import('../errors');
const { ExpectedError } = await import('../../errors');
throw new ExpectedError(
'You must specify either a fleet (-f), or the device type (-d) and architecture (-A)',
);
}
// Validate project directory
const { validateProjectDirectory } = await import('../utils/compose_ts');
const { validateProjectDirectory } = await import('../../utils/compose_ts');
const { dockerfilePath, registrySecrets } = await validateProjectDirectory(
sdk,
{
@ -172,7 +173,7 @@ ${dockerignoreHelp}
protected async getAppAndResolveArch(opts: FlagsDef) {
if (opts.fleet) {
const { getAppWithArch } = await import('../utils/helpers');
const { getAppWithArch } = await import('../../utils/helpers');
const app = await getAppWithArch(opts.fleet);
opts.arch = app.arch;
opts.deviceType = app.is_for__device_type[0].slug;
@ -181,7 +182,7 @@ ${dockerignoreHelp}
}
protected async prepareBuild(options: FlagsDef) {
const { getDocker, generateBuildOpts } = await import('../utils/docker');
const { getDocker, generateBuildOpts } = await import('../../utils/docker');
const [docker, buildOpts, composeOpts] = await Promise.all([
getDocker(options),
generateBuildOpts(options),
@ -209,7 +210,7 @@ ${dockerignoreHelp}
*/
protected async buildProject(
docker: import('dockerode'),
logger: import('../utils/logger'),
logger: import('../../utils/logger'),
composeOpts: ComposeOpts,
opts: {
app?: {
@ -221,7 +222,7 @@ ${dockerignoreHelp}
buildOpts: BuildOpts;
},
) {
const { loadProject } = await import('../utils/compose_ts');
const { loadProject } = await import('../../utils/compose_ts');
const project = await loadProject(
logger,

View File

@ -259,6 +259,8 @@ export default class ConfigGenerateCmd extends Command {
if (!options.fleet && options.deviceType) {
throw new ExpectedError(this.deviceTypeNotAllowedMessage);
}
const { normalizeOsVersion } = await import('../../utils/normalization');
options.version = normalizeOsVersion(options.version);
const { validateDevOptionAndWarn } = await import('../../utils/config');
await validateDevOptionAndWarn(options.dev, options.version);
}

View File

@ -18,31 +18,31 @@
import { Args, Flags } from '@oclif/core';
import type { ImageDescriptor } from '@balena/compose/dist/parse';
import Command from '../command';
import { ExpectedError } from '../errors';
import { getBalenaSdk, getChalk, stripIndent } from '../utils/lazy';
import Command from '../../command';
import { ExpectedError } from '../../errors';
import { getBalenaSdk, getChalk, stripIndent } from '../../utils/lazy';
import {
dockerignoreHelp,
registrySecretsHelp,
buildArgDeprecation,
} from '../utils/messages';
import * as ca from '../utils/common-args';
import * as compose from '../utils/compose';
} from '../../utils/messages';
import * as ca from '../../utils/common-args';
import * as compose from '../../utils/compose';
import type {
BuiltImage,
ComposeCliFlags,
ComposeOpts,
Release as ComposeReleaseInfo,
} from '../utils/compose-types';
import type { BuildOpts, DockerCliFlags } from '../utils/docker';
} from '../../utils/compose-types';
import type { BuildOpts, DockerCliFlags } from '../../utils/docker';
import {
applyReleaseTagKeysAndValues,
buildProject,
composeCliFlags,
isBuildConfig,
parseReleaseTagKeysAndValues,
} from '../utils/compose_ts';
import { dockerCliFlags } from '../utils/docker';
} from '../../utils/compose_ts';
import { dockerCliFlags } from '../../utils/docker';
import type { ApplicationType, DeviceType, Release } from 'balena-sdk';
interface ApplicationWithArch {
@ -98,6 +98,7 @@ ${dockerignoreHelp}
public static examples = [
'$ balena deploy myFleet',
'$ balena deploy myorg/myfleet --build --source myBuildDir/',
'$ balena deploy myorg/myfleet --builld --source myBuildDir/ --docker-compose my-custom-compose.yml',
'$ balena deploy myorg/myfleet --build --source myBuildDir/ --note "this is the note for this release"',
'$ balena deploy myorg/myfleet myRepo/myImage',
'$ balena deploy myFleet myRepo/myImage --release-tag key1 "" key2 "value2 with spaces"',
@ -175,7 +176,7 @@ ${dockerignoreHelp}
const sdk = getBalenaSdk();
const { getRegistrySecrets, validateProjectDirectory } = await import(
'../utils/compose_ts'
'../../utils/compose_ts'
);
const { releaseTagKeys, releaseTagValues } = parseReleaseTagKeysAndValues(
@ -199,10 +200,10 @@ ${dockerignoreHelp}
(options as FlagsDef)['registry-secrets'] = registrySecrets;
}
const helpers = await import('../utils/helpers');
const helpers = await import('../../utils/helpers');
const app = await helpers.getAppWithArch(fleet);
const dockerUtils = await import('../utils/docker');
const dockerUtils = await import('../../utils/docker');
const [docker, buildOpts, composeOpts] = await Promise.all([
dockerUtils.getDocker(options),
dockerUtils.generateBuildOpts(options as FlagsDef),
@ -232,7 +233,7 @@ ${dockerignoreHelp}
async deployProject(
docker: import('dockerode'),
logger: import('../utils/logger'),
logger: import('../../utils/logger'),
composeOpts: ComposeOpts,
opts: {
app: ApplicationWithArch; // the application instance to deploy to
@ -250,7 +251,7 @@ ${dockerignoreHelp}
const doodles = await import('resin-doodles');
const sdk = getBalenaSdk();
const { deployProject: $deployProject, loadProject } = await import(
'../utils/compose_ts'
'../../utils/compose_ts'
);
const appType = opts.app.application_type[0];
@ -332,7 +333,7 @@ ${dockerignoreHelp}
let release: Release | ComposeReleaseInfo['release'];
if (appType.slug === 'legacy-v1' || appType.slug === 'legacy-v2') {
const { deployLegacy } = require('../utils/deploy-legacy');
const { deployLegacy } = require('../../utils/deploy-legacy');
const msg = getChalk().yellow(
'Target fleet requires legacy deploy method.',

View File

@ -20,6 +20,7 @@ import Command from '../../command';
import * as cf from '../../utils/common-flags';
import { expandForAppName } from '../../utils/helpers';
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
import { jsonInfo } from '../../utils/messages';
import type { Application, Release } from 'balena-sdk';
@ -45,10 +46,13 @@ export default class DeviceCmd extends Command {
Show info about a single device.
Show information about a single device.
${jsonInfo.split('\n').join('\n\t\t')}
`;
public static examples = [
'$ balena device 7cf02a6',
'$ balena device 7cf02a6 --view',
'$ balena device 7cf02a6 --json',
];
public static args = {
@ -61,6 +65,7 @@ export default class DeviceCmd extends Command {
public static usage = 'device <uuid>';
public static flags = {
json: cf.json,
help: cf.help,
view: Flags.boolean({
default: false,
@ -76,33 +81,45 @@ export default class DeviceCmd extends Command {
const balena = getBalenaSdk();
const device = (await balena.models.device.get(params.uuid, {
$select: [
'device_name',
'id',
'overall_status',
'is_online',
'ip_address',
'mac_address',
'last_connectivity_event',
'uuid',
'supervisor_version',
'is_web_accessible',
'note',
'os_version',
'memory_usage',
'memory_total',
'public_address',
'storage_block_device',
'storage_usage',
'storage_total',
'cpu_usage',
'cpu_temp',
'cpu_id',
'is_undervolted',
],
...expandForAppName,
})) as ExtendedDevice;
const device = (await balena.models.device.get(
params.uuid,
options.json
? {
$expand: {
device_tag: {
$select: ['tag_key', 'value'],
},
...expandForAppName.$expand,
},
}
: {
$select: [
'device_name',
'id',
'overall_status',
'is_online',
'ip_address',
'mac_address',
'last_connectivity_event',
'uuid',
'supervisor_version',
'is_web_accessible',
'note',
'os_version',
'memory_usage',
'memory_total',
'public_address',
'storage_block_device',
'storage_usage',
'storage_total',
'cpu_usage',
'cpu_temp',
'cpu_id',
'is_undervolted',
],
...expandForAppName,
},
)) as ExtendedDevice;
if (options.view) {
const open = await import('open');
@ -166,6 +183,11 @@ export default class DeviceCmd extends Command {
);
}
if (options.json) {
console.log(JSON.stringify(device, null, 4));
return;
}
console.log(
getVisuals().table.vertical(device, [
`$${device.device_name}$`,

View File

@ -37,6 +37,7 @@ export default class DeviceOsUpdateCmd extends Command {
'$ balena device os-update 23c73a1',
'$ balena device os-update 23c73a1 --version 2.101.7',
'$ balena device os-update 23c73a1 --version 2.31.0+rev1.prod',
'$ balena device os-update 23c73a1 --include-draft',
];
public static args = {
@ -51,6 +52,12 @@ export default class DeviceOsUpdateCmd extends Command {
public static flags = {
version: Flags.string({
description: 'a balenaOS version',
exclusive: ['include-draft'],
}),
'include-draft': Flags.boolean({
description: 'include pre-release balenaOS versions',
default: false,
exclusive: ['version'],
}),
yes: cf.yes,
help: cf.help,
@ -86,10 +93,25 @@ export default class DeviceOsUpdateCmd extends Command {
);
}
let includeDraft = options['include-draft'];
if (!includeDraft && options.version != null) {
const bSemver = await import('balena-semver');
const parsedVersion = bSemver.parse(options.version);
// When the user provides a draft version, we need to pass `includeDraft`
// to the os.getSupportedOsUpdateVersions() since w/o it the results
// will for sure not include the user provided version and the command
// would return a "not in the Host OS update targets" error.
includeDraft =
parsedVersion != null && parsedVersion.prerelease.length > 0;
}
// Get supported OS update versions
const hupVersionInfo = await sdk.models.os.getSupportedOsUpdateVersions(
is_of__device_type[0].slug,
currentOsVersion,
{
includeDraft,
},
);
if (hupVersionInfo.versions.length === 0) {
throw new ExpectedError(
@ -100,6 +122,8 @@ export default class DeviceOsUpdateCmd extends Command {
// Get target OS version
let targetOsVersion = options.version;
if (targetOsVersion != null) {
const { normalizeOsVersion } = await import('../../utils/normalization');
targetOsVersion = normalizeOsVersion(targetOsVersion);
if (!hupVersionInfo.versions.includes(targetOsVersion)) {
throw new ExpectedError(
`The provided version ${targetOsVersion} is not in the Host OS update targets for this device`,

View File

@ -18,11 +18,11 @@ import { Flags } from '@oclif/core';
import type { Interfaces } from '@oclif/core';
import type * as SDK from 'balena-sdk';
import * as _ from 'lodash';
import Command from '../command';
import { ExpectedError } from '../errors';
import * as cf from '../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../utils/lazy';
import { applicationIdInfo } from '../utils/messages';
import Command from '../../command';
import { ExpectedError } from '../../errors';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
import { applicationIdInfo } from '../../utils/messages';
type FlagsDef = Interfaces.InferredFlags<typeof EnvsCmd.flags>;
@ -124,12 +124,16 @@ export default class EnvsCmd extends Command {
const balena = getBalenaSdk();
let fleetSlug: string | undefined = options.fleet
? await (await import('../utils/sdk')).getFleetSlug(balena, options.fleet)
? await (
await import('../../utils/sdk')
).getFleetSlug(balena, options.fleet)
: undefined;
let fullUUID: string | undefined; // as oppposed to the short, 7-char UUID
if (options.device) {
const { getDeviceAndMaybeAppFromUUID } = await import('../utils/cloud');
const { getDeviceAndMaybeAppFromUUID } = await import(
'../../utils/cloud'
);
const [device, app] = await getDeviceAndMaybeAppFromUUID(
balena,
options.device,
@ -182,7 +186,7 @@ export default class EnvsCmd extends Command {
}
if (options.json) {
const { pickAndRename } = await import('../utils/helpers');
const { pickAndRename } = await import('../../utils/helpers');
const mapped = varArray.map((o) => pickAndRename(o, fields));
this.log(JSON.stringify(mapped, null, 4));
} else {

View File

@ -17,9 +17,9 @@
import type * as BalenaSdk from 'balena-sdk';
import Command from '../command';
import * as cf from '../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../utils/lazy';
import Command from '../../command';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy';
interface ExtendedApplication extends ApplicationWithDeviceTypeSlug {
device_count: number;

View File

@ -16,11 +16,11 @@
*/
import { Args, Flags } from '@oclif/core';
import Command from '../command';
import * as cf from '../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../utils/lazy';
import { applicationIdInfo } from '../utils/messages';
import { parseAsLocalHostnameOrIp } from '../utils/validation';
import Command from '../../command';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { applicationIdInfo } from '../../utils/messages';
import { parseAsLocalHostnameOrIp } from '../../utils/validation';
export default class JoinCmd extends Command {
public static description = stripIndent`
@ -78,7 +78,7 @@ export default class JoinCmd extends Command {
public async run() {
const { args: params, flags: options } = await this.parse(JoinCmd);
const promote = await import('../utils/promote');
const promote = await import('../../utils/promote');
const sdk = getBalenaSdk();
const logger = await Command.getLogger();
return promote.join(

View File

@ -15,9 +15,9 @@
* limitations under the License.
*/
import Command from '../command';
import * as cf from '../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../utils/lazy';
import Command from '../../command';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
export default class KeysCmd extends Command {
public static description = stripIndent`

View File

@ -16,10 +16,10 @@
*/
import { Args } from '@oclif/core';
import Command from '../command';
import * as cf from '../utils/common-flags';
import { stripIndent } from '../utils/lazy';
import { parseAsLocalHostnameOrIp } from '../utils/validation';
import Command from '../../command';
import * as cf from '../../utils/common-flags';
import { stripIndent } from '../../utils/lazy';
import { parseAsLocalHostnameOrIp } from '../../utils/validation';
export default class LeaveCmd extends Command {
public static description = stripIndent`
@ -62,7 +62,7 @@ export default class LeaveCmd extends Command {
public async run() {
const { args: params } = await this.parse(LeaveCmd);
const promote = await import('../utils/promote');
const promote = await import('../../utils/promote');
const logger = await Command.getLogger();
return promote.leave(logger, params.deviceIpOrHostname);
}

View File

@ -16,10 +16,10 @@
*/
import { Flags, Args } from '@oclif/core';
import Command from '../command';
import * as cf from '../utils/common-flags';
import { getBalenaSdk, stripIndent, getCliForm } from '../utils/lazy';
import { ExpectedError } from '../errors';
import Command from '../../command';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy';
import { ExpectedError } from '../../errors';
import type { WhoamiResult } from 'balena-sdk';
interface FlagsDef {
@ -123,7 +123,7 @@ export default class LoginCmd extends Command {
const { flags: options, args: params } = await this.parse(LoginCmd);
const balena = getBalenaSdk();
const messages = await import('../utils/messages');
const messages = await import('../../utils/messages');
const balenaUrl = await balena.settings.get('balenaUrl');
// Consolidate user/email options
@ -202,16 +202,16 @@ ${messages.reachingOut}`);
}
// Credentials
else if (loginOptions.credentials) {
const patterns = await import('../utils/patterns');
const patterns = await import('../../utils/patterns');
return patterns.authenticate(loginOptions);
}
// Web
else if (loginOptions.web) {
const auth = await import('../auth');
const auth = await import('../../auth');
await auth.login({ port: loginOptions.port });
return;
} else {
const patterns = await import('../utils/patterns');
const patterns = await import('../../utils/patterns');
// User had not selected login preference, prompt interactively
const loginType = await patterns.askLoginType();
if (loginType === 'register') {

View File

@ -15,8 +15,8 @@
* limitations under the License.
*/
import Command from '../command';
import { getBalenaSdk, stripIndent } from '../utils/lazy';
import Command from '../../command';
import { getBalenaSdk, stripIndent } from '../../utils/lazy';
export default class LogoutCmd extends Command {
public static description = stripIndent`

View File

@ -16,9 +16,9 @@
*/
import { Flags, Args } from '@oclif/core';
import Command from '../command';
import * as cf from '../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../utils/lazy';
import Command from '../../command';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { LogMessage } from 'balena-sdk';
const MAX_RETRY = 1000;
@ -96,14 +96,14 @@ export default class LogsCmd extends Command {
const { args: params, flags: options } = await this.parse(LogsCmd);
const balena = getBalenaSdk();
const { serviceIdToName } = await import('../utils/cloud');
const { serviceIdToName } = await import('../../utils/cloud');
const { connectAndDisplayDeviceLogs, displayLogObject } = await import(
'../utils/device/logs'
'../../utils/device/logs'
);
const { validateIPAddress, validateDotLocalUrl } = await import(
'../utils/validation'
'../../utils/validation'
);
const Logger = await import('../utils/logger');
const Logger = await import('../../utils/logger');
const logger = Logger.getLogger();
@ -132,13 +132,13 @@ export default class LogsCmd extends Command {
validateDotLocalUrl(params.device)
) {
// Logs from local device
const { DeviceAPI } = await import('../utils/device/api');
const { DeviceAPI } = await import('../../utils/device/api');
const deviceApi = new DeviceAPI(logger, params.device);
logger.logDebug('Checking we can access device');
try {
await deviceApi.ping();
} catch (e) {
const { ExpectedError } = await import('../errors');
const { ExpectedError } = await import('../../errors');
throw new ExpectedError(
`Cannot access device at address ${params.device}. Device may not be in local mode.`,
);

View File

@ -16,10 +16,10 @@
*/
import { Flags, Args } from '@oclif/core';
import Command from '../command';
import { ExpectedError } from '../errors';
import * as cf from '../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../utils/lazy';
import Command from '../../command';
import { ExpectedError } from '../../errors';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy';
export default class NoteCmd extends Command {
public static description = stripIndent`

View File

@ -15,9 +15,9 @@
* limitations under the License.
*/
import Command from '../command';
import * as cf from '../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../utils/lazy';
import Command from '../../command';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
export default class OrgsCmd extends Command {
public static description = stripIndent`
@ -38,7 +38,7 @@ export default class OrgsCmd extends Command {
public async run() {
await this.parse(OrgsCmd);
const { getOwnOrganizations } = await import('../utils/sdk');
const { getOwnOrganizations } = await import('../../utils/sdk');
// Get organizations
const organizations = await getOwnOrganizations(getBalenaSdk(), {

View File

@ -216,9 +216,15 @@ export default class OsConfigureCmd extends Command {
configJson = JSON.parse(rawConfig);
}
const osVersion =
const { normalizeOsVersion } = await import('../../utils/normalization');
const osVersion = normalizeOsVersion(
options.version ||
(await getOsVersionFromImage(params.image, deviceTypeManifest, devInit));
(await getOsVersionFromImage(
params.image,
deviceTypeManifest,
devInit,
)),
);
const { validateDevOptionAndWarn } = await import('../../utils/config');
await validateDevOptionAndWarn(options.dev, osVersion);

View File

@ -48,15 +48,33 @@ export default class OsVersionsCmd extends Command {
description: 'select balenaOS ESR versions',
default: false,
}),
'include-draft': Flags.boolean({
description: 'include pre-release balenaOS versions',
default: false,
}),
};
public async run() {
const { args: params, flags: options } = await this.parse(OsVersionsCmd);
if (options['include-draft']) {
const { warnify } = await import('../../utils/messages');
console.error(
warnify(stripIndent`
Using pre-release balenaOS versions is only supported for OS updates
and not for OS image downloads.
`),
);
}
const { formatOsVersion, getOsVersions } = await import(
'../../utils/cloud'
);
const vs = await getOsVersions(params.type, !!options.esr);
const vs = await getOsVersions(
params.type,
!!options.esr,
options['include-draft'],
);
console.log(vs.map((v) => formatOsVersion(v)).join('\n'));
}

View File

@ -15,18 +15,18 @@
* limitations under the License.
*/
import Command from '../command';
import { ExpectedError } from '../errors';
import * as cf from '../utils/common-flags';
import Command from '../../command';
import { ExpectedError } from '../../errors';
import * as cf from '../../utils/common-flags';
import {
getBalenaSdk,
getCliForm,
getVisuals,
stripIndent,
} from '../utils/lazy';
import { applicationIdInfo } from '../utils/messages';
import { dockerConnectionCliFlags } from '../utils/docker';
import { parseAsInteger } from '../utils/validation';
} from '../../utils/lazy';
import { applicationIdInfo } from '../../utils/messages';
import { dockerConnectionCliFlags } from '../../utils/docker';
import { parseAsInteger } from '../../utils/validation';
import { Flags, Args } from '@oclif/core';
import * as _ from 'lodash';
@ -148,7 +148,7 @@ Can be repeated to add multiple certificates.\
const balenaPreload = await import('balena-preload');
const visuals = getVisuals();
const nodeCleanup = await import('node-cleanup');
const { instanceOf } = await import('../errors');
const { instanceOf } = await import('../../errors');
// Check image file exists
try {
@ -171,7 +171,9 @@ Can be repeated to add multiple certificates.\
// balena-preload currently does not work with numerical app IDs
// Load app here, and use app slug from hereon
const fleetSlug: string | undefined = options.fleet
? await (await import('../utils/sdk')).getFleetSlug(balena, options.fleet)
? await (
await import('../../utils/sdk')
).getFleetSlug(balena, options.fleet)
: undefined;
const progressBars: {
@ -227,7 +229,7 @@ Can be repeated to add multiple certificates.\
}
// Get a configured dockerode instance
const dockerUtils = await import('../utils/docker');
const dockerUtils = await import('../../utils/docker');
const docker = await dockerUtils.getDocker(options);
const preloader = new balenaPreload.Preloader(
undefined,
@ -479,7 +481,7 @@ Would you like to disable automatic updates for this fleet now?\
}
async getAppWithReleases(balenaSdk: BalenaSDK, slug: string) {
const { getApplication } = await import('../utils/sdk');
const { getApplication } = await import('../../utils/sdk');
return await getApplication(balenaSdk, slug, {
$expand: this.applicationExpandOptions,

View File

@ -17,18 +17,18 @@
import { Flags, Args } from '@oclif/core';
import type { Interfaces } from '@oclif/core';
import Command from '../command';
import * as cf from '../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../utils/lazy';
import { dockerignoreHelp, registrySecretsHelp } from '../utils/messages';
import Command from '../../command';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { dockerignoreHelp, registrySecretsHelp } from '../../utils/messages';
import type { BalenaSDK } from 'balena-sdk';
import { ExpectedError, instanceOf } from '../errors';
import { ExpectedError, instanceOf } from '../../errors';
import { RegistrySecrets } from '@balena/compose/dist/multibuild';
import { lowercaseIfSlug } from '../utils/normalization';
import { lowercaseIfSlug } from '../../utils/normalization';
import {
applyReleaseTagKeysAndValues,
parseReleaseTagKeysAndValues,
} from '../utils/compose_ts';
} from '../../utils/compose_ts';
enum BuildTarget {
Cloud,
@ -78,6 +78,7 @@ export default class PushCmd extends Command {
'$ balena push myFleet -s <source directory>',
'$ balena push myFleet --source <source directory> --note "this is the note for this release"',
'$ balena push myFleet --release-tag key1 "" key2 "value2 with spaces"',
'$ balena push myorg/myfleet --docker-compose my-custom-compose.yml',
'$ balena push myorg/myfleet',
'',
'$ balena push 10.0.0.1',
@ -121,6 +122,10 @@ export default class PushCmd extends Command {
description:
'Alternative Dockerfile name/path, relative to the source folder',
}),
'docker-compose': Flags.string({
description:
'Alternative compose yml file, relative to the source folder',
}),
nocache: Flags.boolean({
description: stripIndent`
Don't use cached layers of previously built images for this project. This
@ -233,7 +238,7 @@ export default class PushCmd extends Command {
logger.logDebug(`Using build source directory: ${options.source} `);
const sdk = getBalenaSdk();
const { validateProjectDirectory } = await import('../utils/compose_ts');
const { validateProjectDirectory } = await import('../../utils/compose_ts');
const { dockerfilePath, registrySecrets } = await validateProjectDirectory(
sdk,
{
@ -276,8 +281,8 @@ export default class PushCmd extends Command {
dockerfilePath: string,
registrySecrets: RegistrySecrets,
) {
const remote = await import('../utils/remote-build');
const { getApplication } = await import('../utils/sdk');
const remote = await import('../../utils/remote-build');
const { getApplication } = await import('../../utils/sdk');
// Check for invalid options
const localOnlyOptions: Array<keyof FlagsDef> = [
@ -356,7 +361,7 @@ export default class PushCmd extends Command {
'is only valid when pushing to a fleet',
);
const deviceDeploy = await import('../utils/device/deploy');
const deviceDeploy = await import('../../utils/device/deploy');
try {
await deviceDeploy.deployToDevice({
@ -365,6 +370,7 @@ export default class PushCmd extends Command {
dockerfilePath,
registrySecrets,
multiDockerignore: options['multi-dockerignore'],
composefileName: options['docker-compose'],
nocache: options.nocache,
pull: options.pull,
noParentCheck: options['noparent-check'],
@ -376,7 +382,7 @@ export default class PushCmd extends Command {
convertEol: !options['noconvert-eol'],
});
} catch (e) {
const { BuildError } = await import('../utils/device/errors');
const { BuildError } = await import('../../utils/device/errors');
if (instanceOf(e, BuildError)) {
throw new ExpectedError(e.toString());
} else {
@ -386,7 +392,9 @@ export default class PushCmd extends Command {
}
protected async getBuildTarget(appOrDevice: string): Promise<BuildTarget> {
const { validateLocalHostnameOrIp } = await import('../utils/validation');
const { validateLocalHostnameOrIp } = await import(
'../../utils/validation'
);
return validateLocalHostnameOrIp(appOrDevice)
? BuildTarget.Device

View File

@ -16,12 +16,12 @@
*/
import { Args } from '@oclif/core';
import Command from '../command';
import * as cf from '../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../utils/lazy';
import { applicationNameNote } from '../utils/messages';
import Command from '../../command';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
import { applicationNameNote } from '../../utils/messages';
import type * as BalenaSdk from 'balena-sdk';
import { jsonInfo } from '../utils/messages';
import { jsonInfo } from '../../utils/messages';
export default class ReleasesCmd extends Command {
public static description = stripIndent`
@ -67,7 +67,7 @@ export default class ReleasesCmd extends Command {
];
const balena = getBalenaSdk();
const { getFleetSlug } = await import('../utils/sdk');
const { getFleetSlug } = await import('../../utils/sdk');
const releases = await balena.models.release.getAllByApplication(
await getFleetSlug(balena, params.fleet),

View File

@ -16,9 +16,9 @@
*/
import { Flags } from '@oclif/core';
import Command from '../command';
import * as cf from '../utils/common-flags';
import { getCliUx, stripIndent } from '../utils/lazy';
import Command from '../../command';
import * as cf from '../../utils/common-flags';
import { getCliUx, stripIndent } from '../../utils/lazy';
export default class ScanCmd extends Command {
public static description = stripIndent`
@ -64,9 +64,11 @@ export default class ScanCmd extends Command {
public async run() {
const _ = await import('lodash');
const { discoverLocalBalenaOsDevices } = await import('../utils/discover');
const { discoverLocalBalenaOsDevices } = await import(
'../../utils/discover'
);
const prettyjson = await import('prettyjson');
const dockerUtils = await import('../utils/docker');
const dockerUtils = await import('../../utils/docker');
const dockerPort = 2375;
const dockerTimeout = 2000;

View File

@ -15,9 +15,9 @@
* limitations under the License.
*/
import Command from '../command';
import * as cf from '../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../utils/lazy';
import Command from '../../command';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy';
export default class SettingsCmd extends Command {
public static description = stripIndent`

View File

@ -16,10 +16,13 @@
*/
import { Flags, Args } from '@oclif/core';
import Command from '../command';
import * as cf from '../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../utils/lazy';
import { parseAsInteger, validateLocalHostnameOrIp } from '../utils/validation';
import Command from '../../command';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import {
parseAsInteger,
validateLocalHostnameOrIp,
} from '../../utils/validation';
export default class SshCmd extends Command {
public static description = stripIndent`
@ -108,7 +111,7 @@ export default class SshCmd extends Command {
// Local connection
if (validateLocalHostnameOrIp(params.fleetOrDevice)) {
const { performLocalDeviceSSH } = await import('../utils/device/ssh');
const { performLocalDeviceSSH } = await import('../../utils/device/ssh');
return await performLocalDeviceSSH({
hostname: params.fleetOrDevice,
port: options.port || 'local',
@ -119,8 +122,8 @@ export default class SshCmd extends Command {
}
// Remote connection
const { getProxyConfig } = await import('../utils/helpers');
const { getOnlineTargetDeviceUuid } = await import('../utils/patterns');
const { getProxyConfig } = await import('../../utils/helpers');
const { getOnlineTargetDeviceUuid } = await import('../../utils/patterns');
const sdk = getBalenaSdk();
const proxyConfig = getProxyConfig();
@ -134,7 +137,7 @@ export default class SshCmd extends Command {
params.fleetOrDevice,
);
const { which } = await import('../utils/which');
const { which } = await import('../../utils/which');
const [whichProxytunnel, { username }, proxyUrl] = await Promise.all([
useProxy ? which('proxytunnel', false) : undefined,
@ -185,7 +188,9 @@ export default class SshCmd extends Command {
// that we know exists and is accessible
let containerId: string | undefined;
if (params.service != null) {
const { getContainerIdForService } = await import('../utils/device/ssh');
const { getContainerIdForService } = await import(
'../../utils/device/ssh'
);
containerId = await getContainerIdForService({
deviceUuid,
hostname: `ssh.${proxyUrl}`,
@ -202,7 +207,7 @@ export default class SshCmd extends Command {
} else {
accessCommand = `host ${deviceUuid}`;
}
const { runRemoteCommand } = await import('../utils/ssh');
const { runRemoteCommand } = await import('../../utils/ssh');
await runRemoteCommand({
cmd: accessCommand,
hostname: `ssh.${proxyUrl}`,

View File

@ -16,11 +16,11 @@
*/
import { Flags, Args } from '@oclif/core';
import Command from '../command';
import { ExpectedError } from '../errors';
import * as cf from '../utils/common-flags';
import { getBalenaSdk, getCliUx, stripIndent } from '../utils/lazy';
import { applicationIdInfo } from '../utils/messages';
import Command from '../../command';
import { ExpectedError } from '../../errors';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, getCliUx, stripIndent } from '../../utils/lazy';
import { applicationIdInfo } from '../../utils/messages';
export default class SupportCmd extends Command {
public static description = stripIndent`
@ -116,7 +116,7 @@ export default class SupportCmd extends Command {
ux.action.stop();
}
const { getFleetSlug } = await import('../utils/sdk');
const { getFleetSlug } = await import('../../utils/sdk');
// Process applications
for (const appName of appNames) {

View File

@ -15,11 +15,11 @@
* limitations under the License.
*/
import Command from '../command';
import { ExpectedError } from '../errors';
import * as cf from '../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../utils/lazy';
import { applicationIdInfo } from '../utils/messages';
import Command from '../../command';
import { ExpectedError } from '../../errors';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
import { applicationIdInfo } from '../../utils/messages';
export default class TagsCmd extends Command {
public static description = stripIndent`
@ -71,7 +71,7 @@ export default class TagsCmd extends Command {
let tags;
if (options.fleet) {
const { getFleetSlug } = await import('../utils/sdk');
const { getFleetSlug } = await import('../../utils/sdk');
tags = await balena.models.application.tags.getAllByApplication(
await getFleetSlug(balena, options.fleet),
);
@ -81,7 +81,7 @@ export default class TagsCmd extends Command {
}
if (options.release) {
const { disambiguateReleaseParam } = await import(
'../utils/normalization'
'../../utils/normalization'
);
const releaseParam = await disambiguateReleaseParam(
balena,

View File

@ -16,15 +16,15 @@
*/
import { Flags, Args } from '@oclif/core';
import Command from '../command';
import Command from '../../command';
import {
NoPortsDefinedError,
InvalidPortMappingError,
ExpectedError,
} from '../errors';
import * as cf from '../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../utils/lazy';
import { lowercaseIfSlug } from '../utils/normalization';
} from '../../errors';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { lowercaseIfSlug } from '../../utils/normalization';
import type { Server, Socket } from 'net';
@ -122,7 +122,7 @@ export default class TunnelCmd extends Command {
}
// Ascertain device uuid
const { getOnlineTargetDeviceUuid } = await import('../utils/patterns');
const { getOnlineTargetDeviceUuid } = await import('../../utils/patterns');
const uuid = await getOnlineTargetDeviceUuid(sdk, params.deviceOrFleet);
logger.logInfo(`Opening a tunnel to ${uuid}...`);
@ -133,7 +133,9 @@ export default class TunnelCmd extends Command {
})
.map(async ({ localPort, localAddress, remotePort }) => {
try {
const { tunnelConnectionToDevice } = await import('../utils/tunnel');
const { tunnelConnectionToDevice } = await import(
'../../utils/tunnel'
);
const handler = await tunnelConnectionToDevice(uuid, remotePort, sdk);
const { createServer } = await import('net');

View File

@ -16,8 +16,8 @@
*/
import { Flags } from '@oclif/core';
import Command from '../command';
import { stripIndent } from '../utils/lazy';
import Command from '../../command';
import { stripIndent } from '../../utils/lazy';
export interface JsonVersions {
'balena-cli': string;
@ -72,7 +72,7 @@ export default class VersionCmd extends Command {
public async run() {
const { flags: options } = await this.parse(VersionCmd);
const versions: JsonVersions = {
'balena-cli': (await import('../../package.json')).version,
'balena-cli': (await import('../../../package.json')).version,
'Node.js':
process.version && process.version.startsWith('v')
? process.version.slice(1)

View File

@ -15,8 +15,8 @@
* limitations under the License.
*/
import Command from '../command';
import { getBalenaSdk, getVisuals, stripIndent } from '../utils/lazy';
import Command from '../../command';
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
export default class WhoamiCmd extends Command {
public static description = stripIndent`

View File

@ -47,6 +47,12 @@ export class NoPortsDefinedError extends ExpectedError {
export class SIGINTError extends ExpectedError {}
export class CompositionFileNotFoundError extends ExpectedError {
constructor(filePath: string) {
super(`Composition file not found at: "${filePath}"`);
}
}
/**
* instanceOf is a more reliable implementation of the plain `instanceof`
* typescript operator, for use with TypedError errors when the error
@ -211,7 +217,6 @@ const EXPECTED_ERROR_REGEXES = [
/^BalenaOrganizationNotFound/, // balena-sdk
/Request error: Unauthorized$/, // balena-sdk
/^Missing \d+ required arg/, // oclif parser: RequiredArgsError
/Missing required flag/, // oclif parser: RequiredFlagError
/^Unexpected argument/, // oclif parser: UnexpectedArgsError
/to be one of/, // oclif parser: FlagInvalidOptionError, ArgInvalidOptionError
/must also be provided when using/, // oclif parser (depends-on)

View File

@ -50,7 +50,7 @@ export default class BalenaHelp extends Help {
const command = this.config.findCommand(subject);
if (command) {
await this.showCommandHelp(await command.load());
await this.showCommandHelp(command);
return;
}

View File

@ -15,12 +15,16 @@
* limitations under the License.
*/
import type { Interfaces } from '@oclif/core';
export let unsupportedFlag = false;
export interface AppOptions {
// Prevent the default behavior of flushing stdout after running a command
noFlush?: boolean;
configPath?: string;
development?: boolean;
dir: string;
loadOptions?: Interfaces.LoadOptions;
}
export async function preparseArgs(argv: string[]): Promise<string[]> {

View File

@ -31,6 +31,7 @@ export async function applicationCreateBase(
name: params.name,
deviceType,
organization,
applicationClass: resource,
});
// Output

View File

@ -200,22 +200,23 @@ async function resolveOSVersion(
version: string,
): Promise<string> {
if (['menu', 'menu-esr'].includes(version)) {
return await selectOSVersionFromMenu(deviceType, version === 'menu-esr');
}
// Note that `version` may also be 'latest', 'recommended', 'default'
if (/^v?\d+\.\d+\.\d+/.test(version)) {
if (version[0] === 'v') {
version = version.slice(1);
}
return await selectOSVersionFromMenu(
deviceType,
version === 'menu-esr',
false,
);
}
const { normalizeOsVersion } = await import('./normalization');
version = normalizeOsVersion(version);
return version;
}
async function selectOSVersionFromMenu(
deviceType: string,
esr: boolean,
includeDraft: boolean,
): Promise<string> {
const vs = await getOsVersions(deviceType, esr);
const vs = await getOsVersions(deviceType, esr, includeDraft);
const choices = vs.map((v) => ({
value: v.raw_version,
@ -237,17 +238,22 @@ async function selectOSVersionFromMenu(
export async function getOsVersions(
deviceType: string,
esr: boolean,
includeDraft: boolean,
): Promise<SDK.OsVersion[]> {
const sdk = getBalenaSdk();
let slug = deviceType;
let versions: SDK.OsVersion[] =
await sdk.models.os.getAvailableOsVersions(slug);
let versions: SDK.OsVersion[] = await sdk.models.os.getAvailableOsVersions(
slug,
{ includeDraft },
);
// if slug is an alias, fetch the real slug
if (!versions.length) {
// unalias device type slug
slug = (await sdk.models.deviceType.get(slug, { $select: 'slug' })).slug;
if (slug !== deviceType) {
versions = await sdk.models.os.getAvailableOsVersions(slug);
versions = await sdk.models.os.getAvailableOsVersions(slug, {
includeDraft,
});
}
}
versions = versions.filter(

View File

@ -53,6 +53,7 @@ export interface TaggedImage {
export interface ComposeOpts {
convertEol: boolean;
dockerfilePath?: string;
composefileName?: string;
inlineLogs?: boolean;
multiDockerignore: boolean;
noParentCheck: boolean;
@ -65,6 +66,7 @@ export interface ComposeCliFlags {
emulated: boolean;
dockerfile?: string;
nologs: boolean;
'docker-compose'?: string;
'multi-dockerignore': boolean;
'noparent-check': boolean;
'registry-secrets'?: RegistrySecrets;

View File

@ -20,6 +20,7 @@ import type * as SDK from 'balena-sdk';
import type Dockerode = require('dockerode');
import * as path from 'path';
import type { Composition, ImageDescriptor } from '@balena/compose/dist/parse';
import type { RetryParametersObj } from 'pinejs-client-core';
import type {
BuiltImage,
ComposeOpts,
@ -39,6 +40,7 @@ export function generateOpts(options: {
dockerfile?: string;
'multi-dockerignore': boolean;
'noparent-check': boolean;
'docker-compose'?: string;
}): Promise<ComposeOpts> {
const { promises: fs } = require('fs') as typeof import('fs');
return fs.realpath(options.source || '.').then((projectPath) => ({
@ -48,6 +50,7 @@ export function generateOpts(options: {
convertEol: !options['noconvert-eol'],
dockerfilePath: options.dockerfile,
multiDockerignore: !!options['multi-dockerignore'],
composefileName: options['docker-compose'],
noParentCheck: options['noparent-check'],
}));
}
@ -94,22 +97,62 @@ export function createProject(
};
}
const getRequestRetryParameters = (): RetryParametersObj => {
if (
process.env.BALENA_CLI_TEST_TYPE != null &&
process.env.BALENA_CLI_TEST_TYPE !== ''
) {
// We only read the test env vars when in test mode.
const { intVar } =
require('@balena/env-parsing') as typeof import('@balena/env-parsing');
// We use the BALENARCTEST namespace and only parse the env vars while in test mode
// since we plan to switch all pinejs clients with the one of the SDK and might not
// want to have to support these env vars.
return {
minDelayMs: intVar('BALENARCTEST_API_RETRY_MIN_DELAY_MS'),
maxDelayMs: intVar('BALENARCTEST_API_RETRY_MAX_DELAY_MS'),
maxAttempts: intVar('BALENARCTEST_API_RETRY_MAX_ATTEMPTS'),
};
}
return {
minDelayMs: 1000,
maxDelayMs: 60000,
maxAttempts: 7,
};
};
export const createRelease = async function (
logger: Logger,
apiEndpoint: string,
auth: string,
userId: number,
appId: number,
composition: Composition,
draft: boolean,
semver?: string,
contract?: string,
semver: string | undefined,
contract: string | undefined,
): Promise<Release> {
const _ = require('lodash') as typeof import('lodash');
const crypto = require('crypto') as typeof import('crypto');
const releaseMod =
require('@balena/compose/dist/release') as typeof import('@balena/compose/dist/release');
const client = releaseMod.createClient({ apiEndpoint, auth });
const client = releaseMod.createClient({
apiEndpoint,
auth,
retry: {
...getRequestRetryParameters(),
onRetry: (err, delayMs, attempt, maxAttempts) => {
const code = err?.statusCode ?? 0;
logger.logDebug(
`API call failed with code ${code}. Attempting retry ${attempt} of ${maxAttempts} in ${
delayMs / 1000
} seconds`,
);
},
},
});
const { release, serviceImages } = await releaseMod.create({
client,

View File

@ -31,7 +31,7 @@ import type * as MultiBuild from '@balena/compose/dist/multibuild';
import * as semver from 'semver';
import type { Duplex, Readable } from 'stream';
import type { Pack } from 'tar-stream';
import { ExpectedError } from '../errors';
import { CompositionFileNotFoundError, ExpectedError } from '../errors';
import {
BuiltImage,
ComposeOpts,
@ -128,7 +128,11 @@ export async function loadProject(
composeStr = compose.defaultComposition(image);
} else {
logger.logDebug('Resolving project...');
[composeName, composeStr] = await resolveProject(logger, opts.projectPath);
[composeName, composeStr] = await resolveProject({
logger,
projectRoot: opts.projectPath,
compositionFile: opts.composefileName,
});
if (composeName) {
if (opts.dockerfilePath) {
@ -198,33 +202,55 @@ async function mergeDevComposeOverlay(
return composeStr;
}
async function getDefaultCompositionFileName(
projectRoot: string,
): Promise<string | undefined> {
for (const fname of compositionFileNames) {
if (await exists(path.join(projectRoot, fname))) {
return fname;
}
}
}
interface ResolveProjectParameters {
logger: Logger;
projectRoot: string;
quiet?: boolean;
compositionFile?: string;
}
/**
* Look into the given directory for valid compose files and return
* the contents of the first one found.
*/
async function resolveProject(
logger: Logger,
projectRoot: string,
async function resolveProject({
logger,
projectRoot,
quiet = false,
): Promise<[string, string]> {
let composeFileName = '';
compositionFile,
}: ResolveProjectParameters): Promise<[string, string]> {
logger.logError(`Iam on resolve project and have ${compositionFile}`);
const composeFileName =
compositionFile ?? (await getDefaultCompositionFileName(projectRoot));
let composeFileContents = '';
for (const fname of compositionFileNames) {
const fpath = path.join(projectRoot, fname);
if (await exists(fpath)) {
logger.logDebug(`${fname} file found at "${projectRoot}"`);
composeFileName = fname;
try {
composeFileContents = await fs.readFile(fpath, 'utf8');
} catch (err) {
logger.logError(`Error reading composition file "${fpath}":\n${err}`);
throw err;
}
break;
}
if (composeFileName == null) {
throw new CompositionFileNotFoundError(projectRoot);
}
const fpath = path.join(projectRoot, composeFileName);
if (!(await exists(fpath))) {
throw new CompositionFileNotFoundError(fpath);
}
logger.logDebug(`Using composition file at "${fpath}"`);
try {
composeFileContents = await fs.readFile(fpath, 'utf8');
} catch (err) {
logger.logError(`Error reading composition file "${fpath}":\n${err}`);
throw err;
}
if (!quiet && !composeFileName) {
logger.logInfo(`No "docker-compose.yml" file found at "${projectRoot}"`);
logger.logInfo(`No composition file found at "${projectRoot}"`);
}
return [composeFileName, composeFileContents];
@ -680,15 +706,17 @@ async function loadBuildMetatada(
export async function getServiceDirsFromComposition(
sourceDir: string,
composition?: Composition,
compositionFile?: string,
): Promise<Dictionary<string>> {
const { createProject } = await import('./compose');
const serviceDirs: Dictionary<string> = {};
if (!composition) {
const [, composeStr] = await resolveProject(
Logger.getLogger(),
sourceDir,
true,
);
const [, composeStr] = await resolveProject({
logger: Logger.getLogger(),
projectRoot: sourceDir,
quiet: true,
compositionFile,
});
if (composeStr) {
composition = createProject(sourceDir, composeStr).composition;
}
@ -1385,6 +1413,7 @@ export async function deployProject(
`${prefix}Creating release...`,
() =>
createRelease(
logger,
apiEndpoint,
auth,
userId,
@ -1651,6 +1680,9 @@ export const composeCliFlags = {
description:
'Alternative Dockerfile name/path, relative to the source folder',
}),
'docker-compose': Flags.string({
description: 'Alternative compose yml file, relative to the source folder',
}),
nologs: Flags.boolean({
description:
'Hide the image build log output (produce less verbose output)',

View File

@ -184,9 +184,9 @@ export async function validateDevOptionAndWarn(
* option.
*/
export async function validateSecureBootOptionAndWarn(
secureBoot?: boolean,
slug?: string,
version?: string,
secureBoot: boolean,
slug: string,
version: string,
logger?: import('./logger'),
) {
if (!secureBoot) {
@ -202,7 +202,7 @@ export async function validateSecureBootOptionAndWarn(
const sdk = getBalenaSdk();
const [osRelease] = await sdk.models.os.getAllOsVersions(slug, {
$select: 'contract',
$filter: { raw_version: `${version.replace(/^v/, '')}` },
$filter: { raw_version: version },
});
if (!osRelease) {
throw new ExpectedError(`Error: No ${version} release for ${slug}`);

View File

@ -56,6 +56,7 @@ export interface DeviceDeployOptions {
deviceHost: string;
devicePort?: number;
dockerfilePath?: string;
composefileName?: string;
registrySecrets: RegistrySecrets;
multiDockerignore: boolean;
nocache: boolean;
@ -182,6 +183,7 @@ export async function deployToDevice(opts: DeviceDeployOptions): Promise<void> {
const project = await loadProject(globalLogger, {
convertEol: opts.convertEol,
dockerfilePath: opts.dockerfilePath,
composefileName: opts.composefileName,
multiDockerignore: opts.multiDockerignore,
noParentCheck: opts.noParentCheck,
projectName: 'local',
@ -627,17 +629,10 @@ export function generateTargetState(
};
opts.environment = _.merge(opts.environment, env[name]);
// This function can be called with a subset of the
// build tasks, when a single dockerfile has changed
// when livepushing, so check the build task exists for
// this composition entry (everything else in this
// function comes from the composition which doesn't
// change)
let contract;
if (name in keyedBuildTasks) {
contract = keyedBuildTasks[name].contract;
}
// This function should always be called with all the build tasks
// so we can construct the correct target state so we don't really need
// to check that the key exists on the `keyedBuildTasks` object
const contract = keyedBuildTasks[name].contract;
const task = keyedBuildTasks[name];
services[idx] = {

View File

@ -423,7 +423,12 @@ export class LivepushManager {
// If we re-apply the target state, the supervisor
// should recreate the container
await this.api.setTargetState(
generateTargetState(currentState, this.composition, [buildTask], {}),
generateTargetState(
currentState,
this.composition,
this.buildTasks,
{},
),
);
await this.awaitDeviceStateSettle();

View File

@ -81,3 +81,13 @@ export async function disambiguateReleaseParam(
export async function lowercaseIfSlug(s: string) {
return s.includes('/') ? s.toLowerCase() : s;
}
export function normalizeOsVersion(version: string) {
// Note that `version` may also be 'latest', 'recommended', 'default'
if (/^v?\d+\.\d+\.\d+/.test(version)) {
if (version[0] === 'v') {
version = version.slice(1);
}
}
return version;
}

6616
npm-shrinkwrap.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "balena-cli",
"version": "17.3.1",
"version": "18.0.0",
"description": "The official balena Command Line Interface",
"main": "./build/app.js",
"homepage": "https://github.com/balena-io/balena-cli",
@ -16,6 +16,7 @@
"doc/",
"lib/",
"patches/",
"!patches/**/**.dev.patch",
"*.md",
"npm-shrinkwrap.json",
"oclif.manifest.json"
@ -39,6 +40,7 @@
"node_modules/open/xdg-open",
"node_modules/windosu/*.bat",
"node_modules/windosu/*.cmd",
"node_modules/axios/**/*",
"npm-shrinkwrap.json",
"oclif.manifest.json"
]
@ -59,7 +61,8 @@
"package": "npm run build:fast && npm run build:standalone && npm run build:installer",
"release": "ts-node --transpile-only automation/run.ts release",
"pretest": "npm run build",
"test": "npm run test:shrinkwrap && npm run test:source && npm run test:standalone",
"test": "npm run test:shrinkwrap && npm run test:core",
"test:core": "npm run test:source && npm run test:standalone",
"test:shrinkwrap": "ts-node --transpile-only automation/run.ts test-shrinkwrap",
"test:source": "cross-env BALENA_CLI_TEST_TYPE=source mocha",
"test:standalone": "npm run build:standalone && npm run test:standalone:fast",
@ -88,7 +91,7 @@
"author": "Balena Inc. (https://balena.io/)",
"license": "Apache-2.0",
"engines": {
"node": ">=18 <20"
"node": ">=20 <21"
},
"husky": {
"hooks": {
@ -145,7 +148,7 @@
"@types/ndjson": "^2.0.1",
"@types/net-keepalive": "^0.4.1",
"@types/nock": "^11.1.0",
"@types/node": "^18.17.6",
"@types/node": "^20.0.0",
"@types/node-cleanup": "^2.1.2",
"@types/parse-link-header": "^1.0.1",
"@types/prettyjson": "^0.0.30",
@ -184,30 +187,31 @@
"nock": "^13.2.1",
"oclif": "^3.17.1",
"parse-link-header": "^2.0.0",
"pkg": "^5.8.1",
"publish-release": "^1.6.1",
"rewire": "^5.0.0",
"simple-git": "^3.14.1",
"sinon": "^11.1.2",
"ts-node": "^10.4.0",
"typescript": "^5.1.3"
"typescript": "^5.3.2"
},
"dependencies": {
"@balena/compose": "^3.0.2",
"@balena/compose": "^3.2.0",
"@balena/dockerignore": "^1.0.2",
"@balena/env-parsing": "^1.1.8",
"@balena/es-version": "^1.0.1",
"@oclif/core": "^2.15.0",
"@oclif/core": "^3.14.1",
"@resin.io/valid-email": "^0.1.0",
"@sentry/node": "^6.16.1",
"@types/fast-levenshtein": "0.0.1",
"@types/update-notifier": "^4.1.1",
"@yao-pkg/pkg": "^5.11.1",
"balena-config-json": "^4.2.0",
"balena-device-init": "^6.0.0",
"balena-errors": "^4.7.3",
"balena-image-fs": "^7.0.6",
"balena-image-manager": "^10.0.1",
"balena-preload": "^15.0.1",
"balena-sdk": "^19.0.0",
"balena-sdk": "^19.4.0",
"balena-semver": "^2.3.0",
"balena-settings-client": "^5.0.2",
"balena-settings-storage": "^8.1.0",
@ -224,7 +228,7 @@
"docker-progress": "^5.1.3",
"dockerode": "3.3.3",
"ejs": "^3.1.6",
"etcher-sdk": "^8.7.0",
"etcher-sdk": "9.0.6",
"event-stream": "3.3.4",
"express": "^4.17.2",
"fast-boot2": "^1.1.0",
@ -282,6 +286,6 @@
"windosu": "^0.3.0"
},
"versionist": {
"publishedAt": "2023-11-09T17:26:36.954Z"
"publishedAt": "2024-02-06T12:19:36.007Z"
}
}

View File

@ -1,5 +1,5 @@
diff --git a/node_modules/@oclif/core/lib/cli-ux/list.js b/node_modules/@oclif/core/lib/cli-ux/list.js
index dc6058c..64b2f85 100644
index 607d8dc..07ba1f2 100644
--- a/node_modules/@oclif/core/lib/cli-ux/list.js
+++ b/node_modules/@oclif/core/lib/cli-ux/list.js
@@ -22,7 +22,7 @@ function renderList(items) {
@ -12,20 +12,20 @@ index dc6058c..64b2f85 100644
return lines.join('\n');
}
diff --git a/node_modules/@oclif/core/lib/help/command.js b/node_modules/@oclif/core/lib/help/command.js
index 6de139b..3a13197 100644
index 63c0545..7caad4a 100644
--- a/node_modules/@oclif/core/lib/help/command.js
+++ b/node_modules/@oclif/core/lib/help/command.js
@@ -206,7 +206,7 @@ class CommandHelp extends formatter_1.HelpFormatter {
if (args.filter(a => a.description).length === 0)
@@ -58,7 +58,7 @@ class CommandHelp extends formatter_1.HelpFormatter {
if (args.filter((a) => a.description).length === 0)
return;
return args.map(a => {
return args.map((a) => {
- const name = a.name.toUpperCase();
+ const name = a.required ? `<${a.name}>` : `[${a.name}]`;
let description = a.description || '';
if (a.default)
description = `[default: ${a.default}] ${description}`;
@@ -238,14 +238,12 @@ class CommandHelp extends formatter_1.HelpFormatter {
label = labels.join(', ');
description = `${(0, theme_1.colorize)(this.config?.theme?.flagDefaultValue, `[default: ${a.default}]`)} ${description}`;
@@ -153,14 +153,12 @@ class CommandHelp extends formatter_1.HelpFormatter {
label = labels.join(flag.char ? (0, theme_1.colorize)(this.config?.theme?.flagSeparator, ', ') : ' ');
}
if (flag.type === 'option') {
- let value = flag.helpValue || (this.opts.showFlagNameInTitle ? flag.name : '<value>');
@ -36,16 +36,16 @@ index 6de139b..3a13197 100644
if (flag.multiple)
- value += '...';
- if (!value.includes('|'))
- value = underline(value);
- value = chalk_1.default.underline(value);
+ value += ' ...';
label += `=${value}`;
}
return label;
return (0, theme_1.colorize)(this.config.theme?.flag, label);
diff --git a/node_modules/@oclif/core/lib/help/index.js b/node_modules/@oclif/core/lib/help/index.js
index f9ef7cc..a14c67c 100644
index 242538a..efde8ac 100644
--- a/node_modules/@oclif/core/lib/help/index.js
+++ b/node_modules/@oclif/core/lib/help/index.js
@@ -136,11 +136,12 @@ class Help extends HelpBase {
@@ -168,11 +168,12 @@ class Help extends HelpBase {
}
this.log(this.formatCommand(command));
this.log('');
@ -56,51 +56,40 @@ index f9ef7cc..a14c67c 100644
this.log('');
}
- if (subCommands.length > 0) {
+ if (subCommands.length > 0 && !SUPPRESS_SUBTOPICS) {
+ if (subTopics.length > 0 && !SUPPRESS_SUBTOPICS) {
const aliases = [];
const uniqueSubCommands = subCommands.filter(p => {
const uniqueSubCommands = subCommands.filter((p) => {
aliases.push(...p.aliases);
diff --git a/node_modules/@oclif/core/lib/parser/errors.js b/node_modules/@oclif/core/lib/parser/errors.js
index 07ec8e5..a4560ea 100644
index 656ec6b..2bbf36b 100644
--- a/node_modules/@oclif/core/lib/parser/errors.js
+++ b/node_modules/@oclif/core/lib/parser/errors.js
@@ -10,7 +10,8 @@ var errors_2 = require("../errors");
Object.defineProperty(exports, "CLIError", { enumerable: true, get: function () { return errors_2.CLIError; } });
@@ -14,7 +14,8 @@ Object.defineProperty(exports, "CLIError", { enumerable: true, get: function ()
class CLIParseError extends errors_1.CLIError {
parse;
constructor(options) {
- options.message += '\nSee more help with --help';
+ const help = options.command ? `\`${options.command} --help\`` : '--help';
+ options.message += `\nSee more help with ${help}`;
super(options.message);
super(options.message, { exit: options.exit });
this.parse = options.parse;
}
@@ -31,7 +32,8 @@ class InvalidArgsSpecError extends CLIParseError {
exports.InvalidArgsSpecError = InvalidArgsSpecError;
@@ -37,7 +38,8 @@ exports.InvalidArgsSpecError = InvalidArgsSpecError;
class RequiredArgsError extends CLIParseError {
constructor({ args, parse, flagsWithMultiple }) {
args;
constructor({ args, exit, flagsWithMultiple, parse, }) {
- let message = `Missing ${args.length} required arg${args.length === 1 ? '' : 's'}`;
+ const command = 'balena ' + parse.input.context.id.replace(/:/g, ' ');
+ let message = `Missing ${args.length} required argument${args.length === 1 ? '' : 's'}`;
const namedArgs = args.filter(a => a.name);
const namedArgs = args.filter((a) => a.name);
if (namedArgs.length > 0) {
const list = (0, list_1.renderList)(namedArgs.map(a => [a.name, a.description]));
@@ -42,16 +44,17 @@ class RequiredArgsError extends CLIParseError {
const list = (0, list_1.renderList)(namedArgs.map((a) => [a.name, a.description]));
@@ -48,7 +50,7 @@ class RequiredArgsError extends CLIParseError {
message += `\n\nNote: ${flags} allow${flagsWithMultiple.length === 1 ? 's' : ''} multiple values. Because of this you need to provide all arguments before providing ${flagsWithMultiple.length === 1 ? 'that flag' : 'those flags'}.`;
message += '\nAlternatively, you can use "--" to signify the end of the flags and the beginning of arguments.';
}
- super({ parse, message });
+ super({ parse, message, command });
- super({ exit: cache_1.default.getInstance().get('exitCodes')?.requiredArgs ?? exit, message, parse });
+ super({ exit: cache_1.default.getInstance().get('exitCodes')?.requiredArgs ?? exit, message, parse, command });
this.args = args;
}
}
exports.RequiredArgsError = RequiredArgsError;
class RequiredFlagError extends CLIParseError {
constructor({ flag, parse }) {
+ const command = 'balena ' + parse.input.context.id.replace(/:/g, ' ');
const usage = (0, list_1.renderList)((0, help_1.flagUsages)([flag], { displayRequired: false }));
const message = `Missing required flag:\n${usage}`;
- super({ parse, message });
+ super({ parse, message, command });
this.flag = flag;
}
}

View File

@ -12,7 +12,7 @@ upstream:
url: 'https://github.com/balena-io-modules/balena-preload'
- repo: 'etcher-sdk'
url: 'https://github.com/balena-io-modules/etcher-sdk/'
- repo: 'balena-compose'
- repo: '@balena/compose'
url: 'https://github.com/balena-io-modules/balena-compose'
- repo: 'docker-progress'
url: 'https://github.com/balena-io-modules/docker-progress'

View File

@ -15,6 +15,7 @@
* limitations under the License.
*/
import { intVar } from '@balena/env-parsing';
import type { Request as ReleaseRequest } from '@balena/compose/dist/release';
import { expect } from 'chai';
import { promises as fs } from 'fs';
@ -284,16 +285,25 @@ describe('balena deploy', function () {
api.expectPostRelease({});
docker.expectGetManifestBusybox();
let failedImagePatchRequests = 0;
// Mock this patch HTTP request to return status code 500, in which case
// the release status should be saved as "failed" rather than "success"
const maxRequestRetries = intVar('BALENARCTEST_API_RETRY_MAX_ATTEMPTS');
expect(
maxRequestRetries,
'BALENARCTEST_API_RETRY_MAX_ATTEMPTS must be >= 2 for this test',
).to.be.greaterThanOrEqual(2);
api.expectPatchImage({
replyBody: errMsg,
statusCode: 500,
// b/c failed requests are retried
times: maxRequestRetries,
inspectRequest: (_uri, requestBody) => {
const imageBody = requestBody as Partial<
import('@balena/compose/dist/release/models').ImageModel
>;
expect(imageBody.status).to.equal('success');
failedImagePatchRequests++;
},
});
// Check that the CLI patches the release with status="failed"
@ -324,6 +334,7 @@ describe('balena deploy', function () {
responseCode: 200,
services: ['main'],
});
expect(failedImagePatchRequests).to.equal(maxRequestRetries);
} finally {
await switchSentry(sentryStatus);
// @ts-expect-error claims restore does not exist
@ -331,6 +342,82 @@ describe('balena deploy', function () {
}
});
it('should create the expected --build tar stream after retrying failing OData requests (single container)', async () => {
const projectPath = path.join(projectsPath, 'no-docker-compose', 'basic');
const expectedFiles: ExpectedTarStreamFiles = {
'src/.dockerignore': { fileSize: 16, type: 'file' },
'src/start.sh': { fileSize: 89, type: 'file' },
'src/windows-crlf.sh': {
fileSize: isWindows ? 68 : 70,
testStream: isWindows ? expectStreamNoCRLF : undefined,
type: 'file',
},
Dockerfile: { fileSize: 88, type: 'file' },
'Dockerfile-alt': { fileSize: 30, type: 'file' },
};
const responseFilename = 'build-POST.json';
const responseBody = await fs.readFile(
path.join(dockerResponsePath, responseFilename),
'utf8',
);
const expectedResponseLines = [
...commonResponseLines[responseFilename],
`[Info] No "docker-compose.yml" file found at "${projectPath}"`,
`[Info] Creating default composition with source: "${projectPath}"`,
...getDockerignoreWarn1(
[path.join(projectPath, 'src', '.dockerignore')],
'deploy',
),
];
if (isWindows) {
const fname = path.join(projectPath, 'src', 'windows-crlf.sh');
expectedResponseLines.push(
`[Info] Converting line endings CRLF -> LF for file: ${fname}`,
);
}
api.expectPostRelease({});
docker.expectGetManifestBusybox();
const maxRequestRetries = intVar('BALENARCTEST_API_RETRY_MAX_ATTEMPTS');
expect(
maxRequestRetries,
'BALENARCTEST_API_RETRY_MAX_ATTEMPTS must be >= 2 for this test',
).to.be.greaterThanOrEqual(2);
let failedImagePatchRequests = 0;
let succesfullImagePatchRequests = 0;
api
.optPatch(/^\/v6\/image($|[(?])/, { times: maxRequestRetries })
.reply((_uri, requestBody) => {
const imageBody = requestBody as Partial<
import('@balena/compose/dist/release/models').ImageModel
>;
expect(imageBody.status).to.equal('success');
if (failedImagePatchRequests < maxRequestRetries - 1) {
failedImagePatchRequests++;
return [500, 'Patch Image Error'];
}
succesfullImagePatchRequests++;
return [200, 'OK'];
});
api.expectPatchRelease({});
api.expectPostImageLabel();
await testDockerBuildStream({
commandLine: `deploy testApp --build --source ${projectPath}`,
dockerMock: docker,
expectedFilesByService: { main: expectedFiles },
expectedQueryParamsByService: { main: commonQueryParams },
expectedResponseLines,
projectPath,
responseBody,
responseCode: 200,
services: ['main'],
});
expect(failedImagePatchRequests).to.equal(maxRequestRetries - 1);
expect(succesfullImagePatchRequests).to.equal(1);
});
it('should create the expected tar stream (docker-compose, --multi-dockerignore)', async () => {
const projectPath = path.join(projectsPath, 'docker-compose', 'basic');
const service1Dockerfile = (

View File

@ -107,4 +107,19 @@ describe('balena device', function () {
expect(lines[0]).to.equal('== SPARKLING WOOD');
expect(lines[6].split(':')[1].trim()).to.equal('N/a');
});
it('outputs device as JSON with the -j/--json flag', async () => {
api.scope
.get(/^\/v6\/device\?.+&\$expand=device_tag\(\$select=tag_key,value\)/)
.replyWithFile(200, path.join(apiResponsePath, 'device.json'), {
'Content-Type': 'application/json',
});
const { out, err } = await runCommand('device 27fda508c --json');
expect(err).to.be.empty;
const json = JSON.parse(out.join(''));
expect(json.device_name).to.equal('sparkling-wood');
expect(json.belongs_to__application[0].app_name).to.equal('test app');
expect(json.device_tag[0].tag_key).to.equal('example');
});
});

View File

@ -26,6 +26,11 @@ process.env.BALENARC_NO_SENTRY = '1';
// Like the global `--unsupported` flag
process.env.BALENARC_UNSUPPORTED = '1';
// Reduce the api request retry limits to keep the tests fast.
process.env.BALENARCTEST_API_RETRY_MIN_DELAY_MS = '100';
process.env.BALENARCTEST_API_RETRY_MAX_DELAY_MS = '1000';
process.env.BALENARCTEST_API_RETRY_MAX_ATTEMPTS = '2';
import * as tmp from 'tmp';
tmp.setGracefulCleanup();
// Use a temporary dir for tests data

View File

@ -131,7 +131,6 @@ describe('handleError() function', () => {
const messagesToMatch = [
'Missing 1 required argument', // oclif
'Missing 2 required arguments', // oclif
'Missing required flag', // oclif
'Unexpected argument', // oclif
'Unexpected arguments', // oclif
'to be one of', // oclif

View File

@ -106,7 +106,7 @@ async function runCommandInProcess(cmd: string): Promise<TestOutput> {
try {
await balenaCLI.run(preArgs.concat(cmd.split(' ').filter((c) => c)), {
configPath: path.resolve(__dirname, '..'),
dir: path.resolve(__dirname, '..'),
noFlush: true,
});
} finally {

View File

@ -35,11 +35,13 @@ export class BalenaAPIMock extends NockMock {
notFound = false,
optional = false,
persist = false,
times = undefined as number | undefined,
expandArchitecture = false,
} = {}) {
const interceptor = this.optGet(/^\/v6\/application($|[(?])/, {
optional,
persist,
times,
});
if (notFound) {
interceptor.reply(200, { d: [] });
@ -105,10 +107,12 @@ export class BalenaAPIMock extends NockMock {
notFound = false,
optional = false,
persist = false,
times = undefined as number | undefined,
} = {}) {
const interceptor = this.optGet(/^\/v6\/release($|[(?])/, {
persist,
optional,
times,
});
if (notFound) {
interceptor.reply(200, { d: [] });
@ -133,8 +137,9 @@ export class BalenaAPIMock extends NockMock {
inspectRequest = this.inspectNoOp,
optional = false,
persist = false,
times = undefined as number | undefined,
}) {
this.optPatch(/^\/v6\/release($|[(?])/, { optional, persist }).reply(
this.optPatch(/^\/v6\/release($|[(?])/, { optional, persist, times }).reply(
statusCode,
this.getInspectedReplyBodyFunction(inspectRequest, replyBody),
);
@ -148,8 +153,9 @@ export class BalenaAPIMock extends NockMock {
inspectRequest = this.inspectNoOp,
optional = false,
persist = false,
times = undefined as number | undefined,
}) {
this.optPost(/^\/v6\/release($|[(?])/, { optional, persist }).reply(
this.optPost(/^\/v6\/release($|[(?])/, { optional, persist, times }).reply(
statusCode,
this.getInspectedReplyFileFunction(
inspectRequest,
@ -167,8 +173,9 @@ export class BalenaAPIMock extends NockMock {
inspectRequest = this.inspectNoOp,
optional = false,
persist = false,
times = undefined as number | undefined,
}) {
this.optPatch(/^\/v6\/image($|[(?])/, { optional, persist }).reply(
this.optPatch(/^\/v6\/image($|[(?])/, { optional, persist, times }).reply(
statusCode,
this.getInspectedReplyBodyFunction(inspectRequest, replyBody),
);

View File

@ -21,6 +21,7 @@ import * as fs from 'fs';
export interface ScopeOpts {
optional?: boolean;
persist?: boolean;
times?: number;
}
/**
@ -52,36 +53,50 @@ export class NockMock {
this.expect = this.scope;
}
public optMethod(
method: 'get' | 'delete' | 'patch' | 'post',
uri: string | RegExp | ((uri: string) => boolean),
{ optional = false, persist = false, times = undefined }: ScopeOpts,
) {
let scope = this.scope;
if (persist) {
scope = scope.persist();
}
let reqInterceptor = scope[method](uri);
if (times != null) {
reqInterceptor = reqInterceptor.times(times);
} else if (optional) {
reqInterceptor = reqInterceptor.optionally();
}
return reqInterceptor;
}
public optGet(
uri: string | RegExp | ((uri: string) => boolean),
{ optional = false, persist = false }: ScopeOpts,
opts: ScopeOpts,
): nock.Interceptor {
const get = (persist ? this.scope.persist() : this.scope).get(uri);
return optional ? get.optionally() : get;
return this.optMethod('get', uri, opts);
}
public optDelete(
uri: string | RegExp | ((uri: string) => boolean),
{ optional = false, persist = false }: ScopeOpts,
opts: ScopeOpts,
) {
const del = (persist ? this.scope.persist() : this.scope).delete(uri);
return optional ? del.optionally() : del;
return this.optMethod('delete', uri, opts);
}
public optPatch(
uri: string | RegExp | ((uri: string) => boolean),
{ optional = false, persist = false }: ScopeOpts,
opts: ScopeOpts,
) {
const patch = (persist ? this.scope.persist() : this.scope).patch(uri);
return optional ? patch.optionally() : patch;
return this.optMethod('patch', uri, opts);
}
public optPost(
uri: string | RegExp | ((uri: string) => boolean),
{ optional = false, persist = false }: ScopeOpts,
opts: ScopeOpts,
) {
const post = (persist ? this.scope.persist() : this.scope).post(uri);
return optional ? post.optionally() : post;
return this.optMethod('post', uri, opts);
}
protected inspectNoOp(_uri: string, _requestBody: nock.Body): void {

View File

@ -8,6 +8,12 @@
"__metadata": {}
}
],
"device_tag": [
{
"tag_key": "example",
"value": "true"
}
],
"id": 1747415,
"is_managed_by__device": null,
"device_name": "sparkling-wood",

View File

@ -76,13 +76,96 @@
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/win32.bat
%2: path-to-executable/drivelist/win32.bat
prebuild-install warn install No prebuilt binaries found (target=v18.5.0 runtime=node arch=x64 libc= platform=darwin)
prebuild-install warn install No prebuilt binaries found (target=v18.5.0 runtime=node arch=x64 libc= platform=darwin)
prebuild-install warn install No prebuilt binaries found (target=v18.5.0 runtime=node arch=x64 libc= platform=darwin)
prebuild-install warn install No prebuilt binaries found (target=v18.5.0 runtime=node arch=x64 libc= platform=darwin)
> Warning Failed to make bytecode node18-x64 for file node_modules/@isaacs/cliui/node_modules/string-width/index.js
> Warning Failed to make bytecode node18-x64 for file node_modules/@isaacs/cliui/node_modules/strip-ansi/index.js
> Warning Failed to make bytecode node18-x64 for file node_modules/@isaacs/cliui/node_modules/wrap-ansi/index.js
prebuild-install warn install No prebuilt binaries found (target=v18.5.0 runtime=node arch=x64 libc= platform=darwin)
> Warning Failed to make bytecode node18-x64 for file node_modules/@isaacs/cliui/node_modules/ansi-regex/index.js
> Warning Failed to make bytecode node18-x64 for file node_modules/@isaacs/cliui/node_modules/ansi-styles/index.js
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/build/Release/drivelist.node
%2: path-to-executable/drivelist.node
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/scripts/darwin.sh
%2: path-to-executable/drivelist/darwin.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/scripts/linux.sh
%2: path-to-executable/drivelist/linux.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/scripts/win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/build/Release/drivelist.node
%2: path-to-executable/drivelist.node
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/scripts/darwin.sh
%2: path-to-executable/drivelist/darwin.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/scripts/linux.sh
%2: path-to-executable/drivelist/linux.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/scripts/win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/axios.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/utils.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/adapters/adapters.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/adapters/http.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/adapters/xhr.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/cancel/CancelToken.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/cancel/CanceledError.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/cancel/isCancel.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/Axios.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/AxiosError.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/AxiosHeaders.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/InterceptorManager.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/buildFullPath.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/dispatchRequest.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/mergeConfig.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/settle.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/transformData.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/defaults/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/defaults/transitional.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/env/data.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/AxiosTransformStream.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/AxiosURLSearchParams.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/HttpStatusCode.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/ZlibHeaderTransformStream.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/bind.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/buildURL.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/callbackify.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/combineURLs.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/cookies.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/formDataToJSON.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/formDataToStream.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/fromDataURI.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/isAbsoluteURL.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/isAxiosError.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/isURLSameOrigin.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/parseHeaders.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/parseProtocol.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/readBlob.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/speedometer.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/spread.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/throttle.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/toFormData.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/toURLEncodedForm.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/validator.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/common/utils.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/node/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/node/classes/FormData.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/node/classes/URLSearchParams.js
prebuild-install warn install No prebuilt binaries found (target=v20.10.0 runtime=node arch=x64 libc= platform=darwin)
prebuild-install warn install No prebuilt binaries found (target=v20.10.0 runtime=node arch=x64 libc= platform=darwin)
prebuild-install warn install No prebuilt binaries found (target=v20.10.0 runtime=node arch=x64 libc= platform=darwin)
prebuild-install warn install No prebuilt binaries found (target=v20.10.0 runtime=node arch=x64 libc= platform=darwin)
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/string-width/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/strip-ansi/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/wrap-ansi/index.js
prebuild-install warn install No prebuilt binaries found (target=v20.10.0 runtime=node arch=x64 libc= platform=darwin)
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/ansi-regex/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/ansi-styles/index.js
prebuild-install warn install No prebuilt binaries found (target=v20.10.0 runtime=node arch=x64 libc= platform=darwin)

View File

@ -76,12 +76,95 @@
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/win32.bat
%2: path-to-executable/drivelist/win32.bat
prebuild-install warn install No prebuilt binaries found (target=v18.5.0 runtime=node arch=arm64 libc= platform=linux)
prebuild-install warn install No prebuilt binaries found (target=v18.5.0 runtime=node arch=arm64 libc= platform=linux)
prebuild-install warn install No prebuilt binaries found (target=v18.5.0 runtime=node arch=arm64 libc= platform=linux)
> Warning Failed to make bytecode node18-arm64 for file node_modules/@isaacs/cliui/node_modules/string-width/index.js
> Warning Failed to make bytecode node18-arm64 for file node_modules/@isaacs/cliui/node_modules/strip-ansi/index.js
> Warning Failed to make bytecode node18-arm64 for file node_modules/@isaacs/cliui/node_modules/wrap-ansi/index.js
prebuild-install warn install No prebuilt binaries found (target=v18.5.0 runtime=node arch=arm64 libc= platform=linux)
> Warning Failed to make bytecode node18-arm64 for file node_modules/@isaacs/cliui/node_modules/ansi-regex/index.js
> Warning Failed to make bytecode node18-arm64 for file node_modules/@isaacs/cliui/node_modules/ansi-styles/index.js
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/build/Release/drivelist.node
%2: path-to-executable/drivelist.node
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/scripts/darwin.sh
%2: path-to-executable/drivelist/darwin.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/scripts/linux.sh
%2: path-to-executable/drivelist/linux.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/scripts/win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/build/Release/drivelist.node
%2: path-to-executable/drivelist.node
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/scripts/darwin.sh
%2: path-to-executable/drivelist/darwin.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/scripts/linux.sh
%2: path-to-executable/drivelist/linux.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/scripts/win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/axios.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/utils.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/adapters/adapters.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/adapters/http.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/adapters/xhr.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/cancel/CancelToken.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/cancel/CanceledError.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/cancel/isCancel.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/Axios.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/AxiosError.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/AxiosHeaders.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/InterceptorManager.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/buildFullPath.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/dispatchRequest.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/mergeConfig.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/settle.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/core/transformData.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/defaults/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/defaults/transitional.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/env/data.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/AxiosTransformStream.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/AxiosURLSearchParams.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/HttpStatusCode.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/ZlibHeaderTransformStream.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/bind.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/buildURL.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/callbackify.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/combineURLs.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/cookies.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/formDataToJSON.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/formDataToStream.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/fromDataURI.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/isAbsoluteURL.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/isAxiosError.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/isURLSameOrigin.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/parseHeaders.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/parseProtocol.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/readBlob.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/speedometer.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/spread.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/throttle.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/toFormData.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/toURLEncodedForm.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/helpers/validator.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/platform/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/platform/common/utils.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/platform/node/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/platform/node/classes/FormData.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/axios/lib/platform/node/classes/URLSearchParams.js
prebuild-install warn install No prebuilt binaries found (target=v20.10.0 runtime=node arch=arm64 libc= platform=linux)
prebuild-install warn install No prebuilt binaries found (target=v20.10.0 runtime=node arch=arm64 libc= platform=linux)
prebuild-install warn install No prebuilt binaries found (target=v20.10.0 runtime=node arch=arm64 libc= platform=linux)
> Warning Failed to make bytecode node20-arm64 for file node_modules/@isaacs/cliui/node_modules/string-width/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/@isaacs/cliui/node_modules/strip-ansi/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/@isaacs/cliui/node_modules/wrap-ansi/index.js
prebuild-install warn install No prebuilt binaries found (target=v20.10.0 runtime=node arch=arm64 libc= platform=linux)
> Warning Failed to make bytecode node20-arm64 for file node_modules/@isaacs/cliui/node_modules/ansi-regex/index.js
> Warning Failed to make bytecode node20-arm64 for file node_modules/@isaacs/cliui/node_modules/ansi-styles/index.js
prebuild-install warn install No prebuilt binaries found (target=v20.10.0 runtime=node arch=arm64 libc= platform=linux)

View File

@ -76,12 +76,95 @@
The file must be distributed with executable as %2.
%1: node_modules/drivelist/scripts/win32.bat
%2: path-to-executable/drivelist/win32.bat
prebuild-install warn install No prebuilt binaries found (target=v18.5.0 runtime=node arch=x64 libc= platform=linux)
prebuild-install warn install No prebuilt binaries found (target=v18.5.0 runtime=node arch=x64 libc= platform=linux)
prebuild-install warn install No prebuilt binaries found (target=v18.5.0 runtime=node arch=x64 libc= platform=linux)
> Warning Failed to make bytecode node18-x64 for file node_modules/@isaacs/cliui/node_modules/string-width/index.js
> Warning Failed to make bytecode node18-x64 for file node_modules/@isaacs/cliui/node_modules/strip-ansi/index.js
> Warning Failed to make bytecode node18-x64 for file node_modules/@isaacs/cliui/node_modules/wrap-ansi/index.js
prebuild-install warn install No prebuilt binaries found (target=v18.5.0 runtime=node arch=x64 libc= platform=linux)
> Warning Failed to make bytecode node18-x64 for file node_modules/@isaacs/cliui/node_modules/ansi-regex/index.js
> Warning Failed to make bytecode node18-x64 for file node_modules/@isaacs/cliui/node_modules/ansi-styles/index.js
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/build/Release/drivelist.node
%2: path-to-executable/drivelist.node
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/scripts/darwin.sh
%2: path-to-executable/drivelist/darwin.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/scripts/linux.sh
%2: path-to-executable/drivelist/linux.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/scripts/win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/build/Release/drivelist.node
%2: path-to-executable/drivelist.node
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/scripts/darwin.sh
%2: path-to-executable/drivelist/darwin.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/scripts/linux.sh
%2: path-to-executable/drivelist/linux.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules/resin-cli-visuals/node_modules/drivelist/scripts/win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/axios.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/utils.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/adapters/adapters.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/adapters/http.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/adapters/xhr.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/cancel/CancelToken.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/cancel/CanceledError.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/cancel/isCancel.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/Axios.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/AxiosError.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/AxiosHeaders.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/InterceptorManager.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/buildFullPath.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/dispatchRequest.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/mergeConfig.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/settle.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/core/transformData.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/defaults/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/defaults/transitional.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/env/data.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/AxiosTransformStream.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/AxiosURLSearchParams.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/HttpStatusCode.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/ZlibHeaderTransformStream.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/bind.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/buildURL.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/callbackify.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/combineURLs.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/cookies.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/formDataToJSON.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/formDataToStream.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/fromDataURI.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/isAbsoluteURL.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/isAxiosError.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/isURLSameOrigin.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/parseHeaders.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/parseProtocol.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/readBlob.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/speedometer.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/spread.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/throttle.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/toFormData.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/toURLEncodedForm.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/helpers/validator.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/common/utils.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/node/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/node/classes/FormData.js
> Warning Failed to make bytecode node20-x64 for file node_modules/axios/lib/platform/node/classes/URLSearchParams.js
prebuild-install warn install No prebuilt binaries found (target=v20.10.0 runtime=node arch=x64 libc= platform=linux)
prebuild-install warn install No prebuilt binaries found (target=v20.10.0 runtime=node arch=x64 libc= platform=linux)
prebuild-install warn install No prebuilt binaries found (target=v20.10.0 runtime=node arch=x64 libc= platform=linux)
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/string-width/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/strip-ansi/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/wrap-ansi/index.js
prebuild-install warn install No prebuilt binaries found (target=v20.10.0 runtime=node arch=x64 libc= platform=linux)
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/ansi-regex/index.js
> Warning Failed to make bytecode node20-x64 for file node_modules/@isaacs/cliui/node_modules/ansi-styles/index.js
prebuild-install warn install No prebuilt binaries found (target=v20.10.0 runtime=node arch=x64 libc= platform=linux)

View File

@ -76,8 +76,90 @@
The file must be distributed with executable as %2.
%1: node_modules\drivelist\scripts\win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Failed to make bytecode node18-x64 for file node_modules\@isaacs\cliui\node_modules\string-width\index.js
> Warning Failed to make bytecode node18-x64 for file node_modules\@isaacs\cliui\node_modules\strip-ansi\index.js
> Warning Failed to make bytecode node18-x64 for file node_modules\@isaacs\cliui\node_modules\wrap-ansi\index.js
> Warning Failed to make bytecode node18-x64 for file node_modules\@isaacs\cliui\node_modules\ansi-regex\index.js
> Warning Failed to make bytecode node18-x64 for file node_modules\@isaacs\cliui\node_modules\ansi-styles\index.js
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\resin-cli-visuals\node_modules\drivelist\build\Release\drivelist.node
%2: path-to-executable/drivelist.node
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\resin-cli-visuals\node_modules\drivelist\scripts\darwin.sh
%2: path-to-executable/drivelist/darwin.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\resin-cli-visuals\node_modules\drivelist\scripts\linux.sh
%2: path-to-executable/drivelist/linux.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\resin-cli-visuals\node_modules\drivelist\scripts\win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\resin-cli-visuals\node_modules\drivelist\build\Release\drivelist.node
%2: path-to-executable/drivelist.node
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\resin-cli-visuals\node_modules\drivelist\scripts\darwin.sh
%2: path-to-executable/drivelist/darwin.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\resin-cli-visuals\node_modules\drivelist\scripts\linux.sh
%2: path-to-executable/drivelist/linux.sh
> Warning Cannot include file %1 into executable.
The file must be distributed with executable as %2.
%1: node_modules\resin-cli-visuals\node_modules\drivelist\scripts\win32.bat
%2: path-to-executable/drivelist/win32.bat
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\index.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\axios.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\utils.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\adapters\adapters.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\adapters\http.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\adapters\xhr.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\cancel\CanceledError.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\cancel\CancelToken.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\cancel\isCancel.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\core\Axios.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\core\AxiosError.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\core\AxiosHeaders.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\core\buildFullPath.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\core\dispatchRequest.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\core\InterceptorManager.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\core\mergeConfig.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\core\settle.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\core\transformData.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\defaults\index.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\defaults\transitional.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\env\data.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\AxiosTransformStream.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\AxiosURLSearchParams.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\bind.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\buildURL.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\callbackify.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\combineURLs.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\cookies.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\formDataToJSON.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\formDataToStream.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\fromDataURI.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\HttpStatusCode.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\isAbsoluteURL.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\isAxiosError.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\isURLSameOrigin.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\parseHeaders.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\parseProtocol.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\readBlob.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\speedometer.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\spread.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\throttle.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\toFormData.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\toURLEncodedForm.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\validator.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\helpers\ZlibHeaderTransformStream.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\platform\index.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\platform\common\utils.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\platform\node\index.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\platform\node\classes\FormData.js
> Warning Failed to make bytecode node20-x64 for file node_modules\axios\lib\platform\node\classes\URLSearchParams.js
> Warning Failed to make bytecode node20-x64 for file node_modules\@isaacs\cliui\node_modules\string-width\index.js
> Warning Failed to make bytecode node20-x64 for file node_modules\@isaacs\cliui\node_modules\strip-ansi\index.js
> Warning Failed to make bytecode node20-x64 for file node_modules\@isaacs\cliui\node_modules\wrap-ansi\index.js
> Warning Failed to make bytecode node20-x64 for file node_modules\@isaacs\cliui\node_modules\ansi-regex\index.js
> Warning Failed to make bytecode node20-x64 for file node_modules\@isaacs\cliui\node_modules\ansi-styles\index.js

View File

@ -21,7 +21,3 @@ declare namespace NodeJS {
pkg?: boolean;
}
}
declare module 'pkg' {
export function exec(args: string[]): Promise<void>;
}