Compare commits

...

44 Commits

Author SHA1 Message Date
flowzone-app[bot]
650e896f70
v21.1.0 2025-03-12 19:34:20 +00:00
flowzone-app[bot]
a9042124ea
Merge pull request #2922 from balena-io/compose-requirement-labels
Add support for requirement labels feature
2025-03-12 19:33:23 +00:00
Felipe Lalanne
d24d78dac7
Fix package release action for macOS
Depending on the signing password value, the script may interpret the
contents of the password and cause the signing process to fail.

This puts quotes around the password on assignment to prevent this.
2025-03-12 15:30:49 -03:00
Felipe Lalanne
42c50ef8ae
Add support for new requirement labels feature
Updates @balena/compose to v7 to include this new feature.

See: https://balena.fibery.io/Work/Project/Refactoring-container-contracts-1205
Depends-on: https://github.com/balena-io-modules/balena-compose/pull/64
Change-type: minor
2025-03-12 15:30:21 -03:00
flowzone-app[bot]
ba4b9bd447
v21.0.0 2025-03-11 14:42:31 +00:00
Matthew Yarmolinsky
02c0ea5b59
Merge pull request #2921 from balena-io/major-21-second-attempt
Major 21
2025-03-11 10:41:28 -04:00
myarmolinsky
bc3558dd8e Address SDK major v21 breaking changes 2025-03-11 08:19:10 -04:00
myarmolinsky
aad62d1ccd Drop support for OS versions <2.14.0
Change-type: major
2025-03-11 08:19:10 -04:00
myarmolinsky
ecc6f80164 api-key generate: Add required argument expiryDate
Change-type: major
2025-03-11 08:19:10 -04:00
myarmolinsky
c0fd1e3886 Deduplicate dependencies 2025-03-11 08:18:56 -04:00
myarmolinsky
9d3120b144 Update balena-preload to 18.0.1
Change-type: patch
2025-03-11 08:17:27 -04:00
myarmolinsky
ed0e03ddb2 Add dependency date-fns
Change-type: patch
2025-03-11 08:16:50 -04:00
myarmolinsky
8fe6d6c026 Update balena-sdk to 21.2.1
Change-type: patch
2025-03-11 08:16:31 -04:00
flowzone-app[bot]
727033ae14
v20.2.10 2025-03-10 17:33:13 +00:00
flowzone-app[bot]
c19ce6a905
Merge pull request #2923 from balena-io/bump-typescript-to-5.8.2
Bump typescript to 5.8.2
2025-03-10 17:32:13 +00:00
Thodoris Greasidis
1a33029738 Deduplicate dependencies 2025-03-10 17:51:18 +02:00
Thodoris Greasidis
043bc48a1c Add a "deduplicate-dependencies" npm script to standardize such commits 2025-03-04 08:48:31 +02:00
Thodoris Greasidis
a10156a441 Update TypeScript to 5.8.2
Change-type: patch
2025-03-04 08:48:31 +02:00
flowzone-app[bot]
4f665f43d2
v20.2.9 2025-02-26 12:52:10 +00:00
flowzone-app[bot]
9f097a96f5
Merge pull request #2920 from balena-io/x-balena-client-fix
Fix CORS issue with X-Balena-Client header
2025-02-26 12:51:20 +00:00
Thodoris Greasidis
64d1943804 Fix CORS issue with X-Balena-Client header
Change-type: patch
See: https://balena.fibery.io/Work/Project/Extend-the-X-Balena-Client-header-to-include-the-UI-CLI-version-as-well-1174
2025-02-26 14:24:57 +02:00
flowzone-app[bot]
666ce876e6
v20.2.8 2025-02-26 00:22:16 +00:00
Ken Bannister
e01184080f
Merge pull request #2915 from balena-io/fix_os_configure_test
Update balena-config-json dependency and fix test
2025-02-25 19:21:25 -05:00
Ken Bannister
93039b010d Update balena-config-json dependency and fix test
Change-type: patch
Signed-off-by: Ken Bannister <kb2ma@runbox.com>
2025-02-25 18:43:12 -05:00
flowzone-app[bot]
795259bf30
v20.2.7 2025-02-25 20:21:03 +00:00
flowzone-app[bot]
fa134d2d39
Merge pull request #2917 from balena-io/x-balena-client
Use the CLI version in the X-Balena-Client header
2025-02-25 20:20:10 +00:00
Thodoris Greasidis
bef5221ed8 Use the CLI version in the X-Balena-Client header
Change-type: patch
See: https://balena.fibery.io/Work/Project/Extend-the-X-Balena-Client-header-to-include-the-UI-CLI-version-as-well-1174
2025-02-25 21:59:35 +02:00
flowzone-app[bot]
72d6db796c
v20.2.6 2025-02-25 19:13:51 +00:00
balena-renovate[bot]
e848eb63ee
Merge pull request #2918 from balena-io/renovate/actions-upload-artifact-digest
Update actions/upload-artifact digest to 4cec3d8
2025-02-25 19:12:56 +00:00
balena-renovate[bot]
6f0f7350cf
Update actions/upload-artifact digest to 4cec3d8
Update actions/upload-artifact

Change-type: patch
2025-02-25 18:51:27 +00:00
flowzone-app[bot]
07a88c700e
v20.2.5 2025-02-25 18:10:50 +00:00
balena-renovate[bot]
9cae66bd92
Merge pull request #2913 from balena-io/renovate/actions-setup-node-digest
Update actions/setup-node digest to 1d0ff46
2025-02-25 18:09:54 +00:00
balena-renovate[bot]
cddea24cef
Update actions/setup-node digest to 1d0ff46
Update actions/setup-node

