mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-04-26 13:59:54 +00:00
Add contract contents at release creation time
Change-type: patch
This commit is contained in:
parent
9937b91606
commit
d0cdc900a2
@ -3373,7 +3373,7 @@ Hint: Empty values may be specified with "" (bash, cmd.exe) or '""' (PowerShell)
|
|||||||
|
|
||||||
Deploy the release as a draft. Draft releases are ignored
|
Deploy the release as a draft. Draft releases are ignored
|
||||||
by the 'track latest' release policy but can be used through release pinning.
|
by the 'track latest' release policy but can be used through release pinning.
|
||||||
Draft releases can be marked as final through the API. Releases as created
|
Draft releases can be marked as final through the API. Releases are created
|
||||||
as final by default unless this option is given.
|
as final by default unless this option is given.
|
||||||
|
|
||||||
#### -e, --emulated
|
#### -e, --emulated
|
||||||
|
@ -141,7 +141,7 @@ ${dockerignoreHelp}
|
|||||||
description: stripIndent`
|
description: stripIndent`
|
||||||
Deploy the release as a draft. Draft releases are ignored
|
Deploy the release as a draft. Draft releases are ignored
|
||||||
by the 'track latest' release policy but can be used through release pinning.
|
by the 'track latest' release policy but can be used through release pinning.
|
||||||
Draft releases can be marked as final through the API. Releases as created
|
Draft releases can be marked as final through the API. Releases are created
|
||||||
as final by default unless this option is given.`,
|
as final by default unless this option is given.`,
|
||||||
default: false,
|
default: false,
|
||||||
}),
|
}),
|
||||||
|
@ -177,6 +177,7 @@ export async function originalTarDirectory(dir, param) {
|
|||||||
* @param {import('resin-compose-parse').Composition} composition
|
* @param {import('resin-compose-parse').Composition} composition
|
||||||
* @param {boolean} draft
|
* @param {boolean} draft
|
||||||
* @param {string|undefined} semver
|
* @param {string|undefined} semver
|
||||||
|
* @param {string|undefined} contract
|
||||||
* @returns {Promise<import('./compose-types').Release>}
|
* @returns {Promise<import('./compose-types').Release>}
|
||||||
*/
|
*/
|
||||||
export const createRelease = async function (
|
export const createRelease = async function (
|
||||||
@ -187,6 +188,7 @@ export const createRelease = async function (
|
|||||||
composition,
|
composition,
|
||||||
draft,
|
draft,
|
||||||
semver,
|
semver,
|
||||||
|
contract,
|
||||||
) {
|
) {
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
@ -203,6 +205,7 @@ export const createRelease = async function (
|
|||||||
commit: crypto.pseudoRandomBytes(16).toString('hex').toLowerCase(),
|
commit: crypto.pseudoRandomBytes(16).toString('hex').toLowerCase(),
|
||||||
semver,
|
semver,
|
||||||
is_final: !draft,
|
is_final: !draft,
|
||||||
|
contract,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -1314,18 +1314,12 @@ export async function deployProject(
|
|||||||
const prefix = getChalk().cyan('[Info]') + ' ';
|
const prefix = getChalk().cyan('[Info]') + ' ';
|
||||||
const spinner = createSpinner();
|
const spinner = createSpinner();
|
||||||
|
|
||||||
const contract = await getContractContent(
|
const contractPath = path.join(projectPath, 'balena.yml');
|
||||||
path.join(projectPath, 'balena.yml'),
|
const contract = await getContractContent(contractPath);
|
||||||
);
|
|
||||||
if (contract?.version && !PLAIN_SEMVER_REGEX.test(contract?.version)) {
|
if (contract?.version && !PLAIN_SEMVER_REGEX.test(contract?.version)) {
|
||||||
throw new ExpectedError(
|
throw new ExpectedError(stripIndent`\
|
||||||
stripIndent`Error: expected the version field in ${path.join(
|
Error: expected the version field in "${contractPath}"
|
||||||
projectPath,
|
to be a basic semver in the format '1.2.3'. Got '${contract.version}' instead`);
|
||||||
'balena.yml',
|
|
||||||
)} to be a basic semver in the format '1.2.3'. Got '${
|
|
||||||
contract.version
|
|
||||||
}' instead`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const $release = await runSpinner(
|
const $release = await runSpinner(
|
||||||
@ -1341,6 +1335,7 @@ export async function deployProject(
|
|||||||
composition,
|
composition,
|
||||||
isDraft,
|
isDraft,
|
||||||
contract?.version,
|
contract?.version,
|
||||||
|
contract ? JSON.stringify(contract) : undefined,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
const { client: pineClient, release, serviceImages } = $release;
|
const { client: pineClient, release, serviceImages } = $release;
|
||||||
@ -1376,11 +1371,6 @@ export async function deployProject(
|
|||||||
} finally {
|
} finally {
|
||||||
await runSpinner(tty, spinner, `${prefix}Saving release...`, async () => {
|
await runSpinner(tty, spinner, `${prefix}Saving release...`, async () => {
|
||||||
release.end_timestamp = new Date();
|
release.end_timestamp = new Date();
|
||||||
|
|
||||||
// Add contract contents to the release
|
|
||||||
if (contract) {
|
|
||||||
release.contract = JSON.stringify(contract);
|
|
||||||
}
|
|
||||||
if (release.id != null) {
|
if (release.id != null) {
|
||||||
await releaseMod.updateRelease(pineClient, release.id, release);
|
await releaseMod.updateRelease(pineClient, release.id, release);
|
||||||
}
|
}
|
||||||
|
6
npm-shrinkwrap.json
generated
6
npm-shrinkwrap.json
generated
@ -3969,9 +3969,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"balena-release": {
|
"balena-release": {
|
||||||
"version": "3.1.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/balena-release/-/balena-release-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/balena-release/-/balena-release-3.2.0.tgz",
|
||||||
"integrity": "sha512-FEbu6mdRUXgqZM0UTEz80zS5fLJDPPJ1ztF0+kmFR4VQ1Cr/s1Xn3m35GCREZlq5quOWLQnWr5Xe2TESH7IdIA==",
|
"integrity": "sha512-jwmAjIZCJ5I46/yQNN+dA73RWlre0+jBVmo2QeJl1pK83obTLyifJeWNVf5irzP8KFE7WQzo9ICK1cCpLtygFA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/bluebird": "^3.5.18",
|
"@types/bluebird": "^3.5.18",
|
||||||
"@types/node": "^8.0.55",
|
"@types/node": "^8.0.55",
|
||||||
|
@ -206,7 +206,7 @@
|
|||||||
"balena-image-fs": "^7.0.6",
|
"balena-image-fs": "^7.0.6",
|
||||||
"balena-image-manager": "^7.0.3",
|
"balena-image-manager": "^7.0.3",
|
||||||
"balena-preload": "^10.5.0",
|
"balena-preload": "^10.5.0",
|
||||||
"balena-release": "^3.1.0",
|
"balena-release": "^3.2.0",
|
||||||
"balena-sdk": "^15.48.0",
|
"balena-sdk": "^15.48.0",
|
||||||
"balena-semver": "^2.3.0",
|
"balena-semver": "^2.3.0",
|
||||||
"balena-settings-client": "^4.0.7",
|
"balena-settings-client": "^4.0.7",
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import type { Request as ReleaseRequest } from 'balena-release';
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai';
|
||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
@ -162,10 +163,9 @@ describe('balena deploy', function () {
|
|||||||
'with-contract',
|
'with-contract',
|
||||||
);
|
);
|
||||||
const expectedFiles: ExpectedTarStreamFiles = {
|
const expectedFiles: ExpectedTarStreamFiles = {
|
||||||
'src/.dockerignore': { fileSize: 16, type: 'file' },
|
|
||||||
'src/start.sh': { fileSize: 30, type: 'file' },
|
'src/start.sh': { fileSize: 30, type: 'file' },
|
||||||
Dockerfile: { fileSize: 88, type: 'file' },
|
Dockerfile: { fileSize: 88, type: 'file' },
|
||||||
'balena.yml': { fileSize: 58, type: 'file' },
|
'balena.yml': { fileSize: 55, type: 'file' },
|
||||||
};
|
};
|
||||||
const responseFilename = 'build-POST.json';
|
const responseFilename = 'build-POST.json';
|
||||||
const responseBody = await fs.readFile(
|
const responseBody = await fs.readFile(
|
||||||
@ -176,19 +176,14 @@ describe('balena deploy', function () {
|
|||||||
...commonResponseLines[responseFilename],
|
...commonResponseLines[responseFilename],
|
||||||
`[Info] No "docker-compose.yml" file found at "${projectPath}"`,
|
`[Info] No "docker-compose.yml" file found at "${projectPath}"`,
|
||||||
`[Info] Creating default composition with source: "${projectPath}"`,
|
`[Info] Creating default composition with source: "${projectPath}"`,
|
||||||
...getDockerignoreWarn1(
|
|
||||||
[path.join(projectPath, 'src', '.dockerignore')],
|
|
||||||
'deploy',
|
|
||||||
),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
api.expectPostRelease({
|
api.expectPostRelease({
|
||||||
inspectRequest: (_uri: string, requestBody: nock.Body) => {
|
inspectRequest: (_uri: string, requestBody: nock.Body) => {
|
||||||
const body = requestBody.valueOf() as {
|
const body = requestBody.valueOf() as Partial<ReleaseRequest>;
|
||||||
semver: string;
|
expect(body.contract).to.be.equal(
|
||||||
is_final: boolean;
|
'{"name":"testContract","type":"sw.application","version":"1.5.2"}',
|
||||||
};
|
);
|
||||||
expect(body.semver).to.be.equal('1.5.2');
|
|
||||||
expect(body.is_final).to.be.true;
|
expect(body.is_final).to.be.true;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -216,10 +211,9 @@ describe('balena deploy', function () {
|
|||||||
'with-contract',
|
'with-contract',
|
||||||
);
|
);
|
||||||
const expectedFiles: ExpectedTarStreamFiles = {
|
const expectedFiles: ExpectedTarStreamFiles = {
|
||||||
'src/.dockerignore': { fileSize: 16, type: 'file' },
|
|
||||||
'src/start.sh': { fileSize: 30, type: 'file' },
|
'src/start.sh': { fileSize: 30, type: 'file' },
|
||||||
Dockerfile: { fileSize: 88, type: 'file' },
|
Dockerfile: { fileSize: 88, type: 'file' },
|
||||||
'balena.yml': { fileSize: 58, type: 'file' },
|
'balena.yml': { fileSize: 55, type: 'file' },
|
||||||
};
|
};
|
||||||
const responseFilename = 'build-POST.json';
|
const responseFilename = 'build-POST.json';
|
||||||
const responseBody = await fs.readFile(
|
const responseBody = await fs.readFile(
|
||||||
@ -230,18 +224,14 @@ describe('balena deploy', function () {
|
|||||||
...commonResponseLines[responseFilename],
|
...commonResponseLines[responseFilename],
|
||||||
`[Info] No "docker-compose.yml" file found at "${projectPath}"`,
|
`[Info] No "docker-compose.yml" file found at "${projectPath}"`,
|
||||||
`[Info] Creating default composition with source: "${projectPath}"`,
|
`[Info] Creating default composition with source: "${projectPath}"`,
|
||||||
...getDockerignoreWarn1(
|
|
||||||
[path.join(projectPath, 'src', '.dockerignore')],
|
|
||||||
'deploy',
|
|
||||||
),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
api.expectPostRelease({
|
api.expectPostRelease({
|
||||||
inspectRequest: (_uri: string, requestBody: nock.Body) => {
|
inspectRequest: (_uri: string, requestBody: nock.Body) => {
|
||||||
const body = requestBody.valueOf() as {
|
const body = requestBody.valueOf() as Partial<ReleaseRequest>;
|
||||||
semver: string;
|
expect(body.contract).to.be.equal(
|
||||||
is_final: boolean;
|
'{"name":"testContract","type":"sw.application","version":"1.5.2"}',
|
||||||
};
|
);
|
||||||
expect(body.semver).to.be.equal('1.5.2');
|
expect(body.semver).to.be.equal('1.5.2');
|
||||||
expect(body.is_final).to.be.false;
|
expect(body.is_final).to.be.false;
|
||||||
},
|
},
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
name: testymctestface
|
name: testContract
|
||||||
type: sw.application
|
type: sw.application
|
||||||
version: 1.5.2
|
version: 1.5.2
|
||||||
|
@ -1 +0,0 @@
|
|||||||
windows-crlf.sh
|
|
Loading…
x
Reference in New Issue
Block a user