diff --git a/completion/_balena b/completion/_balena index eb33194366..0c62cc20c4 100644 --- a/completion/_balena +++ b/completion/_balena @@ -22,7 +22,7 @@ _balena() { key_cmds=( add rm ) local_cmds=( configure flash ) os_cmds=( build-config configure download initialize versions ) - release_cmds=( finalize invalidate validate ) + release_cmds=( export finalize import invalidate validate ) tag_cmds=( rm set ) diff --git a/completion/balena-completion.bash b/completion/balena-completion.bash index 3c1101a1eb..e6d548a772 100644 --- a/completion/balena-completion.bash +++ b/completion/balena-completion.bash @@ -21,7 +21,7 @@ _balena_complete() key_cmds="add rm" local_cmds="configure flash" os_cmds="build-config configure download initialize versions" - release_cmds="finalize invalidate validate" + release_cmds="export finalize import invalidate validate" tag_cmds="rm set" diff --git a/docs/balena-cli.md b/docs/balena-cli.md index 28a46c793b..eecd6068ab 100644 --- a/docs/balena-cli.md +++ b/docs/balena-cli.md @@ -282,7 +282,9 @@ are encouraged to regularly update the balena CLI to the latest version. - Releases + - [release export <commitorid>](#release-export-commitorid) - [release finalize <commitorid>](#release-finalize-commitorid) + - [release import <file> <fleet>](#release-import-file-fleet) - [release <commitorid>](#release-commitorid) - [release invalidate <commitorid>](#release-invalidate-commitorid) - [release validate <commitorid>](#release-validate-commitorid) @@ -3345,6 +3347,37 @@ The notes for this release # Releases +## release export <commitOrId> + +Exporting a release to a file allows you to import an exact +copy of the original release into another app. + +If the SemVer of a release is provided using the --version option, +the first argument is assumed to be the fleet's slug. + +Only successful releases can be exported. + +Examples: + + $ balena release export a777f7345fe3d655c1c981aa642e5555 -o ../path/to/release.tar + $ balena release export myOrg/myFleet --version 1.2.3 -o ../path/to/release.tar + +### Arguments + +#### COMMITORID + +commit, ID, or version of the release to export + +### Options + +#### -o, --output OUTPUT + +output path + +#### --version VERSION + +version of the release to export from the specified fleet + ## release finalize <commitOrId> Finalize a release. Releases can be "draft" or "final", and this command @@ -3371,6 +3404,40 @@ the commit or ID of the release to finalize ### Options +## release import <file> <fleet> + +is automatically omitted when importing a release. The backend will auto-increment +the revision field of the imported release if a release exists with the same semver. +A release will not be imported if a successful release with the same commit already +exists. + +To export a release to a file, use 'balena release export'. + +Use the --override-version option to specify the version +of the imported release, overriding the one saved in the file. + +Examples: + + $ balena release import ../path/to/release.tar myFleet + $ balena release import ../path/to/release.tar myOrg/myFleet + $ balena release import ../path/to/release.tar myOrg/myFleet --override-version 1.2.3 + +### Arguments + +#### BUNDLE + +path to a file, e.g. "./release.tar" + +#### FLEET + +fleet that the release will be imported to, e.g. "myOrg/myFleet" + +### Options + +#### --override-version OVERRIDE-VERSION + +Imports this release with the specified version overriding the version in the file. + ## release <commitOrId> The --json option is recommended when scripting the output of this command, diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index bf049ea8a4..f2b1c742b6 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -14,6 +14,7 @@ "@balena/dockerignore": "^1.0.2", "@balena/env-parsing": "^1.1.8", "@balena/es-version": "^1.0.1", + "@balena/release-bundle": "^0.5.2", "@oclif/core": "^4.0.8", "@resin.io/valid-email": "^0.1.0", "@sentry/node": "^6.16.1", @@ -1656,6 +1657,40 @@ "web-streams-polyfill": "^3.1.0" } }, + "node_modules/@balena/release-bundle": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@balena/release-bundle/-/release-bundle-0.5.2.tgz", + "integrity": "sha512-q2ji3Pky9RGeztApTBaoZEF2R8FSiHsFutIvvlmA0ggJKgATxNNavZd4ueYtlK/Nl53g9vUrKmiwzCVgw9rDRw==", + "dependencies": { + "@balena/resource-bundle": "^0.8.3", + "balena-semver": "^2.3.5" + }, + "peerDependencies": { + "balena-sdk": "^19.0.0" + } + }, + "node_modules/@balena/resource-bundle": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@balena/resource-bundle/-/resource-bundle-0.8.3.tgz", + "integrity": "sha512-WKkeZkZIcrey1l08G1gS60EQCYtTZsOwwmnRhvmjnmWmUAcqa3Z9WqYDqM7ePbFO/pdo9Cd0JK0Xr+pgj3A8ng==", + "dependencies": { + "auth-header": "^1.0.0", + "tar-stream": "^3.1.7" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@balena/resource-bundle/node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/@balena/udif": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@balena/udif/-/udif-1.1.2.tgz", @@ -2079,9 +2114,9 @@ } }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "engines": { "node": ">=12" }, @@ -3894,9 +3929,9 @@ } }, "node_modules/@types/node": { - "version": "20.16.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.4.tgz", - "integrity": "sha512-ioyQ1zK9aGEomJ45zz8S8IdzElyxhvP1RVWnPrXDf6wFaUb+kk1tEcVVJkF7RPGM0VWI7cp5U57oCPIn5iN1qg==", + "version": "20.16.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.5.tgz", + "integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==", "dependencies": { "undici-types": "~6.19.2" } @@ -5327,6 +5362,11 @@ "node": ">= 4.0.0" } }, + "node_modules/auth-header": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/auth-header/-/auth-header-1.0.0.tgz", + "integrity": "sha512-CPPazq09YVDUNNVWo4oSPTQmtwIzHusZhQmahCKvIsk0/xH6U3QsMAv3sM+7+Q0B1K2KJ/Q38OND317uXs4NHA==" + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -5681,9 +5721,9 @@ } }, "node_modules/balena-sdk/node_modules/@types/node": { - "version": "18.19.49", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.49.tgz", - "integrity": "sha512-ALCeIR6n0nQ7j0FUF1ycOhrp6+XutJWqEu/vtdEqXFUQwkBfgUA5cEg3ZNmjWGF/ZYA/FcF9QMkL55Ar0O6UrA==", + "version": "18.19.50", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.50.tgz", + "integrity": "sha512-xonK+NRrMBRtkL1hVCc3G+uXtjh1Al4opBLjqVmipe5ZAaBYWW6cNAiBVZ1BvmkBhep698rP3UM3aRAdSALuhg==", "dependencies": { "undici-types": "~5.26.4" } @@ -7128,11 +7168,11 @@ } }, "node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -12650,12 +12690,6 @@ "node": ">=10" } }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "node_modules/mocha/node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -12876,9 +12910,9 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/multicast-dns": { "version": "7.2.5", @@ -14776,9 +14810,9 @@ "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" }, "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.1.tgz", + "integrity": "sha512-2ynnAmUu45oUSq51AQbeugLkMSKaz8FqVpZ6ykTqzOVkzXe8u/ezkGsYrFJqKZx+D9cVxoDrSbR7CeAwxFa5cQ==", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -15800,11 +15834,6 @@ "node": ">=4" } }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, "node_modules/sentence-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", diff --git a/package.json b/package.json index 9769a0d0b1..50708cbb9b 100644 --- a/package.json +++ b/package.json @@ -196,6 +196,7 @@ "@balena/dockerignore": "^1.0.2", "@balena/env-parsing": "^1.1.8", "@balena/es-version": "^1.0.1", + "@balena/release-bundle": "^0.5.2", "@oclif/core": "^4.0.8", "@resin.io/valid-email": "^0.1.0", "@sentry/node": "^6.16.1", diff --git a/src/commands/release/export.ts b/src/commands/release/export.ts new file mode 100644 index 0000000000..bf054f779a --- /dev/null +++ b/src/commands/release/export.ts @@ -0,0 +1,116 @@ +/** + * @license + * Copyright 2016-2024 Balena Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { commitOrIdArg } from '.'; +import { Flags } from '@oclif/core'; +import Command from '../../command'; +import * as cf from '../../utils/common-flags'; +import { getBalenaSdk, stripIndent } from '../../utils/lazy'; +import { create } from '@balena/release-bundle'; +import * as fs from 'fs/promises'; +import * as semver from 'balena-semver'; +import { ExpectedError } from '../../errors'; + +export default class ReleaseExportCmd extends Command { + public static description = stripIndent` + Exports a release into a file. + + Exporting a release to a file allows you to import an exact + copy of the original release into another app. + + If the SemVer of a release is provided using the --version option, + the first argument is assumed to be the fleet's slug. + + Only successful releases can be exported. +`; + public static examples = [ + '$ balena release export a777f7345fe3d655c1c981aa642e5555 -o ../path/to/release.tar', + '$ balena release export myOrg/myFleet --version 1.2.3 -o ../path/to/release.tar', + ]; + + public static usage = 'release export '; + + public static flags = { + output: Flags.string({ + description: 'output path', + char: 'o', + required: true, + }), + version: Flags.string({ + description: 'version of the release to export from the specified fleet', + }), + help: cf.help, + }; + + public static args = { + commitOrId: commitOrIdArg({ + description: 'commit, ID, or version of the release to export', + required: true, + }), + }; + + public static authenticated = true; + + public async run() { + const { args: params, flags: options } = await this.parse(ReleaseExportCmd); + + const balena = getBalenaSdk(); + + let release: balenaSdk.Release; + if (typeof options.version === 'string') { + const application = params.commitOrId; + const parsedVersion = semver.parse(options.version); + if (parsedVersion == null) { + throw new ExpectedError( + `Release of ${application} with version ${options.version} could not be exported; version must be valid SemVer.`, + ); + } else { + const rawVersion = + parsedVersion.build.length === 0 + ? parsedVersion.version + : `${parsedVersion.version}+${parsedVersion.build[0]}`; + release = await balena.models.release.get( + { application, rawVersion }, + { $select: ['id'] }, + ); + } + } else { + release = await balena.models.release.get(params.commitOrId, { + $select: ['id'], + }); + } + + try { + const releaseBundle = await create({ + sdk: balena, + releaseId: release.id, + }); + await fs.writeFile(options.output, releaseBundle); + const versionInfo = + typeof options.version === 'string' + ? ` version ${options.version}` + : ''; + console.log( + `Release ${params.commitOrId}${versionInfo} has been exported to ${options.output}.`, + ); + } catch (error) { + throw new ExpectedError( + `Release ${params.commitOrId} could not be exported: ${error.message}`, + ); + } + } +} diff --git a/src/commands/release/import.ts b/src/commands/release/import.ts new file mode 100644 index 0000000000..51d76b3bce --- /dev/null +++ b/src/commands/release/import.ts @@ -0,0 +1,103 @@ +/** + * @license + * Copyright 2016-2024 Balena Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Flags, Args } from '@oclif/core'; +import Command from '../../command'; +import * as cf from '../../utils/common-flags'; +import { getBalenaSdk, stripIndent } from '../../utils/lazy'; +import { apply } from '@balena/release-bundle'; +import { createReadStream } from 'fs'; +import { ExpectedError } from '../../errors'; + +export default class ReleaseImportCmd extends Command { + public static description = stripIndent` + Imports a release from a file to an app or fleet. The revision field of the release + is automatically omitted when importing a release. The backend will auto-increment + the revision field of the imported release if a release exists with the same semver. + A release will not be imported if a successful release with the same commit already + exists. + + To export a release to a file, use 'balena release export'. + + Use the --override-version option to specify the version + of the imported release, overriding the one saved in the file. +`; + public static examples = [ + '$ balena release import ../path/to/release.tar myFleet', + '$ balena release import ../path/to/release.tar myOrg/myFleet', + '$ balena release import ../path/to/release.tar myOrg/myFleet --override-version 1.2.3', + ]; + + public static usage = 'release import '; + + public static flags = { + 'override-version': Flags.string({ + description: + 'Imports this release with the specified version overriding the version in the file.', + required: false, + }), + help: cf.help, + }; + + public static args = { + bundle: Args.string({ + required: true, + description: 'path to a file, e.g. "./release.tar"', + }), + fleet: Args.string({ + required: true, + description: + 'fleet that the release will be imported to, e.g. "myOrg/myFleet"', + }), + }; + + public static authenticated = true; + + public async run() { + const { args: params, flags: options } = await this.parse(ReleaseImportCmd); + + const balena = getBalenaSdk(); + + const bundle = createReadStream(params.bundle).on('error', () => { + throw new ExpectedError( + `Release bundle ${params.bundle} does not exist or is not accessible.`, + ); + }); + + try { + const application = await balena.models.application.get(params.fleet, { + $select: ['id'], + }); + if (application == null) { + throw new ExpectedError(`Fleet ${params.fleet} not found.`); + } + await apply({ + sdk: balena, + application: application.id, + stream: bundle, + version: options['override-version'], + }); + console.log( + `Release bundle ${params.bundle} has been imported to ${params.fleet}.`, + ); + } catch (error) { + throw new ExpectedError( + `Could not import release bundle ${params.bundle} to fleet ${params.fleet}: ${error.message}`, + ); + } + } +} diff --git a/tests/commands/release/export.spec.ts b/tests/commands/release/export.spec.ts new file mode 100644 index 0000000000..50307b32ee --- /dev/null +++ b/tests/commands/release/export.spec.ts @@ -0,0 +1,76 @@ +import * as stream from 'node:stream'; +import { cleanOutput, runCommand } from '../../helpers'; +import { BalenaAPIMock } from '../../nock/balena-api-mock'; +import { expect } from 'chai'; +import * as mock from 'mock-require'; +import * as sinon from 'sinon'; + +// "itSS" means "it() Skip Standalone" +const itSS = process.env.BALENA_CLI_TEST_TYPE === 'standalone' ? it.skip : it; + +describe('export fleet content to a file', function () { + let api: BalenaAPIMock; + const releaseBundleCreateStub = sinon.stub(); + + this.beforeEach(() => { + api = new BalenaAPIMock(); + mock('@balena/release-bundle', { + create: releaseBundleCreateStub, + }); + }); + + this.afterEach(() => { + // Check all expected api calls have been made and clean up. + api.done(); + mock.stop('@balena/release-bundle'); + }); + + itSS('should export a release to a file', async () => { + api.expectGetWhoAmI(); + api.expectGetRelease(); + releaseBundleCreateStub.resolves(stream.Readable.from('something')); + + const { out, err } = await runCommand( + 'release export badc0ffe -o /tmp/release.tar.gz', + ); + + const lines = cleanOutput(out); + expect(lines[0]).to.contain( + 'Release badc0ffe has been exported to /tmp/release.tar.gz.', + ); + expect(err).to.be.empty; + }); + + itSS('should fail if the create throws an error', async () => { + api.expectGetWhoAmI(); + api.expectGetRelease(); + releaseBundleCreateStub.rejects( + new Error('Something went wrong creating the bundle'), + ); + + const { err } = await runCommand( + 'release export badc0ffe -o /tmp/release.tar.gz', + ); + + expect(cleanOutput(err, true)).to.include( + 'Release badc0ffe could not be exported: Something went wrong creating the bundle', + ); + }); + + itSS('should parse with application slug and version', async () => { + api.expectGetWhoAmI(); + api.expectGetRelease(); + api.expectGetApplication(); + releaseBundleCreateStub.resolves(stream.Readable.from('something')); + + const { out, err } = await runCommand( + 'release export org/superApp -o /tmp/release.tar.gz --version 1.2.3+rev1', + ); + + const lines = cleanOutput(out); + expect(lines[0]).to.contain( + 'Release org/superApp version 1.2.3+rev1 has been exported to /tmp/release.tar.gz.', + ); + expect(err).to.be.empty; + }); +}); diff --git a/tests/test-data/pkg/expected-warnings-darwin-arm64.txt b/tests/test-data/pkg/expected-warnings-darwin-arm64.txt index 960b23f8bc..9359a8714a 100644 --- a/tests/test-data/pkg/expected-warnings-darwin-arm64.txt +++ b/tests/test-data/pkg/expected-warnings-darwin-arm64.txt @@ -205,6 +205,12 @@ > Warning Entry 'main' not found in %1 %1: node_modules/@oclif/core/package.json %2: build/commands/push/index.js +> Warning Entry 'main' not found in %1 + %1: node_modules/@oclif/core/package.json + %2: build/commands/release/export.js +> Warning Entry 'main' not found in %1 + %1: node_modules/@oclif/core/package.json + %2: build/commands/release/import.js > Warning Entry 'main' not found in %1 %1: node_modules/@oclif/core/package.json %2: build/commands/release/index.js diff --git a/tests/test-data/pkg/expected-warnings-darwin-x64.txt b/tests/test-data/pkg/expected-warnings-darwin-x64.txt index bab73f1c67..9e1d254f21 100644 --- a/tests/test-data/pkg/expected-warnings-darwin-x64.txt +++ b/tests/test-data/pkg/expected-warnings-darwin-x64.txt @@ -205,6 +205,12 @@ > Warning Entry 'main' not found in %1 %1: node_modules/@oclif/core/package.json %2: build/commands/push/index.js +> Warning Entry 'main' not found in %1 + %1: node_modules/@oclif/core/package.json + %2: build/commands/release/export.js +> Warning Entry 'main' not found in %1 + %1: node_modules/@oclif/core/package.json + %2: build/commands/release/import.js > Warning Entry 'main' not found in %1 %1: node_modules/@oclif/core/package.json %2: build/commands/release/index.js diff --git a/tests/test-data/pkg/expected-warnings-linux-arm64.txt b/tests/test-data/pkg/expected-warnings-linux-arm64.txt index 67d1f96855..c19ec23aa6 100644 --- a/tests/test-data/pkg/expected-warnings-linux-arm64.txt +++ b/tests/test-data/pkg/expected-warnings-linux-arm64.txt @@ -205,6 +205,12 @@ > Warning Entry 'main' not found in %1 %1: node_modules/@oclif/core/package.json %2: build/commands/push/index.js +> Warning Entry 'main' not found in %1 + %1: node_modules/@oclif/core/package.json + %2: build/commands/release/export.js +> Warning Entry 'main' not found in %1 + %1: node_modules/@oclif/core/package.json + %2: build/commands/release/import.js > Warning Entry 'main' not found in %1 %1: node_modules/@oclif/core/package.json %2: build/commands/release/index.js diff --git a/tests/test-data/pkg/expected-warnings-linux-x64.txt b/tests/test-data/pkg/expected-warnings-linux-x64.txt index fe0b5c7626..49b9868471 100644 --- a/tests/test-data/pkg/expected-warnings-linux-x64.txt +++ b/tests/test-data/pkg/expected-warnings-linux-x64.txt @@ -205,6 +205,12 @@ > Warning Entry 'main' not found in %1 %1: node_modules/@oclif/core/package.json %2: build/commands/push/index.js +> Warning Entry 'main' not found in %1 + %1: node_modules/@oclif/core/package.json + %2: build/commands/release/export.js +> Warning Entry 'main' not found in %1 + %1: node_modules/@oclif/core/package.json + %2: build/commands/release/import.js > Warning Entry 'main' not found in %1 %1: node_modules/@oclif/core/package.json %2: build/commands/release/index.js diff --git a/tests/test-data/pkg/expected-warnings-win32-x64.txt b/tests/test-data/pkg/expected-warnings-win32-x64.txt index 6804a05903..9da837a1b4 100644 --- a/tests/test-data/pkg/expected-warnings-win32-x64.txt +++ b/tests/test-data/pkg/expected-warnings-win32-x64.txt @@ -205,6 +205,12 @@ > Warning Entry 'main' not found in %1 %1: node_modules\@oclif\core\package.json %2: build\commands\push\index.js +> Warning Entry 'main' not found in %1 + %1: node_modules\@oclif\core\package.json + %2: build\commands\release\export.js +> Warning Entry 'main' not found in %1 + %1: node_modules\@oclif\core\package.json + %2: build\commands\release\import.js > Warning Entry 'main' not found in %1 %1: node_modules\@oclif\core\package.json %2: build\commands\release\index.js