Change-type: patch
2025-02-25 17:45:52 +00:00
flowzone-app[bot]
b1c246c0b4
v20.2.4 2025-02-25 17:17:03 +00:00
Ken Bannister
00b4d57a03
Merge pull request #2916 from balena-io/pin_docker-modem_regression
Pin docker-modem and dockerode to avoid regression in docker-modem v5.0.6
2025-02-25 12:16:10 -05:00
Ken Bannister
2cba82e914 Pin docker-modem and dockerode to avoid regression
Change-type: patch
Signed-off-by: Ken Bannister <kb2ma@runbox.com>
2025-02-24 20:22:59 -05:00
flowzone-app[bot]
1352c5c823
v20.2.3 2025-01-15 18:21:09 +00:00
flowzone-app[bot]
c86eb97010
Merge pull request #2910 from balena-io/clean-eslint
Remove unused old eslint version files
2025-01-15 18:19:22 +00:00
Otavio Jacobi
53be743b9d Remove unused old eslint version files
Change-type: patch
2025-01-15 08:37:35 -03:00
flowzone-app[bot]
d9f21b4c3f
v20.2.2 2025-01-12 14:49:07 +00:00
Thodoris Greasidis
261ab398dd
Merge pull request #2906 from balena-io/bump-balena-image-fs
Use the promises namespace of balena-image-fs
2025-01-12 16:48:08 +02:00
Thodoris Greasidis
f28a9992e4 Deduplicate dependencies 2025-01-09 23:33:54 +02:00
Thodoris Greasidis
29e7827eb1 Use the promises namespace of balena-image-fs
Change-type: patch
2025-01-09 23:33:54 +02:00
Thodoris Greasidis
1d77cf3665 Update balena-device-init to 8.1.3 & balena-image-fs to 7.3.0
Update balena-device-init from 8.1.0 to 8.1.3
Update balena-image-fs from 7.0.6 to 7.3.0

Change-type: patch
2025-01-09 23:33:54 +02:00
26 changed files with 1508 additions and 545 deletions

View File

