From a52a623fdfb4126edd87104b5f68e0469a2bda27 Mon Sep 17 00:00:00 2001 From: Thodoris Greasidis Date: Tue, 4 Aug 2020 16:17:51 +0300 Subject: [PATCH] Update balena-release to v3 Change-type: patch Signed-off-by: Thodoris Greasidis --- lib/utils/compose-types.d.ts | 2 +- lib/utils/compose.js | 54 +++++---- lib/utils/compose_ts.ts | 2 +- npm-shrinkwrap.json | 109 +++++++++++++----- package.json | 3 +- tests/balena-api-mock.ts | 60 ++++++++-- tests/commands/deploy.spec.ts | 5 +- .../application-GET-v6-expanded-app-type.json | 35 ++++++ ...{image-POST-v5.json => image-POST-v6.json} | 0 ... => image-is-part-of-release-POST-v6.json} | 0 ...-POST-v5.json => image-label-POST-v6.json} | 0 ...ease-POST-v5.json => release-POST-v6.json} | 0 12 files changed, 197 insertions(+), 73 deletions(-) create mode 100644 tests/test-data/api-response/application-GET-v6-expanded-app-type.json rename tests/test-data/api-response/{image-POST-v5.json => image-POST-v6.json} (100%) rename tests/test-data/api-response/{image-is-part-of-release-POST-v5.json => image-is-part-of-release-POST-v6.json} (100%) rename tests/test-data/api-response/{image-label-POST-v5.json => image-label-POST-v6.json} (100%) rename tests/test-data/api-response/{release-POST-v5.json => release-POST-v6.json} (100%) diff --git a/lib/utils/compose-types.d.ts b/lib/utils/compose-types.d.ts index 8365e73b..3d8b230a 100644 --- a/lib/utils/compose-types.d.ts +++ b/lib/utils/compose-types.d.ts @@ -78,7 +78,7 @@ export interface ComposeProject { } export interface Release { - client: import('pinejs-client').ApiClient; + client: ReturnType; release: Partial; serviceImages: Partial; } diff --git a/lib/utils/compose.js b/lib/utils/compose.js index 3ef02386..1d9af259 100644 --- a/lib/utils/compose.js +++ b/lib/utils/compose.js @@ -540,7 +540,7 @@ export function buildProject( * @param {import('resin-compose-parse').Composition} composition * @returns {Promise} */ -export const createRelease = function ( +export const createRelease = async function ( apiEndpoint, auth, userId, @@ -553,33 +553,31 @@ export const createRelease = function ( const client = releaseMod.createClient({ apiEndpoint, auth }); - return releaseMod - .create({ - client, - user: userId, - application: appId, - composition, - source: 'local', - commit: crypto.pseudoRandomBytes(16).toString('hex').toLowerCase(), - }) - .then(function ({ release, serviceImages }) { - return { - client, - release: _.omit(release, [ - 'created_at', - 'belongs_to__application', - 'is_created_by__user', - '__metadata', - ]), - serviceImages: _.mapValues(serviceImages, (serviceImage) => - _.omit(serviceImage, [ - 'created_at', - 'is_a_build_of__service', - '__metadata', - ]), - ), - }; - }); + const { release, serviceImages } = await releaseMod.create({ + client, + user: userId, + application: appId, + composition, + source: 'local', + commit: crypto.pseudoRandomBytes(16).toString('hex').toLowerCase(), + }); + + return { + client, + release: _.omit(release, [ + 'created_at', + 'belongs_to__application', + 'is_created_by__user', + '__metadata', + ]), + serviceImages: _.mapValues(serviceImages, (serviceImage) => + _.omit(serviceImage, [ + 'created_at', + 'is_a_build_of__service', + '__metadata', + ]), + ), + }; }; /** diff --git a/lib/utils/compose_ts.ts b/lib/utils/compose_ts.ts index dd3f9f3e..daabea98 100644 --- a/lib/utils/compose_ts.ts +++ b/lib/utils/compose_ts.ts @@ -772,7 +772,7 @@ async function getTokenForPreviousRepos( async function pushServiceImages( docker: import('docker-toolbelt'), logger: Logger, - pineClient: import('pinejs-client'), + pineClient: ReturnType, taggedImages: TaggedImage[], token: string, skipLogUpload: boolean, diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 9fa7b4e4..5acce4d2 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1296,6 +1296,11 @@ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.150.tgz", "integrity": "sha512-kMNLM5JBcasgYscD9x/Gvr6lTAv2NVgsKtet/hm93qMyf/D1pt+7jeEZklKJKxMVmXjxbRVQQGfqDSfipYCO6w==" }, + "@types/lru-cache": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/lru-cache/-/lru-cache-5.1.0.tgz", + "integrity": "sha512-RaE0B+14ToE4l6UqdarKPnXwVDuigfFv+5j9Dze/Nqr23yyuqdNvzcZi3xB+3Agvi5R4EOgAksfv3lXX4vBt9w==" + }, "@types/memoizee": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/@types/memoizee/-/memoizee-0.4.4.tgz", @@ -2597,25 +2602,23 @@ } }, "balena-release": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/balena-release/-/balena-release-2.1.0.tgz", - "integrity": "sha512-HlVaQBNL35W9NF1MeSfkAPClo/MNvu6WBX487dnfo0V9BpyT5qgRoFBFmnqyVXE+N1DrQwkZ3sHoGgOXMl+7Zg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/balena-release/-/balena-release-3.0.0.tgz", + "integrity": "sha512-LYgPGBUnqJY+ajhTWE2BizyaRNxitxPSIZp4xGWDHbpVHmwKaV4p3d6nw1Hf9kEHP4dLELJvnNXq2EKV2IpTFA==", "requires": { "@types/bluebird": "^3.5.18", - "@types/lodash": "^4.14.87", "@types/node": "^8.0.55", "@types/request": "^2.0.8", "bluebird": "^3.5.1", - "lodash": "^4.17.4", - "pinejs-client": "^4.2.3", + "pinejs-client-request": "^7.1.0", "resin-compose-parse": "^2.0.0", "typed-error": "^3.0.0" }, "dependencies": { "@types/node": { - "version": "8.10.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.60.tgz", - "integrity": "sha512-YjPbypHFuiOV0bTgeF07HpEEqhmHaZqYNSdCKeBJa+yFoQ/7BC+FpJcwmi34xUIIRVFktnUyP1dPU8U0612GOg==" + "version": "8.10.62", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.62.tgz", + "integrity": "sha512-76fupxOYVxk36kb7O/6KtrAPZ9jnSK3+qisAX4tQMEuGNdlvl7ycwatlHqjoE6jHfVtXFM3pCrCixZOidc5cuw==" } } }, @@ -11366,25 +11369,6 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" }, - "pinejs-client": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/pinejs-client/-/pinejs-client-4.3.2.tgz", - "integrity": "sha512-Qu3lDbZOdK+olEr7sUtmBupanXLGm93zhqlQe2ny0MPOEkQyM6gzta5EOXR1gMXBc7H9CeITDXGBXuGb14w46A==", - "requires": { - "bluebird": "^3.0.6", - "bluebird-lru-cache": "^1.0.0", - "lodash": "^4.0.0", - "request": "^2.82.0", - "typed-error": "^0.1.0" - }, - "dependencies": { - "typed-error": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/typed-error/-/typed-error-0.1.0.tgz", - "integrity": "sha1-xf7ds5ZI66OMSAIapb4lASRgxgQ=" - } - } - }, "pinejs-client-core": { "version": "5.8.0", "resolved": "https://registry.npmjs.org/pinejs-client-core/-/pinejs-client-core-5.8.0.tgz", @@ -11393,6 +11377,75 @@ "@balena/es-version": "^1.0.0" } }, + "pinejs-client-request": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pinejs-client-request/-/pinejs-client-request-7.1.0.tgz", + "integrity": "sha512-BZmBLfiS+C/dfA07GYNJDz3oqj8G7mBC0kL36PRD9kDWjYZHd4RSOSgGOae/S8/NnxeQheQ0xtnqNDcamTlpcA==", + "requires": { + "@types/lodash": "^4.14.158", + "@types/lru-cache": "^5.1.0", + "@types/request": "^2.48.5", + "lodash": "^4.17.19", + "lru-cache": "^6.0.0", + "pinejs-client-core": "^6.1.0", + "request": "^2.88.2", + "typed-error": "^3.2.0" + }, + "dependencies": { + "@types/lodash": { + "version": "4.14.158", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.158.tgz", + "integrity": "sha512-InCEXJNTv/59yO4VSfuvNrZHt7eeNtWQEgnieIA+mIC+MOWM9arOWG2eQ8Vhk6NbOre6/BidiXhkZYeDY9U35w==" + }, + "@types/request": { + "version": "2.48.5", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.5.tgz", + "integrity": "sha512-/LO7xRVnL3DxJ1WkPGDQrp4VTV1reX9RkC85mJ+Qzykj2Bdw+mG15aAfDahc76HtknjzE16SX/Yddn6MxVbmGQ==", + "requires": { + "@types/caseless": "*", + "@types/node": "*", + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + } + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "pinejs-client-core": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pinejs-client-core/-/pinejs-client-core-6.1.0.tgz", + "integrity": "sha512-sp9/LYOOsJuYtlp8d8gR3QqW/oZNN/WEb1UhNJJqRMawNh/LBQRCP3TXCkBwhVmTcH3kYsopj/oCc4Gei+htkQ==", + "requires": { + "@balena/es-version": "^1.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", diff --git a/package.json b/package.json index 009c7235..86e30ec6 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "build/**/*.js", "node_modules/balena-sync/build/capitano/*.js", "node_modules/balena-sync/build/sync/*.js", + "node_modules/pinejs-client-request/node_modules/pinejs-client-core/es2018/index.js", "node_modules/resin-compose-parse/build/schemas/*.json" ], "assets": [ @@ -190,7 +191,7 @@ "balena-errors": "^4.3.0", "balena-image-manager": "^7.0.1", "balena-preload": "^10.2.0", - "balena-release": "^2.1.0", + "balena-release": "^3.0.0", "balena-sdk": "^13.6.0", "balena-semver": "^2.2.0", "balena-settings-client": "^4.0.5", diff --git a/tests/balena-api-mock.ts b/tests/balena-api-mock.ts index 9d47f7e2..46450da8 100644 --- a/tests/balena-api-mock.ts +++ b/tests/balena-api-mock.ts @@ -51,6 +51,26 @@ export class BalenaAPIMock extends NockMock { } } + public expectGetApplicationV6({ + notFound = false, + optional = false, + persist = false, + } = {}) { + const interceptor = this.optGet(/^\/v6\/application($|[(?])/, { + optional, + persist, + }); + if (notFound) { + interceptor.reply(200, { d: [] }); + } else { + interceptor.replyWithFile( + 200, + path.join(apiResponsePath, 'application-GET-v6-expanded-app-type.json'), + jHeader, + ); + } + } + public expectDownloadConfig(opts: ScopeOpts = {}) { this.optPost('/download-config', opts).reply( 200, @@ -110,16 +130,16 @@ export class BalenaAPIMock extends NockMock { optional = false, persist = false, }) { - this.optPatch(/^\/v5\/release($|[(?])/, { optional, persist }).reply( + this.optPatch(/^\/v6\/release($|[(?])/, { optional, persist }).reply( statusCode, this.getInspectedReplyBodyFunction(inspectRequest, replyBody), ); } public expectPostRelease(opts: ScopeOpts = {}) { - this.optPost(/^\/v5\/release($|[(?])/, opts).replyWithFile( + this.optPost(/^\/v6\/release($|[(?])/, opts).replyWithFile( 200, - path.join(apiResponsePath, 'release-POST-v5.json'), + path.join(apiResponsePath, 'release-POST-v6.json'), jHeader, ); } @@ -131,35 +151,35 @@ export class BalenaAPIMock extends NockMock { optional = false, persist = false, }) { - this.optPatch(/^\/v5\/image($|[(?])/, { optional, persist }).reply( + this.optPatch(/^\/v6\/image($|[(?])/, { optional, persist }).reply( statusCode, this.getInspectedReplyBodyFunction(inspectRequest, replyBody), ); } public expectPostImage(opts: ScopeOpts = {}) { - this.optPost(/^\/v5\/image($|[(?])/, opts).replyWithFile( + this.optPost(/^\/v6\/image($|[(?])/, opts).replyWithFile( 201, - path.join(apiResponsePath, 'image-POST-v5.json'), + path.join(apiResponsePath, 'image-POST-v6.json'), jHeader, ); } public expectPostImageLabel(opts: ScopeOpts = {}) { - this.optPost(/^\/v5\/image_label($|[(?])/, opts).replyWithFile( + this.optPost(/^\/v6\/image_label($|[(?])/, opts).replyWithFile( 201, - path.join(apiResponsePath, 'image-label-POST-v5.json'), + path.join(apiResponsePath, 'image-label-POST-v6.json'), jHeader, ); } public expectPostImageIsPartOfRelease(opts: ScopeOpts = {}) { this.optPost( - /^\/v5\/image__is_part_of__release($|[(?])/, + /^\/v6\/image__is_part_of__release($|[(?])/, opts, ).replyWithFile( 200, - path.join(apiResponsePath, 'image-is-part-of-release-POST-v5.json'), + path.join(apiResponsePath, 'image-is-part-of-release-POST-v6.json'), jHeader, ); } @@ -323,9 +343,9 @@ export class BalenaAPIMock extends NockMock { }); } - public expectPostService404(opts: ScopeOpts = {}) { + public expectPostService409(opts: ScopeOpts = {}) { this.optPost(/^\/v\d+\/service$/, opts).reply( - 404, + 409, 'Unique key constraint violated', ); } @@ -346,6 +366,22 @@ export class BalenaAPIMock extends NockMock { }); } + public expectGetUserV6(opts: ScopeOpts = {}) { + this.optGet(/^\/v6\/user/, opts).reply(200, { + d: [ + { + id: 99999, + actor: 1234567, + username: 'gh_user', + created_at: '2018-08-19T13:55:04.485Z', + __metadata: { + uri: '/resin/user(@id)?@id=43699', + }, + }, + ], + }); + } + // User details are cached in the SDK // so often we don't know if we can expect the whoami request public expectGetWhoAmI(opts: ScopeOpts = { optional: true }) { diff --git a/tests/commands/deploy.spec.ts b/tests/commands/deploy.spec.ts index 15773eb4..a7b038d9 100644 --- a/tests/commands/deploy.spec.ts +++ b/tests/commands/deploy.spec.ts @@ -80,11 +80,12 @@ describe('balena deploy', function () { api.expectGetMixpanel({ optional: true }); api.expectGetDeviceTypes(); api.expectGetApplication(); + api.expectGetApplicationV6(); api.expectPostRelease(); api.expectGetRelease(); - api.expectGetUser(); + api.expectGetUserV6(); api.expectGetService({ serviceName: 'main' }); - api.expectPostService404(); + api.expectPostService409(); api.expectGetAuth(); api.expectPostImage(); api.expectPostImageIsPartOfRelease(); diff --git a/tests/test-data/api-response/application-GET-v6-expanded-app-type.json b/tests/test-data/api-response/application-GET-v6-expanded-app-type.json new file mode 100644 index 00000000..67fa9312 --- /dev/null +++ b/tests/test-data/api-response/application-GET-v6-expanded-app-type.json @@ -0,0 +1,35 @@ +{ + "d": [ + { + "application_type": [ + { + "name": "Starter", + "slug": "microservices-starter", + "supports_multicontainer": true, + "is_legacy": false, + "__metadata": {} + } + ], + "id": 1301645, + "user": { + "__deferred": { + "uri": "/resin/user(43699)" + }, + "__id": 43699 + }, + "depends_on__application": null, + "actor": 3423895, + "app_name": "testApp", + "slug": "gh_user/testApp", + "commit": "96eec431d57e6976d3a756df33fde7e2", + "device_type": "raspberrypi3", + "should_track_latest_release": true, + "is_accessible_by_support_until__date": null, + "is_public": false, + "is_host": false, + "__metadata": { + "uri": "/resin/application(@id)?@id=1301645" + } + } + ] +} diff --git a/tests/test-data/api-response/image-POST-v5.json b/tests/test-data/api-response/image-POST-v6.json similarity index 100% rename from tests/test-data/api-response/image-POST-v5.json rename to tests/test-data/api-response/image-POST-v6.json diff --git a/tests/test-data/api-response/image-is-part-of-release-POST-v5.json b/tests/test-data/api-response/image-is-part-of-release-POST-v6.json similarity index 100% rename from tests/test-data/api-response/image-is-part-of-release-POST-v5.json rename to tests/test-data/api-response/image-is-part-of-release-POST-v6.json diff --git a/tests/test-data/api-response/image-label-POST-v5.json b/tests/test-data/api-response/image-label-POST-v6.json similarity index 100% rename from tests/test-data/api-response/image-label-POST-v5.json rename to tests/test-data/api-response/image-label-POST-v6.json diff --git a/tests/test-data/api-response/release-POST-v5.json b/tests/test-data/api-response/release-POST-v6.json similarity index 100% rename from tests/test-data/api-response/release-POST-v5.json rename to tests/test-data/api-response/release-POST-v6.json