balena-cli 23.2.13 → 23.2.14-build-update-compose-tar-dependencies-8decbe453ca1f661f606bfb12ed61e774d54276a-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "balena-cli",
3
- "version": "23.2.13",
3
+ "version": "23.2.14-build-update-compose-tar-dependencies-8decbe453ca1f661f606bfb12ed61e774d54276a-1",
4
4
  "description": "The official balena Command Line Interface",
5
5
  "main": "./build/app.js",
6
6
  "homepage": "https://github.com/balena-io/balena-cli",
@@ -176,7 +176,7 @@
176
176
  "typescript": "^5.9.2"
177
177
  },
178
178
  "dependencies": {
179
- "@balena/compose": "^7.0.10",
179
+ "@balena/compose": "^7.2.1",
180
180
  "@balena/dockerignore": "^1.0.2",
181
181
  "@balena/env-parsing": "^1.1.8",
182
182
  "@balena/es-version": "^1.0.1",
@@ -243,8 +243,8 @@
243
243
  "stream-to-promise": "^2.2.0",
244
244
  "string-width": "^4.2.3",
245
245
  "strip-ansi-stream": "^1.0.0",
246
- "tar-stream": "^2.1.3",
247
- "tar-utils": "^3.0.3",
246
+ "tar-stream": "^3.1.7",
247
+ "tar-utils": "^3.1.1",
248
248
  "through2": "^2.0.3",
249
249
  "tmp": "^0.2.1",
250
250
  "typed-error": "^3.2.1",
@@ -262,6 +262,6 @@
262
262
  "balena-request": "14.0.6"
263
263
  },
264
264
  "versionist": {
265
- "publishedAt": "2025-12-29T14:29:28.509Z"
265
+ "publishedAt": "2025-12-30T07:41:17.796Z"
266
266
  }
267
267
  }
@@ -15,12 +15,9 @@
15
15
  * limitations under the License.
16
16
  */
17
17
 
18
- import type {
19
- ImageModel,
20
- ReleaseModel,
21
- } from '@balena/compose/dist/release/models';
22
- import type { Composition, ImageDescriptor } from '@balena/compose/dist/parse';
18
+ import type * as compose from '@balena/compose';
23
19
  import type { Pack } from 'tar-stream';
20
+ import type { BalenaModel } from 'balena-sdk';
24
21
 