@ -1,2 +0,0 @@
/completion/*
/bin/*

View File

@ -1,21 +0,0 @@
module.exports = {
extends: ['./node_modules/@balena/lint/config/.eslintrc.js'],
parserOptions: {
project: 'tsconfig.dev.json',
},
root: true,
rules: {
ignoreDefinitionFiles: 0,
// to avoid the `warning Forbidden non-null assertion @typescript-eslint/no-non-null-assertion`
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-shadow': 'off',
'@typescript-eslint/no-var-requires': 'off',
'no-restricted-imports': [
'error',
{
paths: ['resin-cli-visuals', 'chalk', 'common-tags', 'resin-cli-form'],
},
],
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
},
};

View File

@ -39,7 +39,7 @@ runs:
run: tar -xf ${{ runner.temp }}/custom.tgz
- name: Setup Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
with:
node-version: ${{ inputs.NODE_VERSION }}
cache: npm
@ -94,7 +94,7 @@ runs:
runner_arch="$(echo "${RUNNER_ARCH}" | tr '[:upper:]' '[:lower:]')"
if [[ $runner_os =~ darwin|macos|osx ]]; then
CSC_KEY_PASSWORD=${{ fromJSON(inputs.secrets).APPLE_SIGNING_PASSWORD }}
CSC_KEY_PASSWORD='${{ fromJSON(inputs.secrets).APPLE_SIGNING_PASSWORD }}'
CSC_KEYCHAIN=signing_temp
CSC_LINK=${{ fromJSON(inputs.secrets).APPLE_SIGNING }}
@ -135,7 +135,7 @@ runs:
XCODE_APP_LOADER_TEAM_ID: ${{ inputs.XCODE_APP_LOADER_TEAM_ID }}
- name: Upload artifacts
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4
with:
name: gh-release-${{ github.event.pull_request.head.sha || github.event.head_commit.id }}-${{ strategy.job-index }}
path: dist

View File

@ -26,7 +26,7 @@ runs:
steps:
# https://github.com/actions/setup-node#caching-global-packages-data
- name: Setup Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
with:
node-version: ${{ inputs.NODE_VERSION }}
cache: npm
@ -58,7 +58,7 @@ runs:
run: tar --exclude-vcs -acf ${{ runner.temp }}/custom.tgz .
- name: Upload custom artifact
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # 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,3 +1,455 @@
- commits:
- subject: Add support for new requirement labels feature
hash: 42c50ef8aed110b317a0472d928bf75e372b4c0b
body: |
Updates @balena/compose to v7 to include this new feature.
footer:
See: https://balena.fibery.io/Work/Project/Refactoring-container-contracts-1205
see: https://balena.fibery.io/Work/Project/Refactoring-container-contracts-1205
Depends-on: https://github.com/balena-io-modules/balena-compose/pull/64
depends-on: https://github.com/balena-io-modules/balena-compose/pull/64
Change-type: minor
change-type: minor
author: Felipe Lalanne
nested: []
version: 21.1.0
title: ""
date: 2025-03-12T19:34:17.610Z
- commits:
- subject: Drop support for OS versions <2.14.0
hash: aad62d1ccd11ebb69b1035d5b95aef93d384bfd5
body: ""
footer:
Change-type: major
change-type: major
author: myarmolinsky
nested: []
- subject: "api-key generate: Add required argument `expiryDate`"
hash: ecc6f80164fca3c0cde42b140b6d7404abe8c877
body: ""
footer:
Change-type: major
change-type: major
author: myarmolinsky
nested: []
- subject: Update `balena-preload` to 18.0.1
hash: 9d3120b144c2c017eda55463b034f1561d264213
body: ""
footer:
Change-type: patch
change-type: patch
author: myarmolinsky
nested: []
- subject: Add dependency `date-fns`
hash: ed0e03ddb274da294f719dc0e307ec37591e10d7
body: ""
footer:
Change-type: patch
change-type: patch
author: myarmolinsky
nested: []
- subject: Update `balena-sdk` to 21.2.1
hash: 8fe6d6c0268f69bcf3bcac3c57470272b959e9b0
body: ""
footer:
Change-type: patch
change-type: patch
author: myarmolinsky
nested: []
version: 21.0.0
title: ""
date: 2025-03-11T14:42:28.479Z
- commits:
- subject: Update TypeScript to 5.8.2
hash: a10156a441b737275cabfb03bd10bfc5aba7bc88
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: 20.2.10
title: ""
date: 2025-03-10T17:33:09.548Z
- commits:
- subject: Fix CORS issue with X-Balena-Client header
hash: 64d19438042921e89c522f022327ead85b286e9f
body: ""
footer:
Change-type: patch
change-type: patch
See: https://balena.fibery.io/Work/Project/Extend-the-X-Balena-Client-header-to-include-the-UI-CLI-version-as-well-1174
see: https://balena.fibery.io/Work/Project/Extend-the-X-Balena-Client-header-to-include-the-UI-CLI-version-as-well-1174
author: Thodoris Greasidis
nested: []
version: 20.2.9
title: ""
date: 2025-02-26T12:52:06.672Z
- commits:
- subject: Update balena-config-json dependency and fix test
hash: 93039b010db15fbf1c0d17d4ed8f0db554064de4
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: 20.2.8
title: ""
date: 2025-02-26T00:22:14.010Z
- commits:
- subject: Use the CLI version in the X-Balena-Client header
hash: bef5221ed891db12a0b760f12fc9654e2f4e241b
body: ""
footer:
Change-type: patch
change-type: patch
See: https://balena.fibery.io/Work/Project/Extend-the-X-Balena-Client-header-to-include-the-UI-CLI-version-as-well-1174
see: https://balena.fibery.io/Work/Project/Extend-the-X-Balena-Client-header-to-include-the-UI-CLI-version-as-well-1174
author: Thodoris Greasidis
nested: []
version: 20.2.7
title: ""
date: 2025-02-25T20:21:00.603Z
- commits:
- subject: Update actions/upload-artifact digest to 4cec3d8
hash: 6f0f7350cf65c35abd099a901266821c218478eb
body: |
Update actions/upload-artifact
footer:
Change-type: patch
change-type: patch
author: balena-renovate[bot]
nested: []
version: 20.2.6
title: ""
date: 2025-02-25T19:13:48.297Z
- commits:
- subject: Update actions/setup-node digest to 1d0ff46
hash: cddea24cefdfef475731e0a7d2bdec4992959a6b
body: |
Update actions/setup-node
footer:
Change-type: patch
change-type: patch
author: balena-renovate[bot]
nested: []
version: 20.2.5
title: ""
date: 2025-02-25T18:10:47.617Z
- commits:
- subject: Pin docker-modem and dockerode to avoid regression
hash: 2cba82e914c720e75b68bd4370a2a92b4d4a7ba0
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: 20.2.4
title: ""
date: 2025-02-25T17:17:00.607Z
- commits:
- subject: Remove unused old eslint version files
hash: 53be743b9dcecbb2f0d8841b6663e7af1a9006c3
body: ""
footer:
Change-type: patch
change-type: patch
author: Otavio Jacobi
nested: []
version: 20.2.3
title: ""
date: 2025-01-15T18:21:02.810Z
- commits:
- subject: Use the promises namespace of balena-image-fs
hash: 29e7827eb1dbe4b0395df51f09cea38c3b2fb2e4
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: Update balena-device-init to 8.1.3 & balena-image-fs to 7.3.0
hash: 1d77cf36652eaca007a25f6ebb85c8509662d576
body: |
Update balena-device-init from 8.1.0 to 8.1.3
Update balena-image-fs from 7.0.6 to 7.3.0
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested:
- commits:
- subject: Drop Bluebird from devDependencies
hash: e4b5c71032112664ba8dac4c9edc5dad5445818d
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: "flowzone: Remove empty with clause"
hash: e83b4ef55eeebffb86d0bcda78dd45ee0651c76f
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: Add the promises namespace as part of the exposed fs
hash: 9b73f44020de213a682afc21092e20caf68eaff8
body: ""
footer:
Change-type: minor
change-type: minor
author: Thodoris Greasidis
nested: []
version: balena-image-fs-7.3.0
title: ""
date: 2025-01-06T14:31:31.244Z
- commits:
- subject: Update dependency @types/node to v20
hash: 4a5f55ae8752b1b28638d3f4016910d5b2057d80
body: |
Update @types/node from 18.11.18 to 20.10.6
footer:
Change-type: patch
change-type: patch
author: Self-hosted Renovate Bot
nested: []
version: balena-image-fs-7.2.2
title: ""
date: 2024-01-02T18:50:24.990Z
- commits:
- subject: Remove repo config from flowzone.yml
hash: 3e0053a097a04c1d0c47139bc53787f07bfeb014
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: balena-image-fs-7.2.1
title: ""
date: 2023-12-19T21:54:42.129Z
- commits:
- subject: Add support for Node 18
hash: 2a3bef60d9688dce26bd1c9546a28c98cf6d2566
body: ""
footer:
Change-type: minor
change-type: minor
author: Akis Kesoglou
nested: []
version: balena-image-fs-7.2.0
title: ""
date: 2023-01-20T14:27:37.169Z
- commits:
- subject: Update dependencies
hash: 9acc4bd2e793076095880f1924f8540b4d95fa9c
body: ""
footer:
Change-type: patch
change-type: patch
author: ab77
nested: []
version: balena-image-fs-7.1.2
title: ""
date: 2023-01-05T22:29:15.022Z
- commits:
- subject: Update dependency jsdoc-to-markdown to 8.0.0
hash: 5cf71efa734819263bd75c9938cb4367f90e1391
body: |
Update jsdoc-to-markdown to 8.0.0
Update jsdoc-to-markdown from 7.1.1 to 8.0.0
footer:
Change-type: patch
change-type: patch
author: Renovate Bot
nested: []
version: balena-image-fs-7.1.1
title: ""
date: 2022-12-20T02:52:28.901Z
- commits:
- subject: update dependencies
hash: 71a5bb92caa0658e45d1fb36e8652ca5ea50dee9
body: ""
footer:
Change-type: minor
change-type: minor
author: Zane Hitchcox
nested: []
version: balena-image-fs-7.1.0
title: ""
date: 2022-12-13T00:03:20.006Z
- commits:
- subject: "README: Remove the travisci badge"
hash: 3602a9c0c503502229d12cc1ec1de5bbcbc1b13c
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: balena-device-init-8.1.3
title: ""
date: 2025-01-09T21:25:00.155Z
- commits:
- subject: Use the promises namespace of balena-image-fs
hash: de0af086c5d9124e4bbe5d66bf9aafe0f6c5f11b
body: |
Update balena-image-fs from 7.0.6 to 7.3.0
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested:
- commits:
- subject: Drop Bluebird from devDependencies
hash: e4b5c71032112664ba8dac4c9edc5dad5445818d
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: "flowzone: Remove empty with clause"
hash: e83b4ef55eeebffb86d0bcda78dd45ee0651c76f
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: Add the promises namespace as part of the exposed fs
hash: 9b73f44020de213a682afc21092e20caf68eaff8
body: ""
footer:
Change-type: minor
change-type: minor
author: Thodoris Greasidis
nested: []
version: balena-image-fs-7.3.0
title: ""
date: 2025-01-06T14:31:31.244Z
- commits:
- subject: Update dependency @types/node to v20
hash: 4a5f55ae8752b1b28638d3f4016910d5b2057d80
body: |
Update @types/node from 18.11.18 to 20.10.6
footer:
Change-type: patch
change-type: patch
author: Self-hosted Renovate Bot
nested: []
version: balena-image-fs-7.2.2
title: ""
date: 2024-01-02T18:50:24.990Z
- commits:
- subject: Remove repo config from flowzone.yml
hash: 3e0053a097a04c1d0c47139bc53787f07bfeb014
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: balena-image-fs-7.2.1
title: ""
date: 2023-12-19T21:54:42.129Z
- commits:
- subject: Add support for Node 18
hash: 2a3bef60d9688dce26bd1c9546a28c98cf6d2566
body: ""
footer:
Change-type: minor
change-type: minor
author: Akis Kesoglou
nested: []
version: balena-image-fs-7.2.0
title: ""
date: 2023-01-20T14:27:37.169Z
- commits:
- subject: Update dependencies
hash: 9acc4bd2e793076095880f1924f8540b4d95fa9c
body: ""
footer:
Change-type: patch
change-type: patch
author: ab77
nested: []
version: balena-image-fs-7.1.2
title: ""
date: 2023-01-05T22:29:15.022Z
- commits:
- subject: Update dependency jsdoc-to-markdown to 8.0.0
hash: 5cf71efa734819263bd75c9938cb4367f90e1391
body: |
Update jsdoc-to-markdown to 8.0.0
Update jsdoc-to-markdown from 7.1.1 to 8.0.0
footer:
Change-type: patch
change-type: patch
author: Renovate Bot
nested: []
version: balena-image-fs-7.1.1
title: ""
date: 2022-12-20T02:52:28.901Z
- commits:
- subject: update dependencies
hash: 71a5bb92caa0658e45d1fb36e8652ca5ea50dee9
body: ""
footer:
Change-type: minor
change-type: minor
author: Zane Hitchcox
nested: []
version: balena-image-fs-7.1.0
title: ""
date: 2022-12-13T00:03:20.006Z
version: balena-device-init-8.1.2
title: ""
date: 2025-01-09T20:28:30.604Z
- commits:
- subject: Convert some parts to async await and simplify
hash: eb1105cd738998bae9c3dd604a8d25f71eb38e19
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
- subject: Avoid unnecessary destructuring
hash: 4cea6b650ec1c911cf2fc12a4a1dc410c0e7d075
body: ""
footer:
Change-type: patch
change-type: patch
author: Thodoris Greasidis
nested: []
version: balena-device-init-8.1.1
title: ""
date: 2025-01-06T06:37:04.147Z
version: 20.2.2
title: ""
date: 2025-01-12T14:49:03.225Z
- commits:
- subject: Update balena-preload to 17.0.0
hash: 60bc5092e0d6014aecf57d157cac536b3c645f0f

View File

@ -4,6 +4,139 @@ 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/).
## 21.1.0 - 2025-03-12
* Add support for new requirement labels feature [Felipe Lalanne]
## 21.0.0 - 2025-03-11
* Drop support for OS versions <2.14.0 [myarmolinsky]
* api-key generate: Add required argument `expiryDate` [myarmolinsky]
* Update `balena-preload` to 18.0.1 [myarmolinsky]
* Add dependency `date-fns` [myarmolinsky]
* Update `balena-sdk` to 21.2.1 [myarmolinsky]
## 20.2.10 - 2025-03-10
* Update TypeScript to 5.8.2 [Thodoris Greasidis]
## 20.2.9 - 2025-02-26
* Fix CORS issue with X-Balena-Client header [Thodoris Greasidis]
## 20.2.8 - 2025-02-26
* Update balena-config-json dependency and fix test [Ken Bannister]
## 20.2.7 - 2025-02-25
* Use the CLI version in the X-Balena-Client header [Thodoris Greasidis]
## 20.2.6 - 2025-02-25
* Update actions/upload-artifact digest to 4cec3d8 [balena-renovate[bot]]
## 20.2.5 - 2025-02-25
* Update actions/setup-node digest to 1d0ff46 [balena-renovate[bot]]
## 20.2.4 - 2025-02-25
* Pin docker-modem and dockerode to avoid regression [Ken Bannister]
## 20.2.3 - 2025-01-15
* Remove unused old eslint version files [Otavio Jacobi]
## 20.2.2 - 2025-01-12
* Use the promises namespace of balena-image-fs [Thodoris Greasidis]
<details>
<summary> Update balena-device-init to 8.1.3 & balena-image-fs to 7.3.0 [Thodoris Greasidis] </summary>
> ### balena-image-fs-7.3.0 - 2025-01-06
>
> * Drop Bluebird from devDependencies [Thodoris Greasidis]
> * flowzone: Remove empty with clause [Thodoris Greasidis]
> * Add the promises namespace as part of the exposed fs [Thodoris Greasidis]
>
> ### balena-image-fs-7.2.2 - 2024-01-02
>
> * Update dependency @types/node to v20 [Self-hosted Renovate Bot]
>
> ### balena-image-fs-7.2.1 - 2023-12-19
>
> * Remove repo config from flowzone.yml [Kyle Harding]
>
> ### balena-image-fs-7.2.0 - 2023-01-20
>
> * Add support for Node 18 [Akis Kesoglou]
>
> ### balena-image-fs-7.1.2 - 2023-01-05
>
> * Update dependencies [ab77]
>
> ### balena-image-fs-7.1.1 - 2022-12-20
>
> * Update dependency jsdoc-to-markdown to 8.0.0 [Renovate Bot]
>
> ### balena-image-fs-7.1.0 - 2022-12-13
>
> * update dependencies [Zane Hitchcox]
>
> ### balena-device-init-8.1.3 - 2025-01-09
>
> * README: Remove the travisci badge [Thodoris Greasidis]
>
> ### balena-device-init-8.1.2 - 2025-01-09
>
>
> <details>
> <summary> Use the promises namespace of balena-image-fs [Thodoris Greasidis] </summary>
>
>> #### balena-image-fs-7.3.0 - 2025-01-06
>>
>> * Drop Bluebird from devDependencies [Thodoris Greasidis]
>> * flowzone: Remove empty with clause [Thodoris Greasidis]
>> * Add the promises namespace as part of the exposed fs [Thodoris Greasidis]
>>
>> #### balena-image-fs-7.2.2 - 2024-01-02
>>
>> * Update dependency @types/node to v20 [Self-hosted Renovate Bot]
>>
>> #### balena-image-fs-7.2.1 - 2023-12-19
>>
>> * Remove repo config from flowzone.yml [Kyle Harding]
>>
>> #### balena-image-fs-7.2.0 - 2023-01-20
>>
>> * Add support for Node 18 [Akis Kesoglou]
>>
>> #### balena-image-fs-7.1.2 - 2023-01-05
>>
>> * Update dependencies [ab77]
>>
>> #### balena-image-fs-7.1.1 - 2022-12-20
>>
>> * Update dependency jsdoc-to-markdown to 8.0.0 [Renovate Bot]
>>
>> #### balena-image-fs-7.1.0 - 2022-12-13
>>
>> * update dependencies [Zane Hitchcox]
>>
>
> </details>
>
>
> ### balena-device-init-8.1.1 - 2025-01-06
>
> * Convert some parts to async await and simplify [Thodoris Greasidis]
> * Avoid unnecessary destructuring [Thodoris Greasidis]
>
</details>
## 20.2.1 - 2025-01-01

View File

@ -305,7 +305,7 @@ async function zipPkg() {
);
}
await fs.mkdirp(path.dirname(outputFile));
await new Promise((resolve, reject) => {
await new Promise<void>((resolve, reject) => {
console.log(`Zipping standalone package to "${outputFile}"...`);
const archive = archiver('zip', {

View File

@ -326,6 +326,8 @@ or to authenticate requests to the API with an 'Authorization: Bearer <key>' hea
Examples:
$ balena api-key generate "Jenkins Key"
$ balena api-key generate "Jenkins Key" 2025-10-30
$ balena api-key generate "Jenkins Key" never
### Arguments
@ -333,6 +335,10 @@ Examples:
the API key name
#### EXPIRYDATE
the expiry date of the API key as an ISO date string, or "never" for no expiry
## api-key list
### Aliases

1105
npm-shrinkwrap.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "balena-cli",
"version": "20.2.1",
"version": "21.1.0",
"description": "The official balena Command Line Interface",
"main": "./build/app.js",
"homepage": "https://github.com/balena-io/balena-cli",
@ -58,6 +58,7 @@
"build:completion": "node completion/generate-completion.js",
"build:standalone": "ts-node --transpile-only automation/run.ts build:standalone",
"build:installer": "ts-node --transpile-only automation/run.ts build:installer",
"deduplicate-dependencies": "npm dd && git add npm-shrinkwrap.json && git commit --message \"Deduplicate dependencies\"",
"package": "npm run build:fast && npm run build:standalone && npm run build:installer",
"pretest": "npm run build",
"test": "npm run test:shrinkwrap && npm run test:core",
@ -186,21 +187,21 @@
"sinon": "^19.0.0",
"string-to-stream": "^3.0.1",
"ts-node": "^10.4.0",
"typescript": "^5.7.2"
"typescript": "^5.8.2"
},
"dependencies": {
"@balena/compose": "^6.0.0",
"@balena/compose": "^7.0.1",
"@balena/dockerignore": "^1.0.2",
"@balena/env-parsing": "^1.1.8",
"@balena/es-version": "^1.0.1",
"@oclif/core": "^4.1.0",
"@sentry/node": "^6.16.1",
"balena-config-json": "^4.2.0",
"balena-device-init": "^8.1.0",
"balena-config-json": "^4.2.2",
"balena-device-init": "^8.1.3",
"balena-errors": "^4.7.3",
"balena-image-fs": "^7.0.6",
"balena-preload": "^17.0.0",
"balena-sdk": "^20.8.0",
"balena-image-fs": "^7.3.0",
"balena-preload": "^18.0.1",
"balena-sdk": "^21.2.1",
"balena-semver": "^2.3.0",
"balena-settings-client": "^5.0.2",
"balena-settings-storage": "^8.1.0",
@ -211,10 +212,11 @@
"cli-truncate": "^2.1.0",
"color-hash": "^1.1.1",
"common-tags": "^1.7.2",
"date-fns": "^4.1.0",
"denymount": "^2.3.0",
"docker-modem": "^5.0.3",
"docker-modem": "5.0.5",
"docker-progress": "^5.1.3",
"dockerode": "^4.0.2",
"dockerode": "4.0.3",
"ejs": "^3.1.6",
"etcher-sdk": "9.1.0",
"express": "^4.17.2",
@ -274,6 +276,6 @@
}
},
"versionist": {
"publishedAt": "2025-01-01T18:04:59.323Z"
"publishedAt": "2025-03-12T19:34:18.617Z"
}
}

View File

@ -6,6 +6,8 @@ upstream:
url: 'https://github.com/balena-io/balena-sdk'
- repo: 'balena-config-json'
url: 'https://github.com/balena-io-modules/balena-config-json'
- repo: 'balena-image-fs'
url: 'https://github.com/balena-io-modules/balena-image-fs'
- repo: 'balena-device-init'
url: 'https://github.com/balena-io-modules/balena-device-init'
- repo: 'balena-image-manager'

View File

@ -17,7 +17,16 @@
import { Args, Command } from '@oclif/core';
import { ExpectedError } from '../../errors';
import { getBalenaSdk, stripIndent } from '../../utils/lazy';
import { getBalenaSdk, getCliForm, stripIndent } from '../../utils/lazy';
import {
formatDuration,
intervalToDuration,
isValid,
parseISO,
} from 'date-fns';
// In days
const durations = [1, 7, 30, 90];
async function isLoggedInWithJwt() {
const balena = getBalenaSdk();
@ -41,13 +50,21 @@ export default class GenerateCmd extends Command {
This key can be used to log into the CLI using 'balena login --token <key>',
or to authenticate requests to the API with an 'Authorization: Bearer <key>' header.
`;
public static examples = ['$ balena api-key generate "Jenkins Key"'];
public static examples = [
'$ balena api-key generate "Jenkins Key"',
'$ balena api-key generate "Jenkins Key" 2025-10-30',
'$ balena api-key generate "Jenkins Key" never',
];
public static args = {
name: Args.string({
description: 'the API key name',
required: true,
}),
expiryDate: Args.string({
description:
'the expiry date of the API key as an ISO date string, or "never" for no expiry',
}),
};
public static authenticated = true;
@ -55,9 +72,61 @@ export default class GenerateCmd extends Command {
public async run() {
const { args: params } = await this.parse(GenerateCmd);
let expiryDateResponse: string | number | undefined = params.expiryDate;
let key;
try {
key = await getBalenaSdk().models.apiKey.create(params.name);
if (!expiryDateResponse) {
expiryDateResponse = await getCliForm().ask({
message: 'Please pick an expiry date for the API key',
type: 'list',
choices: [...durations, 'custom', 'never'].map((duration) => ({
name:
duration === 'never'
? 'No expiration'
: typeof duration === 'number'
? formatDuration(
intervalToDuration({
start: 0,
end: duration * 24 * 60 * 60 * 1000,
}),
)
: 'Custom expiration',
value: duration,
})),
});
}
let expiryDate: Date | null;
if (expiryDateResponse === 'never') {
expiryDate = null;
} else if (expiryDateResponse === 'custom') {
do {
expiryDate = parseISO(
await getCliForm().ask({
message:
'Please enter an expiry date for the API key as an ISO date string',
type: 'input',
}),
);
if (!isValid(expiryDate)) {
console.error('Invalid date format');
}
} while (!isValid(expiryDate));
} else if (typeof expiryDateResponse === 'string') {
expiryDate = parseISO(expiryDateResponse);
if (!isValid(expiryDate)) {
throw new Error(
'Invalid date format, please use a valid ISO date string',
);
}
} else {
expiryDate = new Date(
Date.now() + expiryDateResponse * 24 * 60 * 60 * 1000,
);
}
key = await getBalenaSdk().models.apiKey.create({
name: params.name,
expiryDate: expiryDate === null ? null : expiryDate.toISOString(),
});
} catch (e) {
if (e.name === 'BalenaNotLoggedIn') {
if (await isLoggedInWithJwt()) {

View File

@ -368,6 +368,7 @@ ${dockerignoreHelp}
!opts.shouldUploadLogs,
composeOpts.projectPath,
opts.createAsDraft,
project.descriptors,
);
}

View File

@ -16,7 +16,6 @@
*/
import { Args, Command } from '@oclif/core';
import { promisify } from 'util';
import { stripIndent } from '../../utils/lazy';
export default class LocalConfigureCmd extends Command {
@ -237,7 +236,7 @@ export default class LocalConfigureCmd extends Command {
const bootPartition = await getBootPartition(target);
const files = await imagefs.interact(target, bootPartition, async (_fs) => {
return await promisify(_fs.readdir)(this.CONNECTIONS_FOLDER);
return await _fs.promises.readdir(this.CONNECTIONS_FOLDER);
});
let connectionFileName;
@ -246,13 +245,14 @@ export default class LocalConfigureCmd extends Command {
} else if (_.includes(files, 'resin-sample.ignore')) {
// Fresh image, new mode, accoding to https://github.com/balena-os/meta-balena/pull/770/files
await imagefs.interact(target, bootPartition, async (_fs) => {
const readFileAsync = promisify(_fs.readFile);
const writeFileAsync = promisify(_fs.writeFile);
const contents = await readFileAsync(
const contents = await _fs.promises.readFile(
`${this.CONNECTIONS_FOLDER}/resin-sample.ignore`,
{ encoding: 'utf8' },
);
await writeFileAsync(`${this.CONNECTIONS_FOLDER}/resin-wifi`, contents);
await _fs.promises.writeFile(
`${this.CONNECTIONS_FOLDER}/resin-wifi`,
contents,
);
});
} else if (_.includes(files, 'resin-sample')) {
// Legacy mode, to be removed later
@ -266,7 +266,7 @@ export default class LocalConfigureCmd extends Command {
} else {
// In case there's no file at all (shouldn't happen normally, but the file might have been removed)
await imagefs.interact(target, bootPartition, async (_fs) => {
await promisify(_fs.writeFile)(
await _fs.promises.writeFile(
`${this.CONNECTIONS_FOLDER}/resin-wifi`,
this.CONNECTION_FILE,
);

View File

@ -18,7 +18,6 @@
import { Flags, Args, Command } from '@oclif/core';
import type { Interfaces } from '@oclif/core';
import type * as BalenaSdk from 'balena-sdk';
import { promisify } from 'util';
import * as _ from 'lodash';
import { ExpectedError } from '../../errors';
import * as cf from '../../utils/common-flags';
@ -292,7 +291,7 @@ export default class OsConfigureCmd extends Command {
for (const { name, content } of files) {
await imagefs.interact(image, bootPartition, async (_fs) => {
await promisify(_fs.writeFile)(
await _fs.promises.writeFile(
path.join(CONNECTIONS_FOLDER, name),
content,
);

View File

@ -295,7 +295,7 @@ Can be repeated to add multiple certificates.\
owns__release: {
$select: ['id', 'commit', 'end_timestamp', 'composition'],
$expand: {
contains__image: {
release_image: {
$select: ['image'],
$expand: {
image: {

View File

@ -128,6 +128,7 @@ export const createRelease = async function (
draft: boolean,
semver: string | undefined,
contract: import('@balena/compose/dist/release/models').ReleaseModel['contract'],
imgDescriptors: ImageDescriptor[],
): Promise<Release> {
const _ = require('lodash') as typeof import('lodash');
const crypto = require('crypto') as typeof import('crypto');
@ -167,6 +168,7 @@ export const createRelease = async function (
semver,
is_final: !draft,
contract,
imgDescriptors,
});
return {
@ -240,7 +242,7 @@ export const getPreviousRepos = (
status: 'success',
},
$expand: {
contains__image: {
release_image: {
$select: 'image',
$expand: { image: { $select: 'is_stored_at__image_location' } },
},
@ -252,7 +254,7 @@ export const getPreviousRepos = (
.then(function (release) {
// grab all images from the latest release, return all image locations in the registry
if (release.length > 0) {
const images = release[0].contains__image as Array<{
const images = release[0].release_image as Array<{
image: [SDK.Image];
}>;
const { getRegistryAndName } =

View File

@ -1375,6 +1375,7 @@ export async function deployProject(
skipLogUpload: boolean,
projectPath: string,
isDraft: boolean,
imgDescriptors: ImageDescriptor[],
): Promise<import('@balena/compose/dist/release/models').ReleaseModel> {
const releaseMod = await import('@balena/compose/dist/release');
const { createRelease, tagServiceImages } = await import('./compose');
@ -1405,6 +1406,7 @@ export async function deployProject(
isDraft,
contract?.version,
contract,
imgDescriptors,
),
);
const { client: pineClient, release, serviceImages } = $release;

View File

@ -14,7 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import type * as BalenaSdk from 'balena-sdk';
import * as semver from 'balena-semver';
import { getBalenaSdk, stripIndent } from './lazy';
export interface ImgConfig {
@ -122,16 +121,10 @@ export function generateDeviceConfig(
// os.getConfig always returns a config for an app
delete config.apiKey;
if (deviceApiKey == null && semver.satisfies(options.version, '<2.0.3')) {
config.apiKey = await sdk.models.application.generateApiKey(
application.id,
);
} else {
config.deviceApiKey =
typeof deviceApiKey === 'string' && deviceApiKey
? deviceApiKey
: await sdk.models.device.generateDeviceKey(device.uuid);
}
config.deviceApiKey =
typeof deviceApiKey === 'string' && deviceApiKey
? deviceApiKey
: await sdk.models.device.generateDeviceKey(device.uuid);
return config;
})

View File

@ -76,38 +76,28 @@ export const getImagePath = async (deviceType: string, version?: string) => {
};
/**
* @summary Determine if a device image is fresh
* @summary Determine if a device image is cached
*
* @description
* If the device image does not exist, return false.
*
* @param {String} deviceType - device type slug or alias
* @param {String} version - the exact balenaOS version number
* @returns {Promise<Boolean>} is image fresh
* @returns {Promise<Boolean>} is image cached
*
* @example
* isImageFresh('raspberry-pi', '1.2.3').then (isFresh) ->
* if isFresh
* console.log('The Raspberry Pi image v1.2.3 is fresh!')
* isImageCached ('raspberry-pi', '1.2.3').then (isCached) ->
* if isCached
* console.log('The Raspberry Pi image v1.2.3 is cached!')
*/
export const isImageFresh = async (deviceType: string, version: string) => {
export const isImageCached = async (deviceType: string, version: string) => {
const imagePath = await getImagePath(deviceType, version);
let createdDate;
try {
createdDate = await getFileCreatedDate(imagePath);
const createdDate = await getFileCreatedDate(imagePath);
return createdDate != null;
} catch {
// Swallow errors from getFileCreatedTime.
}
if (createdDate == null) {
return false;
}
const balena = getBalenaSdk();
const lastModifiedDate = await balena.models.os.getLastModified(
deviceType,
version,
);
return lastModifiedDate < createdDate;
};
/**
@ -286,7 +276,7 @@ export const getStream = async (
versionOrRange = 'latest';
}
const version = await resolveVersion(deviceType, versionOrRange);
const isFresh = await isImageFresh(deviceType, version);
const isFresh = await isImageCached(deviceType, version);
const $stream = isFresh
? await getImage(deviceType, version)
: await doDownload({ ...options, deviceType, version });

View File

@ -21,6 +21,7 @@ import type { Chalk } from 'chalk';
import type * as visuals from 'resin-cli-visuals';
import type * as CliForm from 'resin-cli-form';
import type { ux } from '@oclif/core';
import { version } from '../../package.json';
// Equivalent of _.once but avoiding the need to import lodash for lazy deps
const once = <T>(fn: () => T) => {
@ -43,9 +44,26 @@ export const onceAsync = <T>(fn: () => Promise<T>) => {
};
};
export const getBalenaSdk = once(() =>
(require('balena-sdk') as typeof BalenaSdk).fromSharedOptions(),
);
const cliXBalenaClientHeaderInterceptor: BalenaSdk.Interceptor = {
request($request) {
if ($request.headers['X-Balena-Client']) {
// We intentionally overwrite the sdk version string from the header
// to conserve bandwidth. We only do that when the SDK already has specified
// the X-Balena-Client header, since that signals that this is a safe url to
// include the extra header and will not cause CORS errors.
$request.headers['X-Balena-Client'] = `balena-cli/${version}`;
}
return $request;
},
};
export const getBalenaSdk = once(() => {
const sdk = (require('balena-sdk') as typeof BalenaSdk).fromSharedOptions();
if (!sdk.interceptors.includes(cliXBalenaClientHeaderInterceptor)) {
sdk.interceptors.push(cliXBalenaClientHeaderInterceptor);
}
return sdk;
});
export const getVisuals = once(
() => require('resin-cli-visuals') as typeof visuals,

View File

@ -50,7 +50,7 @@ export function copyQemu(context: string, arch: string) {
.then(() => getQemuPath(arch))
.then(
(qemu) =>
new Promise(function (resolve, reject) {
new Promise<void>(function (resolve, reject) {
const read = fs.createReadStream(qemu);
const write = fs.createWriteStream(binPath);

View File

@ -62,20 +62,22 @@ if (process.platform !== 'win32') {
tmpNonMatchingDtJsonPartitionPath,
12,
async (_fs) => {
const readFileAsync = promisify(_fs.readFile);
const writeFileAsync = promisify(_fs.writeFile);
const dtJson = JSON.parse(
await readFileAsync('/device-type.json', { encoding: 'utf8' }),
await _fs.promises.readFile('/device-type.json', {
encoding: 'utf8',
}),
);
expect(dtJson).to.have.nested.property(
'configuration.config.partition',
12,
);
dtJson.configuration.config.partition = 999;
await writeFileAsync('/device-type.json', JSON.stringify(dtJson));
await _fs.promises.writeFile(
'/device-type.json',
JSON.stringify(dtJson),
);
await writeFileAsync(
await _fs.promises.writeFile(
'/os-release',
stripIndent`
ID="balena-os"
@ -133,16 +135,17 @@ if (process.platform !== 'win32') {
tmpMatchingDtJsonPartitionPath,
12,
async (_fs) => {
const readFileAsync = promisify(_fs.readFile);
const dtJson = JSON.parse(
await readFileAsync('/device-type.json', { encoding: 'utf8' }),
await _fs.promises.readFile('/device-type.json', {
encoding: 'utf8',
}),
);
// confirm that the device-type.json mentions the expected partition
expect(dtJson).to.have.nested.property(
'configuration.config.partition',
12,
);
return await readFileAsync('/config.json');
return await _fs.promises.readFile('/config.json');
},
);
expect(config).to.not.be.empty;
@ -180,16 +183,17 @@ if (process.platform !== 'win32') {
tmpNonMatchingDtJsonPartitionPath,
12,
async (_fs) => {
const readFileAsync = promisify(_fs.readFile);
const dtJson = JSON.parse(
await readFileAsync('/device-type.json', { encoding: 'utf8' }),
await _fs.promises.readFile('/device-type.json', {
encoding: 'utf8',
}),
);
// confirm that the device-type.json mentions the expected partition
expect(dtJson).to.have.nested.property(
'configuration.config.partition',
999,
);
return await readFileAsync('/config.json');
return await _fs.promises.readFile('/config.json');
},
);
expect(config).to.not.be.empty;
@ -227,6 +231,10 @@ if (process.platform !== 'win32') {
err.flatMap((line) => line.split('\n')).filter((line) => line !== ''),
).to.deep.equal(
stripIndent`
[warn] "${tmpDummyPath}":
[warn] Found partition table with 1 partitions,
[warn] but none with a name/label in ['resin-boot', 'flash-boot', 'balena-boot'].
[warn] Will scan all partitions for contents.
[warn] "${tmpDummyPath}":
[warn] 1 partition(s) found, but none containing file "/device-type.json".
[warn] Assuming default boot partition number '1'.
@ -240,7 +248,7 @@ if (process.platform !== 'win32') {
// confirm the image contains a config.json...
const config = await imagefs.interact(tmpDummyPath, 1, async (_fs) => {
return await promisify(_fs.readFile)('/config.json');
return await _fs.promises.readFile('/config.json');
});
expect(config).to.not.be.empty;

View File

@ -82,7 +82,7 @@ describe('balena release', function () {
expect(err).to.be.empty;
const json = JSON.parse(out.join(''));
expect(json[0].commit).to.equal('90247b54de4fa7a0a3cbc85e73c68039');
expect(json[0].contains__image[0].image[0].start_timestamp).to.equal(
expect(json[0].release_image[0].image[0].start_timestamp).to.equal(
'2020-01-04T01:13:08.583Z',
);
});

View File

@ -10,7 +10,7 @@
"build_log": null,
"start_timestamp": "2021-08-25T22:18:33.624Z",
"end_timestamp": "2021-08-25T22:18:48.820Z",
"contains__image": [
"release_image": [
{
"image": [
{

View File

@ -42,7 +42,7 @@ describe('image-manager', function () {
describe('given the image is fresh', function () {
beforeEach(function () {
this.cacheIsImageFresh = stub(imageManager, 'isImageFresh');
this.cacheIsImageFresh = stub(imageManager, 'isImageCached');
return this.cacheIsImageFresh.resolves(true);
});
@ -56,7 +56,7 @@ describe('image-manager', function () {
void imageManager.getStream('raspberry-pi').then(function (stream) {
let result = '';
stream.on('data', (chunk) => (result += chunk.toString()));
stream.on('data', (chunk: string) => (result += chunk.toString()));
return stream.on('end', function () {
expect(result).to.equal('Cache image');
@ -68,7 +68,7 @@ describe('image-manager', function () {
describe('given the image is not fresh', function () {
beforeEach(function () {
this.cacheIsImageFresh = stub(imageManager, 'isImageFresh');
this.cacheIsImageFresh = stub(imageManager, 'isImageCached');
return this.cacheIsImageFresh.resolves(false);
});
@ -91,7 +91,7 @@ describe('image-manager', function () {
void imageManager.getStream('raspberry-pi').then((stream) => {
let result = '';
stream.on('data', (chunk) => (result += chunk));
stream.on('data', (chunk: string) => (result += chunk));
stream.on('end', async () => {
expect(result).to.equal('Download image');
@ -280,7 +280,7 @@ describe('image-manager', function () {
});
});
describe('.isImageFresh()', () => {
describe('.isImageCached()', () => {
describe('given the raspberry-pi manifest', function () {
beforeEach(function () {
this.getDeviceTypeManifestBySlugStub = stub(
@ -314,78 +314,8 @@ describe('image-manager', function () {
});
it('should return false', async function () {
expect(await imageManager.isImageFresh('raspberry-pi', '1.2.3')).to.be
.false;
});
});
describe('given a fixed created time', function () {
beforeEach(function () {
this.utilsGetFileCreatedDate = stub(
imageManager,
'getFileCreatedDate',
);
this.utilsGetFileCreatedDate.resolves(
new Date('2014-01-01T00:00:00.000Z'),
);
});
afterEach(function () {
this.utilsGetFileCreatedDate.restore();
});
describe('given the file was created before the os last modified time', function () {
beforeEach(function () {
this.osGetLastModified = stub(balena.models.os, 'getLastModified');
this.osGetLastModified.resolves(
new Date('2014-02-01T00:00:00.000Z'),
);
});
afterEach(function () {
this.osGetLastModified.restore();
});
it('should return false', function () {
const promise = imageManager.isImageFresh('raspberry-pi', '1.2.3');
return expect(promise).to.eventually.be.false;
});
});
describe('given the file was created after the os last modified time', function () {
beforeEach(function () {
this.osGetLastModified = stub(balena.models.os, 'getLastModified');
this.osGetLastModified.resolves(
new Date('2013-01-01T00:00:00.000Z'),
);
});
afterEach(function () {
this.osGetLastModified.restore();
});
it('should return true', function () {
const promise = imageManager.isImageFresh('raspberry-pi', '1.2.3');
return expect(promise).to.eventually.be.true;
});
});
describe('given the file was created just at the os last modified time', function () {
beforeEach(function () {
this.osGetLastModified = stub(balena.models.os, 'getLastModified');
this.osGetLastModified.resolves(
new Date('2014-00-01T00:00:00.000Z'),
);
});
afterEach(function () {
this.osGetLastModified.restore();
});
it('should return false', function () {
const promise = imageManager.isImageFresh('raspberry-pi', '1.2.3');
return expect(promise).to.eventually.be.false;
});
expect(await imageManager.isImageCached('raspberry-pi', '1.2.3')).to
.be.false;
});
});
});
@ -412,7 +342,7 @@ describe('image-manager', function () {
.then(function (stream) {
let result = '';
stream.on('data', (chunk: string) => (result += chunk));
stream.on('data', (chunk) => (result += chunk as string));
stream.on('end', function () {
expect(result).to.equal('Lorem ipsum dolor sit amet');