Add contract contents at release creation time

Change-type: patch
This commit is contained in:
Paulo Castro 2021-08-26 15:05:50 +01:00
parent 9937b91606
commit d0cdc900a2
9 changed files with 27 additions and 45 deletions

View File

@ -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
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.
#### -e, --emulated

View File

@ -141,7 +141,7 @@ ${dockerignoreHelp}
description: stripIndent`
Deploy the release as a draft. Draft releases are ignored
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.`,
default: false,
}),

View File

@ -177,6 +177,7 @@ export async function originalTarDirectory(dir, param) {
* @param {import('resin-compose-parse').Composition} composition
* @param {boolean} draft
* @param {string|undefined} semver
* @param {string|undefined} contract
* @returns {Promise<import('./compose-types').Release>}
*/
export const createRelease = async function (
@ -187,6 +188,7 @@ export const createRelease = async function (
composition,
draft,
semver,
contract,
) {
const _ = require('lodash');
const crypto = require('crypto');
@ -203,6 +205,7 @@ export const createRelease = async function (
commit: crypto.pseudoRandomBytes(16).toString('hex').toLowerCase(),
semver,
is_final: !draft,
contract,
});
return {

View File

@ -1314,18 +1314,12 @@ export async function deployProject(
const prefix = getChalk().cyan('[Info]') + ' ';
const spinner = createSpinner();
const contract = await getContractContent(
path.join(projectPath, 'balena.yml'),
);
const contractPath = path.join(projectPath, 'balena.yml');
const contract = await getContractContent(contractPath);
if (contract?.version && !PLAIN_SEMVER_REGEX.test(contract?.version)) {
throw new ExpectedError(
stripIndent`Error: expected the version field in ${path.join(
projectPath,
'balena.yml',
)} to be a basic semver in the format '1.2.3'. Got '${
contract.version
}' instead`,
);
throw new ExpectedError(stripIndent`\
Error: expected the version field in "${contractPath}"
to be a basic semver in the format '1.2.3'. Got '${contract.version}' instead`);
}
const $release = await runSpinner(
@ -1341,6 +1335,7 @@ export async function deployProject(
composition,
isDraft,
contract?.version,
contract ? JSON.stringify(contract) : undefined,
),
);
const { client: pineClient, release, serviceImages } = $release;
@ -1376,11 +1371,6 @@ export async function deployProject(
} finally {
await runSpinner(tty, spinner, `${prefix}Saving release...`, async () => {
release.end_timestamp = new Date();
// Add contract contents to the release
if (contract) {
release.contract = JSON.stringify(contract);
}
if (release.id != null) {
await releaseMod.updateRelease(pineClient, release.id, release);
}

6
npm-shrinkwrap.json generated
View File

@ -3969,9 +3969,9 @@
}
},
"balena-release": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/balena-release/-/balena-release-3.1.0.tgz",
"integrity": "sha512-FEbu6mdRUXgqZM0UTEz80zS5fLJDPPJ1ztF0+kmFR4VQ1Cr/s1Xn3m35GCREZlq5quOWLQnWr5Xe2TESH7IdIA==",
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/balena-release/-/balena-release-3.2.0.tgz",
"integrity": "sha512-jwmAjIZCJ5I46/yQNN+dA73RWlre0+jBVmo2QeJl1pK83obTLyifJeWNVf5irzP8KFE7WQzo9ICK1cCpLtygFA==",
"requires": {
"@types/bluebird": "^3.5.18",
"@types/node": "^8.0.55",

View File

@ -206,7 +206,7 @@
"balena-image-fs": "^7.0.6",
"balena-image-manager": "^7.0.3",
"balena-preload": "^10.5.0",
"balena-release": "^3.1.0",
"balena-release": "^3.2.0",
"balena-sdk": "^15.48.0",
"balena-semver": "^2.3.0",
"balena-settings-client": "^4.0.7",

View File

@ -15,6 +15,7 @@
* limitations under the License.
*/
import type { Request as ReleaseRequest } from 'balena-release';
import { expect } from 'chai';
import { promises as fs } from 'fs';
import * as _ from 'lodash';
@ -162,10 +163,9 @@ describe('balena deploy', function () {
'with-contract',
);
const expectedFiles: ExpectedTarStreamFiles = {
'src/.dockerignore': { fileSize: 16, type: 'file' },
'src/start.sh': { fileSize: 30, 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 responseBody = await fs.readFile(
@ -176,19 +176,14 @@ describe('balena deploy', function () {
...commonResponseLines[responseFilename],
`[Info] No "docker-compose.yml" file found at "${projectPath}"`,
`[Info] Creating default composition with source: "${projectPath}"`,
...getDockerignoreWarn1(
[path.join(projectPath, 'src', '.dockerignore')],
'deploy',
),
];
api.expectPostRelease({
inspectRequest: (_uri: string, requestBody: nock.Body) => {
const body = requestBody.valueOf() as {
semver: string;
is_final: boolean;
};
expect(body.semver).to.be.equal('1.5.2');
const body = requestBody.valueOf() as Partial<ReleaseRequest>;
expect(body.contract).to.be.equal(
'{"name":"testContract","type":"sw.application","version":"1.5.2"}',
);
expect(body.is_final).to.be.true;
},
});
@ -216,10 +211,9 @@ describe('balena deploy', function () {
'with-contract',
);
const expectedFiles: ExpectedTarStreamFiles = {
'src/.dockerignore': { fileSize: 16, type: 'file' },
'src/start.sh': { fileSize: 30, 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 responseBody = await fs.readFile(
@ -230,18 +224,14 @@ describe('balena deploy', function () {
...commonResponseLines[responseFilename],
`[Info] No "docker-compose.yml" file found at "${projectPath}"`,
`[Info] Creating default composition with source: "${projectPath}"`,
...getDockerignoreWarn1(
[path.join(projectPath, 'src', '.dockerignore')],
'deploy',
),
];
api.expectPostRelease({
inspectRequest: (_uri: string, requestBody: nock.Body) => {
const body = requestBody.valueOf() as {
semver: string;
is_final: boolean;
};
const body = requestBody.valueOf() as Partial<ReleaseRequest>;
expect(body.contract).to.be.equal(
'{"name":"testContract","type":"sw.application","version":"1.5.2"}',
);
expect(body.semver).to.be.equal('1.5.2');
expect(body.is_final).to.be.false;
},

View File

@ -1,3 +1,3 @@
name: testymctestface
name: testContract
type: sw.application
version: 1.5.2