25
22
  interface Image {
26
23
  context: string;
@@ -42,7 +39,10 @@ export interface BuiltImage {
42
39
 
43
40
  export interface TaggedImage {
44
41
  localImage: import('dockerode').Image;
45
- serviceImage: import('@balena/compose/dist/release/models').ImageModel;
42
+ serviceImage: Omit<
43
+ BalenaModel['image']['Read'],
44
+ 'created_at' | 'is_a_build_of__service'
45
+ >;
46
46
  serviceName: string;
47
47
  logs: string;
48
48
  props: BuiltImage.props;
@@ -75,14 +75,14 @@ export interface ComposeCliFlags {
75
75
  export interface ComposeProject {
76
76
  path: string;
77
77
  name: string;
78
- composition: Composition;
79
- descriptors: ImageDescriptor[];
78
+ composition: compose.parse.Composition;
79
+ descriptors: compose.parse.ImageDescriptor[];
80
80
  }
81
81
 
82
82
  export interface Release {
83
- client: import('@balena/compose').release.Request['client'];
83
+ client: compose.release.Request['client'];
84
84
  release: Pick<
85
- ReleaseModel,
85
+ BalenaModel['release']['Read'],
86
86
  | 'id'
87
87
  | 'status'
88
88
  | 'commit'
@@ -95,12 +95,12 @@ export interface Release {
95
95
  | 'end_timestamp'
96
96
  >;
97
97
  serviceImages: Dictionary<
98
- Omit<ImageModel, 'created_at' | 'is_a_build_of__service'>
98
+ Omit<BalenaModel['image']['Read'], 'created_at' | 'is_a_build_of__service'>
99
99
  >;
100
100
  }
101
101
 
102
102
  interface TarDirectoryOptions {
103
- composition?: Composition;
103
+ composition?: compose.parse.Composition;
104
104
  convertEol?: boolean;
105
105
  multiDockerignore?: boolean;
106
106
  preFinalizeCallback?: (pack: Pack) => void | Promise<void>;
@@ -128,7 +128,7 @@ export const createRelease = async function (
128
128
  composition: Composition,
129
129
  draft: boolean,
130
130
  semver: string | undefined,
131
- contract: import('@balena/compose/dist/release/models').ReleaseModel['contract'],
131
+ contract: import('@balena/compose/dist/release').Request['contract'],
132
132
  imgDescriptors: ImageDescriptor[],
133
133
  ): Promise<Release> {
134
134
  const crypto = require('crypto') as typeof import('crypto');
@@ -156,7 +156,7 @@ export const createRelease = async function (
156
156
  );
157
157
 
158
158
  const { id: userId } = await sdk.auth.getUserInfo();
159
- const { release, serviceImages } = await releaseMod.create({
159
+ const { release, serviceImages: $serviceImages } = await releaseMod.create({
160
160
  client: pinejsClient,
161
161
  user: userId,
162
162
  application: appId,
@@ -169,14 +169,19 @@ export const createRelease = async function (
169
169
  imgDescriptors,
170
170
  });
171
171
 
172
- for (const serviceImage of Object.values(serviceImages)) {
173
- if ('created_at' in serviceImage) {
174
- delete serviceImage.created_at;
175
- }
176
- if ('is_a_build_of__service' in serviceImage) {
177
- delete serviceImage.is_a_build_of__service;
178
- }
179
- }
172
+ const serviceImages = Object.fromEntries(
173
+ Object.entries($serviceImages).map(([key, serviceImage]) => {
174
+ if (
175
+ 'created_at' in serviceImage ||
176
+ 'is_a_build_of__service' in serviceImage
177
+ ) {
178
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars -- omit the created_at, is_a_build_of__service props
179
+ const { created_at, is_a_build_of__service, ...si } = serviceImage;
180
+ return [key, si];
181
+ }
182
+ return [key, serviceImage];
183
+ }),
184
+ );
180
185
 
181
186
  return {
182
187
  client: pinejsClient,
@@ -37,6 +37,7 @@ import type {
37
37
  BuiltImage,
38
38
  ComposeOpts,
39
39
  ComposeProject,
40
+ Release,
40
41
  TaggedImage,
41
42
  TarDirectoryOptions,
42
43
  } from './compose-types';
@@ -44,7 +45,6 @@ import type { DeviceInfo } from './device/api';
44
45
  import { getBalenaSdk, getCliUx, stripIndent } from './lazy';
45
46
  import Logger = require('./logger');
46
47
  import { exists } from './which';
47
- import { pick } from './helpers';
48
48
 
49
49
  const allowedContractTypes = ['sw.application', 'sw.block'];
50
50
 
@@ -1274,7 +1274,7 @@ async function pushAndUpdateServiceImages(
1274
1274
  token: string,
1275
1275
  images: TaggedImage[],
1276
1276
  afterEach: (
1277
- serviceImage: import('@balena/compose/dist/release/models').ImageModel,
1277
+ serviceImage: TaggedImage['serviceImage'],
1278
1278
  props: object,
1279
1279
  ) => Promise<void>,
1280
1280
  ) {
@@ -1338,7 +1338,7 @@ async function pushAndUpdateServiceImages(
1338
1338
  if (props.endTime) {
1339
1339
  serviceImage.end_timestamp = props.endTime;
1340
1340
  }
1341
- serviceImage.push_timestamp = new Date();
1341
+ serviceImage.push_timestamp = new Date().toISOString();
1342
1342
  serviceImage.status = 'success';
1343
1343
  } catch (error) {
1344
1344
  serviceImage.error_message = '' + error;
@@ -1378,23 +1378,23 @@ async function pushServiceImages(
1378
1378
  logger.logDebug(
1379
1379
  `Saving image ${serviceImage.is_stored_at__image_location}`,
1380
1380
  );
1381
- if (skipLogUpload) {
1382
- delete serviceImage.build_log;
1383
- }
1384
1381
 
1385
1382
  // These are the only update-able image fields in bC atm, and passing
1386
1383
  // the whole image object in v7+ would result the allowlist to reject the request.
1387
- const imagePayload = pick(serviceImage, [
1384
+ const imagePayloadFields = [
1388
1385
  'end_timestamp',
1389
1386
  'project_type',
1390
1387
  'error_message',
1391
- 'build_log',
1392
1388
  'push_timestamp',
1393
1389
  'status',
1394
1390
  'content_hash',
1395
1391
  'dockerfile',
1396
1392
  'image_size',
1397
- ]);
1393
+ ];
1394
+ if (!skipLogUpload) {
1395
+ imagePayloadFields.push('build_log');
1396
+ }
1397
+ const imagePayload = _.pick(serviceImage, imagePayloadFields);
1398
1398
 
1399
1399
  if (
1400
1400
  typeof imagePayload.error_message === 'string' &&
@@ -1425,7 +1425,7 @@ export async function deployProject(
1425
1425
  projectPath: string,
1426
1426
  isDraft: boolean,
1427
1427
  imgDescriptors: ImageDescriptor[],
1428
- ): Promise<import('@balena/compose/dist/release/models').ReleaseModel> {
1428
+ ): Promise<Release['release']> {
1429
1429
  const releaseMod = await import('@balena/compose/dist/release');
1430
1430
  const { createRelease, tagServiceImages } = await import('./compose');
1431
1431
  const tty = (await import('./tty'))(process.stdout);
@@ -1496,7 +1496,7 @@ export async function deployProject(
1496
1496
  }
1497
1497
  } finally {
1498
1498
  await runSpinner(tty, spinner, `${prefix}Saving release...`, async () => {
1499
- release.end_timestamp = new Date();
1499
+ release.end_timestamp = new Date().toISOString();
1500
1500
  if (release.id != null) {
1501
1501
  await releaseMod.updateRelease(pineClient, release.id, {
1502
1502
  status: release.status,
@@ -1552,9 +1552,7 @@ export function createRunLoop(tick: (...args: any[]) => void) {
1552
1552
 
1553
1553
  async function getContractContent(
1554
1554
  filePath: string,
1555
- ): Promise<
1556
- import('@balena/compose/dist/release/models').ReleaseModel['contract']
1557
- > {
1555
+ ): Promise<import('@balena/compose/dist/release').Request['contract']> {
1558
1556
  let fileContentAsString;
1559
1557
  try {
1560
1558
  fileContentAsString = await fs.readFile(filePath, 'utf8');