balena-cli 23.2.15-build-update-compose-7-3-0-97bf26975807627a264274621ffcf8380aea838e-1 → 23.2.15-build-mockttp-6cb0abaec2656b73d1230e92f9e8a907f95bef98-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/CHANGELOG.md +12 -3
- package/build/commands/os/configure.js.map +1 -1
- package/build/commands/release/list.js +4 -4
- package/build/commands/release/list.js.map +1 -1
- package/build/deprecation.js +3 -1
- package/build/deprecation.js.map +1 -1
- package/build/utils/compose.d.ts +2 -2
- package/build/utils/compose.js +3 -3
- package/build/utils/compose.js.map +1 -1
- package/build/utils/compose_ts.d.ts +2 -2
- package/build/utils/compose_ts.js +7 -8
- package/build/utils/compose_ts.js.map +1 -1
- package/build/utils/device/api.js +3 -1
- package/build/utils/device/api.js.map +1 -1
- package/npm-shrinkwrap.json +976 -39
- package/oclif.manifest.json +791 -791
- package/package.json +6 -4
- package/src/commands/os/configure.ts +4 -4
- package/src/commands/release/list.ts +4 -4
- package/src/deprecation.ts +4 -1
- package/src/utils/compose-types.d.ts +19 -32
- package/src/utils/compose.ts +5 -8
- package/src/utils/compose_ts.ts +13 -13
- package/src/utils/device/api.ts +3 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "balena-cli",
|
|
3
|
-
"version": "23.2.15-build-
|
|
3
|
+
"version": "23.2.15-build-mockttp-6cb0abaec2656b73d1230e92f9e8a907f95bef98-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",
|
|
@@ -165,6 +165,7 @@
|
|
|
165
165
|
"mocha": "^10.6.0",
|
|
166
166
|
"mock-fs": "^5.2.0",
|
|
167
167
|
"mock-require": "^3.0.3",
|
|
168
|
+
"mockttp": "^4.2.0",
|
|
168
169
|
"nock": "^14.0.4",
|
|
169
170
|
"oclif": "^4.22.61",
|
|
170
171
|
"rewire": "^7.0.0",
|
|
@@ -173,10 +174,11 @@
|
|
|
173
174
|
"sinon": "^19.0.0",
|
|
174
175
|
"string-to-stream": "^3.0.1",
|
|
175
176
|
"ts-node": "^10.4.0",
|
|
176
|
-
"typescript": "^5.9.2"
|
|
177
|
+
"typescript": "^5.9.2",
|
|
178
|
+
"undici": "^7.16.0"
|
|
177
179
|
},
|
|
178
180
|
"dependencies": {
|
|
179
|
-
"@balena/compose": "^7.
|
|
181
|
+
"@balena/compose": "^7.0.10",
|
|
180
182
|
"@balena/dockerignore": "^1.0.2",
|
|
181
183
|
"@balena/env-parsing": "^1.1.8",
|
|
182
184
|
"@balena/es-version": "^1.0.1",
|
|
@@ -262,6 +264,6 @@
|
|
|
262
264
|
"balena-request": "14.0.6"
|
|
263
265
|
},
|
|
264
266
|
"versionist": {
|
|
265
|
-
"publishedAt": "2026-01-
|
|
267
|
+
"publishedAt": "2026-01-07T17:29:28.041Z"
|
|
266
268
|
}
|
|
267
269
|
}
|
|
@@ -208,7 +208,7 @@ export default class OsConfigureCmd extends Command {
|
|
|
208
208
|
})) as DeviceWithDeviceType & {
|
|
209
209
|
belongs_to__application: BalenaSdk.PineDeferred;
|
|
210
210
|
};
|
|
211
|
-
deviceTypeSlug = device.is_of__device_type[0].slug
|
|
211
|
+
deviceTypeSlug = device.is_of__device_type[0].slug;
|
|
212
212
|
} else if (fleetSlugOrId != null) {
|
|
213
213
|
app = await getApplication(balena, fleetSlugOrId, {
|
|
214
214
|
$select: 'slug',
|
|
@@ -226,7 +226,7 @@ export default class OsConfigureCmd extends Command {
|
|
|
226
226
|
|
|
227
227
|
const deviceTypeManifest = await helpers.getManifest(
|
|
228
228
|
params.image,
|
|
229
|
-
deviceTypeSlug
|
|
229
|
+
deviceTypeSlug,
|
|
230
230
|
);
|
|
231
231
|
|
|
232
232
|
const { normalizeOsVersion } = await import('../../utils/normalization');
|
|
@@ -242,7 +242,7 @@ export default class OsConfigureCmd extends Command {
|
|
|
242
242
|
);
|
|
243
243
|
await validateSecureBootOptionAndWarn(
|
|
244
244
|
secureBoot,
|
|
245
|
-
deviceTypeSlug
|
|
245
|
+
deviceTypeSlug,
|
|
246
246
|
osVersion,
|
|
247
247
|
);
|
|
248
248
|
|
|
@@ -258,7 +258,7 @@ export default class OsConfigureCmd extends Command {
|
|
|
258
258
|
};
|
|
259
259
|
const answers: AugmentedAnswers = {
|
|
260
260
|
...baseAnswers,
|
|
261
|
-
deviceType: deviceTypeSlug
|
|
261
|
+
deviceType: deviceTypeSlug,
|
|
262
262
|
version: osVersion,
|
|
263
263
|
developmentMode: developmentMode,
|
|
264
264
|
secureBoot: secureBoot,
|
|
@@ -89,10 +89,10 @@ export default class ReleaseListCmd extends Command {
|
|
|
89
89
|
(r) => r.id,
|
|
90
90
|
);
|
|
91
91
|
|
|
92
|
-
const augmentedReleases = releases.map((release) => {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
});
|
|
92
|
+
const augmentedReleases = releases.map((release) => ({
|
|
93
|
+
...release,
|
|
94
|
+
...releasesWithExplicitReadFieldsById[release.id],
|
|
95
|
+
}));
|
|
96
96
|
|
|
97
97
|
await pipeline(
|
|
98
98
|
Readable.from(augmentedReleases),
|
package/src/deprecation.ts
CHANGED
|
@@ -89,7 +89,10 @@ export class DeprecationChecker {
|
|
|
89
89
|
* @param version Semver without 'v' prefix, e.g. '12.0.0.'
|
|
90
90
|
*/
|
|
91
91
|
protected getNpmUrl(version: string) {
|
|
92
|
-
|
|
92
|
+
// Allow override for testing with mock servers
|
|
93
|
+
const registryUrl =
|
|
94
|
+
process.env.BALENARC_NPM_REGISTRY ?? 'https://registry.npmjs.org';
|
|
95
|
+
return `${registryUrl}/balena-cli/${version}`;
|
|
93
96
|
}
|
|
94
97
|
|
|
95
98
|
/**
|
|
@@ -15,7 +15,10 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import type {
|
|
18
|
+
import type {
|
|
19
|
+
ImageModel,
|
|
20
|
+
ReleaseModel,
|
|
21
|
+
} from '@balena/compose/dist/release/models';
|
|
19
22
|
import type { Composition, ImageDescriptor } from '@balena/compose/dist/parse';
|
|
20
23
|
import type { Pack } from 'tar-stream';
|
|
21
24
|
|
|
@@ -24,32 +27,25 @@ interface Image {
|
|
|
24
27
|
tag: string;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
interface ImageProperties {
|
|
28
|
-
dockerfile?: string;
|
|
29
|
-
projectType?: string;
|
|
30
|
-
size?: number;
|
|
31
|
-
startTime?: Date;
|
|
32
|
-
endTime?: Date;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
30
|
export interface BuiltImage {
|
|
36
31
|
logs: string;
|
|
37
32
|
name: string;
|
|
38
|
-
props:
|
|
33
|
+
props: {
|
|
34
|
+
dockerfile?: string;
|
|
35
|
+
projectType?: string;
|
|
36
|
+
size?: number;
|
|
37
|
+
startTime?: Date;
|
|
38
|
+
endTime?: Date;
|
|
39
|
+
};
|
|
39
40
|
serviceName: string;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
type ServiceImage = Omit<
|
|
43
|
-
BalenaModel['image']['Read'],
|
|
44
|
-
'created_at' | 'is_a_build_of__service'
|
|
45
|
-
>;
|
|
46
|
-
|
|
47
43
|
export interface TaggedImage {
|
|
48
44
|
localImage: import('dockerode').Image;
|
|
49
|
-
serviceImage:
|
|
45
|
+
serviceImage: import('@balena/compose/dist/release/models').ImageModel;
|
|
50
46
|
serviceName: string;
|
|
51
47
|
logs: string;
|
|
52
|
-
props:
|
|
48
|
+
props: BuiltImage.props;
|
|
53
49
|
registry: string;
|
|
54
50
|
repo: string;
|
|
55
51
|
}
|
|
@@ -86,32 +82,23 @@ export interface ComposeProject {
|
|
|
86
82
|
export interface Release {
|
|
87
83
|
client: import('@balena/compose').release.Request['client'];
|
|
88
84
|
release: Pick<
|
|
89
|
-
|
|
85
|
+
ReleaseModel,
|
|
90
86
|
| 'id'
|
|
91
87
|
| 'status'
|
|
92
88
|
| 'commit'
|
|
93
89
|
| 'composition'
|
|
94
90
|
| 'source'
|
|
95
91
|
| 'is_final'
|
|
92
|
+
| 'contract'
|
|
96
93
|
| 'semver'
|
|
97
94
|
| 'start_timestamp'
|
|
98
95
|
| 'end_timestamp'
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
96
|
+
>;
|
|
97
|
+
serviceImages: Dictionary<
|
|
98
|
+
Omit<ImageModel, 'created_at' | 'is_a_build_of__service'>
|
|
99
|
+
>;
|
|
103
100
|
}
|
|
104
101
|
|
|
105
|
-
// TODO: The balena contract model for release.contract is `{ [key: string]: JSON } | JSON[] | null`
|
|
106
|
-
// which appears to be incorrect, as a contract is represented as `{ [key: string]: any }`
|
|
107
|
-
// (more specifically, `{ type: string, [key: string]: any }`) when querying a release for its contract.
|
|
108
|
-
// @balena/contrato also defines a ContractObject as the type below, see:
|
|
109
|
-
// https://github.com/balena-io/contrato/blob/543e891249431aa98474e17fecc66617ab9ca8f3/lib/types.ts#L15-L17
|
|
110
|
-
export type Contract = {
|
|
111
|
-
type: string;
|
|
112
|
-
[key: string]: any;
|
|
113
|
-
};
|
|
114
|
-
|
|
115
102
|
interface TarDirectoryOptions {
|
|
116
103
|
composition?: Composition;
|
|
117
104
|
convertEol?: boolean;
|
package/src/utils/compose.ts
CHANGED
|
@@ -26,7 +26,6 @@ import type {
|
|
|
26
26
|
ComposeOpts,
|
|
27
27
|
ComposeProject,
|
|
28
28
|
Release,
|
|
29
|
-
Contract,
|
|
30
29
|
TaggedImage,
|
|
31
30
|
} from './compose-types';
|
|
32
31
|
import Logger = require('./logger');
|
|
@@ -129,7 +128,7 @@ export const createRelease = async function (
|
|
|
129
128
|
composition: Composition,
|
|
130
129
|
draft: boolean,
|
|
131
130
|
semver: string | undefined,
|
|
132
|
-
contract:
|
|
131
|
+
contract: import('@balena/compose/dist/release/models').ReleaseModel['contract'],
|
|
133
132
|
imgDescriptors: ImageDescriptor[],
|
|
134
133
|
): Promise<Release> {
|
|
135
134
|
const crypto = require('crypto') as typeof import('crypto');
|
|
@@ -166,18 +165,16 @@ export const createRelease = async function (
|
|
|
166
165
|
commit: crypto.pseudoRandomBytes(16).toString('hex').toLowerCase(),
|
|
167
166
|
semver,
|
|
168
167
|
is_final: !draft,
|
|
169
|
-
contract
|
|
168
|
+
contract,
|
|
170
169
|
imgDescriptors,
|
|
171
170
|
});
|
|
172
171
|
|
|
173
172
|
for (const serviceImage of Object.values(serviceImages)) {
|
|
174
173
|
if ('created_at' in serviceImage) {
|
|
175
|
-
|
|
176
|
-
serviceImage.created_at = undefined as any;
|
|
174
|
+
delete serviceImage.created_at;
|
|
177
175
|
}
|
|
178
176
|
if ('is_a_build_of__service' in serviceImage) {
|
|
179
|
-
|
|
180
|
-
serviceImage.is_a_build_of__service = undefined as any;
|
|
177
|
+
delete serviceImage.is_a_build_of__service;
|
|
181
178
|
}
|
|
182
179
|
}
|
|
183
180
|
|
|
@@ -194,7 +191,7 @@ export const createRelease = async function (
|
|
|
194
191
|
'semver',
|
|
195
192
|
'start_timestamp',
|
|
196
193
|
'end_timestamp',
|
|
197
|
-
])
|
|
194
|
+
]),
|
|
198
195
|
serviceImages,
|
|
199
196
|
};
|
|
200
197
|
};
|
package/src/utils/compose_ts.ts
CHANGED
|
@@ -39,8 +39,6 @@ import type {
|
|
|
39
39
|
ComposeProject,
|
|
40
40
|
TaggedImage,
|
|
41
41
|
TarDirectoryOptions,
|
|
42
|
-
Release,
|
|
43
|
-
Contract,
|
|
44
42
|
} from './compose-types';
|
|
45
43
|
import type { DeviceInfo } from './device/api';
|
|
46
44
|
import { getBalenaSdk, getCliUx, stripIndent } from './lazy';
|
|
@@ -1276,7 +1274,7 @@ async function pushAndUpdateServiceImages(
|
|
|
1276
1274
|
token: string,
|
|
1277
1275
|
images: TaggedImage[],
|
|
1278
1276
|
afterEach: (
|
|
1279
|
-
serviceImage:
|
|
1277
|
+
serviceImage: import('@balena/compose/dist/release/models').ImageModel,
|
|
1280
1278
|
props: object,
|
|
1281
1279
|
) => Promise<void>,
|
|
1282
1280
|
) {
|
|
@@ -1332,15 +1330,15 @@ async function pushAndUpdateServiceImages(
|
|
|
1332
1330
|
serviceImage.image_size = `${imgInfo.Size}`;
|
|
1333
1331
|
serviceImage.content_hash = imgDigest;
|
|
1334
1332
|
serviceImage.build_log = logs;
|
|
1335
|
-
serviceImage.dockerfile = props.dockerfile
|
|
1336
|
-
serviceImage.project_type = props.projectType
|
|
1333
|
+
serviceImage.dockerfile = props.dockerfile;
|
|
1334
|
+
serviceImage.project_type = props.projectType;
|
|
1337
1335
|
if (props.startTime) {
|
|
1338
|
-
serviceImage.start_timestamp = props.startTime
|
|
1336
|
+
serviceImage.start_timestamp = props.startTime;
|
|
1339
1337
|
}
|
|
1340
1338
|
if (props.endTime) {
|
|
1341
|
-
serviceImage.end_timestamp = props.endTime
|
|
1339
|
+
serviceImage.end_timestamp = props.endTime;
|
|
1342
1340
|
}
|
|
1343
|
-
serviceImage.push_timestamp = new Date()
|
|
1341
|
+
serviceImage.push_timestamp = new Date();
|
|
1344
1342
|
serviceImage.status = 'success';
|
|
1345
1343
|
} catch (error) {
|
|
1346
1344
|
serviceImage.error_message = '' + error;
|
|
@@ -1381,7 +1379,7 @@ async function pushServiceImages(
|
|
|
1381
1379
|
`Saving image ${serviceImage.is_stored_at__image_location}`,
|
|
1382
1380
|
);
|
|
1383
1381
|
if (skipLogUpload) {
|
|
1384
|
-
serviceImage.build_log
|
|
1382
|
+
delete serviceImage.build_log;
|
|
1385
1383
|
}
|
|
1386
1384
|
|
|
1387
1385
|
// These are the only update-able image fields in bC atm, and passing
|
|
@@ -1427,7 +1425,7 @@ export async function deployProject(
|
|
|
1427
1425
|
projectPath: string,
|
|
1428
1426
|
isDraft: boolean,
|
|
1429
1427
|
imgDescriptors: ImageDescriptor[],
|
|
1430
|
-
): Promise<
|
|
1428
|
+
): Promise<import('@balena/compose/dist/release/models').ReleaseModel> {
|
|
1431
1429
|
const releaseMod = await import('@balena/compose/dist/release');
|
|
1432
1430
|
const { createRelease, tagServiceImages } = await import('./compose');
|
|
1433
1431
|
const tty = (await import('./tty'))(process.stdout);
|
|
@@ -1498,7 +1496,7 @@ export async function deployProject(
|
|
|
1498
1496
|
}
|
|
1499
1497
|
} finally {
|
|
1500
1498
|
await runSpinner(tty, spinner, `${prefix}Saving release...`, async () => {
|
|
1501
|
-
release.end_timestamp = new Date()
|
|
1499
|
+
release.end_timestamp = new Date();
|
|
1502
1500
|
if (release.id != null) {
|
|
1503
1501
|
await releaseMod.updateRelease(pineClient, release.id, {
|
|
1504
1502
|
status: release.status,
|
|
@@ -1554,7 +1552,9 @@ export function createRunLoop(tick: (...args: any[]) => void) {
|
|
|
1554
1552
|
|
|
1555
1553
|
async function getContractContent(
|
|
1556
1554
|
filePath: string,
|
|
1557
|
-
): Promise<
|
|
1555
|
+
): Promise<
|
|
1556
|
+
import('@balena/compose/dist/release/models').ReleaseModel['contract']
|
|
1557
|
+
> {
|
|
1558
1558
|
let fileContentAsString;
|
|
1559
1559
|
try {
|
|
1560
1560
|
fileContentAsString = await fs.readFile(filePath, 'utf8');
|
|
@@ -1584,7 +1584,7 @@ async function getContractContent(
|
|
|
1584
1584
|
return asJson;
|
|
1585
1585
|
}
|
|
1586
1586
|
|
|
1587
|
-
function isContract(obj: any): obj is
|
|
1587
|
+
function isContract(obj: any): obj is Dictionary<any> {
|
|
1588
1588
|
return obj?.type && allowedContractTypes.includes(obj.type);
|
|
1589
1589
|
}
|
|
1590
1590
|
|
package/src/utils/device/api.ts
CHANGED
|
@@ -74,7 +74,9 @@ export class DeviceAPI {
|
|
|
74
74
|
addr: string,
|
|
75
75
|
port = 48484,
|
|
76
76
|
) {
|
|
77
|
-
|
|
77
|
+
// Allow override for testing with mock servers
|
|
78
|
+
this.deviceAddress =
|
|
79
|
+
process.env.BALENARC_SUPERVISOR_ADDRESS ?? `http://${addr}:${port}/`;
|
|
78
80
|
}
|
|
79
81
|
|
|
80
82
|
// Either return nothing, or throw an error with the info
|