@24i/smartapps-bigscreen-rnv-build-engine 0.0.2-alpha.1321 → 0.0.2-alpha.1323
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/dist/src/index.js +3 -1
- package/dist/src/tasks/deploy/aswS3/deployS3.js +3 -2
- package/dist/src/tasks/deploy/hbbtv/deployHbbtv.js +12 -9
- package/dist/src/tasks/task.rnv.build.js +17 -15
- package/dist/src/tasks/task.rnv.configure.js +3 -1
- package/dist/src/tasks/task.rnv.configureSoft.js +3 -1
- package/dist/src/tasks/task.rnv.deploy.js +5 -2
- package/dist/src/tasks/task.rnv.hooks.run.js +4 -2
- package/dist/src/utils/forEachSupportedPlatformFlavour.js +8 -8
- package/dist/src/utils/getBaseConfig.js +5 -3
- package/dist/src/utils/getDeployLocations.js +1 -3
- package/dist/src/utils/getVersionOffset.js +4 -4
- package/dist/src/utils/replaceRelevantStringsInConfig/replaceTemplateString.js +2 -2
- package/engine/src/enginePlatforms.js +16 -0
- package/engine/src/index.js +67 -0
- package/engine/src/scripts/buildAllWithScheme.js +29 -0
- package/engine/src/scripts/gitReleaser/afterVersionBump.js +24 -0
- package/engine/src/scripts/gitReleaser/beforeVersionBump.js +15 -0
- package/engine/src/scripts/gitReleaser/checkReleaseNotes.js +22 -0
- package/engine/src/scripts/gitReleaser/pushRelease.js +41 -0
- package/engine/src/scripts/gitReleaser/pushReleaseCandidate.js +8 -0
- package/engine/src/scripts/gitReleaser/pushReleaseNotes.js +53 -0
- package/engine/src/scripts/release/deleteSourceMaps.js +14 -0
- package/engine/src/scripts/release/deployToAppCenter.js +79 -0
- package/engine/src/scripts/release/githubRelease.js +138 -0
- package/engine/src/scripts/release/notifySlack/makePayload.js +103 -0
- package/engine/src/scripts/release/notifySlack/notifySlack.js +26 -0
- package/engine/src/scripts/release/notifySlack/slackBlockKitBuilder.js +44 -0
- package/engine/src/scripts/release/sentryRelease.js +79 -0
- package/engine/src/scripts/release/urlsMarkdown.js +85 -0
- package/engine/src/scripts/releaseAllWithScheme.js +91 -0
- package/engine/src/scripts/utils/cmdUtils.js +16 -0
- package/engine/src/scripts/utils/fsUtils.js +14 -0
- package/engine/src/scripts/utils/gitUtils.js +94 -0
- package/engine/src/scripts/utils/index.js +11 -0
- package/engine/src/scripts/utils/stringUtils.js +5 -0
- package/engine/src/sdks/index.js +22 -0
- package/engine/src/sdks/sdk-tizen/index.js +287 -0
- package/engine/src/sdks/sdk-webos/index.js +201 -0
- package/engine/src/sdks/sdk-webpack/index.js +45 -0
- package/engine/src/sdks/sdkUtils.js +22 -0
- package/engine/src/tasks/deploy/aswS3/aws.js +27 -0
- package/engine/src/tasks/deploy/aswS3/deployS3.js +71 -0
- package/engine/src/tasks/deploy/hbbtv/deployHbbtv.js +144 -0
- package/engine/src/tasks/engineTasks.js +23 -0
- package/engine/src/tasks/task.rnv.build.js +126 -0
- package/engine/src/tasks/task.rnv.configure.js +52 -0
- package/engine/src/tasks/task.rnv.configureSoft.js +31 -0
- package/engine/src/tasks/task.rnv.deploy.js +40 -0
- package/engine/src/tasks/task.rnv.hooks.run.js +61 -0
- package/engine/src/tasks/task.rnv.package.js +27 -0
- package/engine/src/tasks/task.rnv.project.configure.js +109 -0
- package/engine/src/tasks/task.rnv.start.js +52 -0
- package/engine/src/utils/forEachSupportedPlatformFlavour.js +29 -0
- package/engine/src/utils/getBaseConfig.js +57 -0
- package/engine/src/utils/getDeployLocations.js +78 -0
- package/engine/src/utils/getVersionOffset.js +39 -0
- package/engine/src/utils/replaceRelevantStringsInConfig/index.js +1 -0
- package/engine/src/utils/replaceRelevantStringsInConfig/replaceRelevantStringsInConfig.js +36 -0
- package/engine/src/utils/replaceRelevantStringsInConfig/replaceTemplateString.js +70 -0
- package/engine/src/utils/resolveBaseUrl.js +35 -0
- package/engine/src/utils/resolveBuildVersion.js +47 -0
- package/engine/src/utils/zipBuildsByPlatforms.js +70 -0
- package/package.json +4 -3
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { getConfigProp } from 'rnv/dist/core/common';
|
|
4
|
+
import { getZippedPlatformBuildsFilePath } from '../../utils/zipBuildsByPlatforms';
|
|
5
|
+
import { getUrlsMarkdown } from './urlsMarkdown';
|
|
6
|
+
|
|
7
|
+
const appCenterRelease = (params) => {
|
|
8
|
+
const {
|
|
9
|
+
filePath, releaseNotesPath, buildVersion, token, projectName,
|
|
10
|
+
group = 'Collaborators', organizationName = '24i-Media',
|
|
11
|
+
} = params;
|
|
12
|
+
const app = `${organizationName}/${projectName}`;
|
|
13
|
+
|
|
14
|
+
execSync(
|
|
15
|
+
'appcenter distribute release '
|
|
16
|
+
+ `--file "${filePath}" `
|
|
17
|
+
+ `--release-notes-file "${releaseNotesPath}" `
|
|
18
|
+
+ `--build-version "${buildVersion}" `
|
|
19
|
+
+ `--app "${app}" `
|
|
20
|
+
+ `--token "${token}" `
|
|
21
|
+
+ `--group "${group}" `
|
|
22
|
+
+ '--disable-telemetry',
|
|
23
|
+
{ stdio: 'inherit' },
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const getAppCenterConfigByPlatformName = (c, platformName) => {
|
|
28
|
+
try {
|
|
29
|
+
return c.buildConfig.platforms[platformName].deploy.appCenter || null;
|
|
30
|
+
} catch (error) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const getTokenByPlatform = (platformName = '') => {
|
|
36
|
+
const envVariableName = `APPCENTER_TOKEN_${platformName.toUpperCase()}`;
|
|
37
|
+
return process.env[envVariableName] || '';
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const processPlatform = (c, platformName) => {
|
|
41
|
+
const appCenterConfig = getAppCenterConfigByPlatformName(c, platformName);
|
|
42
|
+
if (!appCenterConfig) return;
|
|
43
|
+
|
|
44
|
+
const { appName } = appCenterConfig;
|
|
45
|
+
|
|
46
|
+
const token = getTokenByPlatform(platformName);
|
|
47
|
+
const zipPath = getZippedPlatformBuildsFilePath(c, platformName);
|
|
48
|
+
const buildVersion = getConfigProp(c, platformName, 'packageVersion', '');
|
|
49
|
+
const releaseNotesPath = getConfigProp(c, platformName, 'releaseNotes', {}).relativePath || '';
|
|
50
|
+
|
|
51
|
+
if (!appName || !token || !releaseNotesPath || !zipPath || !buildVersion) return;
|
|
52
|
+
|
|
53
|
+
const tempReleaseNotesPath = `RELEASE_NOTES_APPCENTER_${platformName.toUpperCase()}.md`;
|
|
54
|
+
if (fs.existsSync(tempReleaseNotesPath)) {
|
|
55
|
+
fs.unlinkSync(tempReleaseNotesPath);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
execSync(`cat ${releaseNotesPath} >> ${tempReleaseNotesPath}`);
|
|
59
|
+
const urlsMarkdown = getUrlsMarkdown(c, [platformName]);
|
|
60
|
+
execSync(`echo "${urlsMarkdown}" >> ${tempReleaseNotesPath}`);
|
|
61
|
+
|
|
62
|
+
console.log(`Deploying ${platformName} platform to AppCenter.ms...`);
|
|
63
|
+
appCenterRelease({
|
|
64
|
+
projectName: appName,
|
|
65
|
+
buildVersion,
|
|
66
|
+
filePath: zipPath,
|
|
67
|
+
releaseNotesPath: tempReleaseNotesPath,
|
|
68
|
+
token,
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const deployToAppCenter = (c) => {
|
|
73
|
+
const { supportedPlatforms = [] } = c.buildConfig.defaults || {};
|
|
74
|
+
supportedPlatforms.forEach((platformName) => processPlatform(c, platformName));
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export {
|
|
78
|
+
deployToAppCenter,
|
|
79
|
+
};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { strict } from 'assert';
|
|
4
|
+
import { basename } from 'path';
|
|
5
|
+
import { getZippedPlatformBuildsFilePath } from '../../utils/zipBuildsByPlatforms';
|
|
6
|
+
import { getUrlsMarkdown } from './urlsMarkdown';
|
|
7
|
+
|
|
8
|
+
const { ok } = strict;
|
|
9
|
+
|
|
10
|
+
const token = process.env.GITHUB_TOKEN;
|
|
11
|
+
const targetCommit = process.env.TRAVIS_COMMIT;
|
|
12
|
+
|
|
13
|
+
const githubContentType = 'application/vnd.github.v3+json';
|
|
14
|
+
const githubReleaseNotesPath = 'RELEASE_NOTES_GITHUB.md';
|
|
15
|
+
|
|
16
|
+
const handleResponseErrors = (response) => {
|
|
17
|
+
const { errors, message } = response;
|
|
18
|
+
|
|
19
|
+
if (message && !errors) throw new Error(`GitHub error: ${message}`);
|
|
20
|
+
if (!errors) return;
|
|
21
|
+
|
|
22
|
+
const makeErrorDetailString = (error = {}) => {
|
|
23
|
+
return Object.keys(error)
|
|
24
|
+
.map((key) => `${key}: "${error[key]}"`)
|
|
25
|
+
.join(', ');
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const errorsDetails = errors.map(makeErrorDetailString);
|
|
29
|
+
throw new Error(`GitHub error: ${message || ''}\n${errorsDetails.join('\n')}`);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const getReleaseNotesPath = (c) => {
|
|
33
|
+
try {
|
|
34
|
+
return c.buildConfig.common.releaseNotes.relativePath || '';
|
|
35
|
+
} catch (error) {
|
|
36
|
+
return '';
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const deleteFileIfExists = (filePath) => {
|
|
41
|
+
if (fs.existsSync(filePath)) {
|
|
42
|
+
fs.unlinkSync(filePath);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const makeGitHubReleaseNotes = (c) => {
|
|
47
|
+
const releaseNotesPath = getReleaseNotesPath(c);
|
|
48
|
+
ok(releaseNotesPath, 'The path to the file with release notes is missing!');
|
|
49
|
+
|
|
50
|
+
deleteFileIfExists(githubReleaseNotesPath);
|
|
51
|
+
execSync(`sed '1d;2d' ${releaseNotesPath} >> ${githubReleaseNotesPath}`); // copy without first two lines
|
|
52
|
+
const textToAppend = getUrlsMarkdown(c);
|
|
53
|
+
execSync(`echo "${textToAppend}" >> ${githubReleaseNotesPath}`);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const createRelease = (c) => {
|
|
57
|
+
const { packageVersion, git = {} } = c.buildConfig.common;
|
|
58
|
+
const versionLabel = `v${packageVersion}`;
|
|
59
|
+
|
|
60
|
+
ok(token, 'process.env.GITHUB_TOKEN is not set!');
|
|
61
|
+
ok(targetCommit, 'process.env.TRAVIS_COMMIT is not set!');
|
|
62
|
+
ok(git.owner, 'Missing value for rnv config prop: common.git.owner');
|
|
63
|
+
ok(git.repo, 'Missing value for rnv config prop: common.git.repo');
|
|
64
|
+
ok(packageVersion);
|
|
65
|
+
|
|
66
|
+
makeGitHubReleaseNotes(c);
|
|
67
|
+
const releaseNotesContent = fs.readFileSync(githubReleaseNotesPath).toString();
|
|
68
|
+
|
|
69
|
+
const data = {
|
|
70
|
+
tag_name: versionLabel,
|
|
71
|
+
target_commitish: targetCommit,
|
|
72
|
+
name: versionLabel,
|
|
73
|
+
body: releaseNotesContent,
|
|
74
|
+
draft: false,
|
|
75
|
+
prerelease: false,
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const url = `https://api.github.com/repos/${git.owner}/${git.repo}/releases`;
|
|
79
|
+
const headers = `-H "Accept: ${githubContentType}" -H "Authorization: token ${token}"`;
|
|
80
|
+
const dataStringWithFixedSingleQuotes = JSON.stringify(data).replace(/'/g, "'\\''");
|
|
81
|
+
const cmd = `curl -X POST ${headers} ${url} -d '${dataStringWithFixedSingleQuotes}'`;
|
|
82
|
+
|
|
83
|
+
console.log(`Pushing GitHub Release: ${versionLabel}...`);
|
|
84
|
+
const responseString = execSync(cmd, { stdio: 'pipe' }).toString();
|
|
85
|
+
const response = JSON.parse(responseString);
|
|
86
|
+
handleResponseErrors(response);
|
|
87
|
+
console.log('Pushing done.');
|
|
88
|
+
|
|
89
|
+
return response;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const getFileMimeType = (filepath) => {
|
|
93
|
+
const cmd = `file --mime-type -b ${filepath}`;
|
|
94
|
+
return execSync(cmd, { stdio: 'pipe' })
|
|
95
|
+
.toString()
|
|
96
|
+
.replace(/\r?\n/, '');
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const uploadAsset = (uploadUrl = '', filePath) => {
|
|
100
|
+
if (!uploadUrl) return null;
|
|
101
|
+
const url = `${uploadUrl.replace('{?name,label}', '')}`;
|
|
102
|
+
const headers = `-H "Accept: ${githubContentType}" -H "Authorization: token ${token}" -H "content-type: ${getFileMimeType(filePath)}" -H "content-length: ${fs.statSync(filePath).size}"`;
|
|
103
|
+
const cmd = `curl --data-binary @"${filePath}" ${headers} ${url}?name=${basename(filePath)}`;
|
|
104
|
+
|
|
105
|
+
console.log(`Uploading ${filePath} asset to created GitHub Release...`);
|
|
106
|
+
const responseString = execSync(cmd, { stdio: 'pipe' }).toString();
|
|
107
|
+
const uploadResponse = JSON.parse(responseString);
|
|
108
|
+
handleResponseErrors(uploadResponse);
|
|
109
|
+
console.log('Uploading done.');
|
|
110
|
+
|
|
111
|
+
return uploadResponse;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const uploadZipWithPlatformBuilds = (c, platformName, githubUploadUrl) => {
|
|
115
|
+
const zipFilePath = getZippedPlatformBuildsFilePath(c, platformName);
|
|
116
|
+
|
|
117
|
+
if (zipFilePath) {
|
|
118
|
+
uploadAsset(githubUploadUrl, zipFilePath);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const githubRelease = (c) => {
|
|
123
|
+
const releaseResponse = createRelease(c) || {};
|
|
124
|
+
const uploadUrl = releaseResponse.upload_url;
|
|
125
|
+
ok(uploadUrl, 'Missing "upload_url" in release response!');
|
|
126
|
+
|
|
127
|
+
const { defaults = {} } = c.buildConfig;
|
|
128
|
+
const { supportedPlatforms = [] } = defaults;
|
|
129
|
+
|
|
130
|
+
supportedPlatforms.forEach((platformName) => {
|
|
131
|
+
uploadZipWithPlatformBuilds(c, platformName, uploadUrl);
|
|
132
|
+
});
|
|
133
|
+
deleteFileIfExists(githubReleaseNotesPath);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export {
|
|
137
|
+
githubRelease,
|
|
138
|
+
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Section, Actions, Divider, Context } from './slackBlockKitBuilder';
|
|
2
|
+
import { getDeployLocations } from '../../../utils/getDeployLocations';
|
|
3
|
+
|
|
4
|
+
const getVersionsObject = (c) => {
|
|
5
|
+
const { versions = [] } = getDeployLocations(c) || {};
|
|
6
|
+
return versions;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const getVersion = (c) => {
|
|
10
|
+
return Object.keys(getVersionsObject(c))[0] || '';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const getPlatformsObject = (c) => {
|
|
14
|
+
const version = getVersion(c);
|
|
15
|
+
const { platforms = {} } = getVersionsObject(c)[version] || {};
|
|
16
|
+
return platforms;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const getCommonAppName = (c) => {
|
|
20
|
+
try { return c.buildConfig.common.appName }
|
|
21
|
+
catch (error) { return '' }
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const makeFlavoursMarkdown = (platformName, entries) => {
|
|
25
|
+
return entries
|
|
26
|
+
.map(([flavour, flavourData]) => {
|
|
27
|
+
const { indexUrl, packageUrl } = flavourData;
|
|
28
|
+
return `- *${flavour}* [<${packageUrl}|Download>] [<${indexUrl}|Open deployed index.html>]`;
|
|
29
|
+
})
|
|
30
|
+
.join('\n');
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const makePackagePayload = (c, platformName) => {
|
|
34
|
+
const platformData = getPlatformsObject(c)[platformName];
|
|
35
|
+
const flavoursEntries = Object.entries(platformData);
|
|
36
|
+
|
|
37
|
+
return [
|
|
38
|
+
Divider.plain(),
|
|
39
|
+
Context.mrkdwns([`Platform: *${platformName}*`]),
|
|
40
|
+
Context.mrkdwns([makeFlavoursMarkdown(platformName, flavoursEntries)]),
|
|
41
|
+
];
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const makePackagesPayload = (c) => {
|
|
45
|
+
const platformList = Object.keys(getPlatformsObject(c));
|
|
46
|
+
return platformList
|
|
47
|
+
.map((platformName) => makePackagePayload(c, platformName))
|
|
48
|
+
.flat();
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const makeHeaderPayload = (c, { title = '', buttons }) => {
|
|
52
|
+
const { travisBuild, gitHubRelease } = buttons || {};
|
|
53
|
+
const { owner, repo } = c.buildConfig.common.git || {};
|
|
54
|
+
const version = getVersion(c);
|
|
55
|
+
|
|
56
|
+
return [
|
|
57
|
+
Divider.plain(),
|
|
58
|
+
Section.mrkdwn(title),
|
|
59
|
+
Context.mrkdwns([`Version: *${version}*`]),
|
|
60
|
+
Actions.buttons([
|
|
61
|
+
travisBuild ? {
|
|
62
|
+
text: 'View Travis Build Log',
|
|
63
|
+
url: process.env.TRAVIS_BUILD_WEB_URL || `https://travis-ci.com/github/${owner}/${repo}/branches`,
|
|
64
|
+
} : null,
|
|
65
|
+
gitHubRelease ? {
|
|
66
|
+
text: 'View GitHub Release',
|
|
67
|
+
url: `https://github.com/${owner}/${repo}/releases/tag/${version}`,
|
|
68
|
+
} : null,
|
|
69
|
+
].filter(Boolean)),
|
|
70
|
+
];
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const makePayload = (c, title, buttons) => ({
|
|
74
|
+
blocks: [
|
|
75
|
+
...makeHeaderPayload(c, { title, buttons }),
|
|
76
|
+
...makePackagesPayload(c),
|
|
77
|
+
],
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const makeDevelopmentPayload = (c) => {
|
|
81
|
+
const title = `There are new *development* builds for *${getCommonAppName(c)}* app!`;
|
|
82
|
+
const buttons = { travisBuild: true };
|
|
83
|
+
return makePayload(c, title, buttons);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const makeReleaseCandidatePayload = (c) => {
|
|
87
|
+
const title = `There are new *release candidate* builds for *${getCommonAppName(c)}* app!`;
|
|
88
|
+
const buttons = { travisBuild: true };
|
|
89
|
+
return makePayload(c, title, buttons);
|
|
90
|
+
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const makeDistributionPayload = (c) => {
|
|
94
|
+
const title = `There are new *distribution* builds for *${getCommonAppName(c)}* app!`;
|
|
95
|
+
const buttons = { travisBuild: true, gitHubRelease: true };
|
|
96
|
+
return makePayload(c, title, buttons);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export {
|
|
100
|
+
makeDevelopmentPayload,
|
|
101
|
+
makeReleaseCandidatePayload,
|
|
102
|
+
makeDistributionPayload,
|
|
103
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import * as payload from './makePayload';
|
|
3
|
+
|
|
4
|
+
const getPayload = (c) => {
|
|
5
|
+
const releaseType = c.runtime.scheme;
|
|
6
|
+
|
|
7
|
+
switch (releaseType) {
|
|
8
|
+
case 'dev:latest': return payload.makeDevelopmentPayload(c);
|
|
9
|
+
case 'rc:latest': return payload.makeReleaseCandidatePayload(c);
|
|
10
|
+
case 'release:dist': return payload.makeDistributionPayload(c);
|
|
11
|
+
default: throw new Error('Notify Slack: unsupported or undefined release type! Did you pass it as an argument?');
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const notifySlack = (c) => {
|
|
16
|
+
const contentType = '"Content-type: application/json"';
|
|
17
|
+
const data = `--data '${JSON.stringify(getPayload(c))}'`;
|
|
18
|
+
const webHookUrl = c.buildConfig?.common?.deploy?.slack?.webhookUrl || '';
|
|
19
|
+
|
|
20
|
+
const cmd = `curl -X POST -H ${contentType} ${data} ${webHookUrl}`;
|
|
21
|
+
execSync(cmd, { stdio: 'inherit' });
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export {
|
|
25
|
+
notifySlack,
|
|
26
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// https://app.slack.com/block-kit-builder
|
|
2
|
+
|
|
3
|
+
const mrkdwn = (text) => ({ type: 'mrkdwn', text });
|
|
4
|
+
|
|
5
|
+
const plainText = (text) => ({
|
|
6
|
+
type: 'plain_text',
|
|
7
|
+
text,
|
|
8
|
+
emoji: true,
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
const buttonWithUrl = ({ text, url }) => ({
|
|
12
|
+
type: 'button',
|
|
13
|
+
text: plainText(text),
|
|
14
|
+
url,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const Section = {
|
|
18
|
+
mrkdwn: (text) => ({
|
|
19
|
+
type: 'section',
|
|
20
|
+
text: mrkdwn(text),
|
|
21
|
+
}),
|
|
22
|
+
};
|
|
23
|
+
const Actions = {
|
|
24
|
+
buttons: (btnsData) => ({
|
|
25
|
+
type: 'actions',
|
|
26
|
+
elements: btnsData.map(buttonWithUrl),
|
|
27
|
+
}),
|
|
28
|
+
};
|
|
29
|
+
const Divider = {
|
|
30
|
+
plain: () => ({ type: 'divider' }),
|
|
31
|
+
};
|
|
32
|
+
const Context = {
|
|
33
|
+
mrkdwns: (texts) => ({
|
|
34
|
+
type: 'context',
|
|
35
|
+
elements: texts.map(mrkdwn),
|
|
36
|
+
}),
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export {
|
|
40
|
+
Section,
|
|
41
|
+
Actions,
|
|
42
|
+
Divider,
|
|
43
|
+
Context,
|
|
44
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
|
|
4
|
+
const UNSUPPORTED_PLATFORMS = ['webtv'];
|
|
5
|
+
|
|
6
|
+
const executeSync = (cmd) => execSync(cmd, { stdio: 'inherit' });
|
|
7
|
+
|
|
8
|
+
const createNewRelease = (version) => {
|
|
9
|
+
executeSync(`sentry-cli releases new ${version}`);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const uploadSourceMaps = (params) => {
|
|
13
|
+
const { version, sourceMapsPath, urlPrefix } = params;
|
|
14
|
+
executeSync(
|
|
15
|
+
'sentry-cli releases '
|
|
16
|
+
+ `files ${version} `
|
|
17
|
+
+ `upload-sourcemaps ${sourceMapsPath} `
|
|
18
|
+
+ `--url-prefix "~/${urlPrefix}" `
|
|
19
|
+
+ '--rewrite --validate',
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const setReleaseCommits = (version) => {
|
|
24
|
+
try {
|
|
25
|
+
executeSync(`sentry-cli releases set-commits ${version} --auto --log-level=debug`);
|
|
26
|
+
} catch (error) {
|
|
27
|
+
console.log('Sentry release commits failed: ', error);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const finalizeRelease = (version) => {
|
|
32
|
+
executeSync(`sentry-cli releases finalize ${version}`);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const processPlatform = (c, platform, version) => {
|
|
36
|
+
const processFlavour = (flavour) => {
|
|
37
|
+
const { platformBuildsDir } = c.buildConfig.paths;
|
|
38
|
+
const sourceMapsPath = `${platformBuildsDir}/${flavour}_${platform}-public/public/content/js`;
|
|
39
|
+
const urlPrefix = `builds/${platform}/${flavour}/dist/${version}/public/content/js/`;
|
|
40
|
+
if (!fs.existsSync(sourceMapsPath)) return;
|
|
41
|
+
|
|
42
|
+
console.log(`Uploading ${flavour}_${platform} sourcemaps to Sentry...`);
|
|
43
|
+
uploadSourceMaps({ version, sourceMapsPath, urlPrefix });
|
|
44
|
+
};
|
|
45
|
+
const { supportedFlavours = [] } = c.buildConfig.platforms[platform]?.deploy || {};
|
|
46
|
+
supportedFlavours.forEach(processFlavour);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const isSentryProjectConfigured = () => {
|
|
50
|
+
const cmd = execSync('sentry-cli info --config-status-json');
|
|
51
|
+
const sentryConfig = JSON.parse(cmd.toString()) || {};
|
|
52
|
+
return !!sentryConfig.config?.project;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const sentryRelease = (c) => {
|
|
56
|
+
if (!isSentryProjectConfigured()) {
|
|
57
|
+
console.log('Project is not defined...');
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const version = `v${c.buildConfig.common?.packageVersion}`;
|
|
62
|
+
if (!version) return;
|
|
63
|
+
|
|
64
|
+
const { supportedPlatforms = [] } = c.buildConfig.defaults || {};
|
|
65
|
+
const supportedPlatformsBySentry = supportedPlatforms.filter(
|
|
66
|
+
(platform) => !UNSUPPORTED_PLATFORMS.includes(platform),
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
createNewRelease(version);
|
|
70
|
+
supportedPlatformsBySentry.forEach((platform) => processPlatform(c, platform, version));
|
|
71
|
+
setReleaseCommits(version);
|
|
72
|
+
finalizeRelease(version);
|
|
73
|
+
|
|
74
|
+
console.log('Source Maps uploaded...');
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export {
|
|
78
|
+
sentryRelease,
|
|
79
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { getDeployLocations } from '../../utils/getDeployLocations';
|
|
2
|
+
import { strict } from 'assert';
|
|
3
|
+
|
|
4
|
+
const { ok } = strict;
|
|
5
|
+
|
|
6
|
+
const newLine = '\r\n';
|
|
7
|
+
|
|
8
|
+
const getDataToProceed = (c, customPlatformList = []) => {
|
|
9
|
+
const locations = getDeployLocations(c);
|
|
10
|
+
ok(locations, 'It seems that file with remote locations has not been generated! Try to check rnv build hooks...');
|
|
11
|
+
|
|
12
|
+
const { versions } = locations;
|
|
13
|
+
const { platforms } = versions[Object.keys(versions)[0]];
|
|
14
|
+
|
|
15
|
+
if (!customPlatformList.length) return platforms;
|
|
16
|
+
|
|
17
|
+
const outputData = {};
|
|
18
|
+
const addToOutputIfPlatformHasData = (platformName) => {
|
|
19
|
+
const platformData = platforms[platformName];
|
|
20
|
+
if (platformData) {
|
|
21
|
+
outputData[platformName] = platformData;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
customPlatformList.forEach(addToOutputIfPlatformHasData);
|
|
25
|
+
return outputData;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const beautifyPlatformName = (platformName) => {
|
|
29
|
+
switch (platformName.toLowerCase()) {
|
|
30
|
+
case 'entone': return 'Entone';
|
|
31
|
+
case 'hbbtv': return 'HbbTV';
|
|
32
|
+
case 'tizen': return 'Tizen (Samsung)';
|
|
33
|
+
case 'webos': return 'webOS (LG)';
|
|
34
|
+
case 'webtv': return 'WebTV';
|
|
35
|
+
default: return platformName;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const getPlatformOutput = (data, platformName) => {
|
|
40
|
+
if (platformName === 'tizen' || platformName === 'webos') {
|
|
41
|
+
return '';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const platformData = data[platformName];
|
|
45
|
+
let output = `**${beautifyPlatformName(platformName)}**${newLine}`;
|
|
46
|
+
|
|
47
|
+
const processPlatformEntry = ([flavour, flavourData]) => {
|
|
48
|
+
const { indexUrl } = flavourData;
|
|
49
|
+
output += `* [${flavour}](${indexUrl})${newLine}`;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
Object.entries(platformData).forEach(processPlatformEntry);
|
|
53
|
+
return output;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/*
|
|
57
|
+
=== OUTPUT EXAMPLE start ===
|
|
58
|
+
## URL
|
|
59
|
+
**Entone**
|
|
60
|
+
* [flavour1](http://.../index.html)
|
|
61
|
+
* [flavour2](http://.../index.html)
|
|
62
|
+
|
|
63
|
+
**WebTV**
|
|
64
|
+
* [flavour1](http://.../index.html)
|
|
65
|
+
* [flavour2](http://.../index.html)
|
|
66
|
+
=== OUTPUT EXAMPLE end ===
|
|
67
|
+
*/
|
|
68
|
+
const getUrlsMarkdown = (c, customPlatformList) => {
|
|
69
|
+
const dataToProceed = getDataToProceed(c, customPlatformList);
|
|
70
|
+
|
|
71
|
+
const markdownWithoutHeader = Object.keys(dataToProceed)
|
|
72
|
+
.map((platformName) => getPlatformOutput(dataToProceed, platformName))
|
|
73
|
+
.filter(Boolean)
|
|
74
|
+
.join(newLine);
|
|
75
|
+
|
|
76
|
+
if (markdownWithoutHeader.length) {
|
|
77
|
+
const urlHeader = `${newLine}## URL${newLine}`;
|
|
78
|
+
return urlHeader + markdownWithoutHeader;
|
|
79
|
+
}
|
|
80
|
+
return '';
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export {
|
|
84
|
+
getUrlsMarkdown,
|
|
85
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import { forEachSupportedPlatformFlavour } from '../utils/forEachSupportedPlatformFlavour';
|
|
3
|
+
import { getBaseConfig } from '../utils/getBaseConfig';
|
|
4
|
+
import { getDeployLocations } from '../utils/getDeployLocations';
|
|
5
|
+
import { zipBuildsByPlatforms } from '../utils/zipBuildsByPlatforms';
|
|
6
|
+
import { deleteSourceMaps } from './release/deleteSourceMaps';
|
|
7
|
+
import { deployToAppCenter } from './release/deployToAppCenter';
|
|
8
|
+
import { githubRelease } from './release/githubRelease';
|
|
9
|
+
import { notifySlack } from './release/notifySlack/notifySlack';
|
|
10
|
+
import { sentryRelease } from './release/sentryRelease';
|
|
11
|
+
|
|
12
|
+
const deployTask = (options) => {
|
|
13
|
+
const { scheme, platform, flavour } = options;
|
|
14
|
+
const cmd = `npx rnv deploy -s ${scheme} -p ${platform} -c ${flavour} --ci --only`;
|
|
15
|
+
execSync(cmd, { stdio: 'inherit' });
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const deployBuilds = (c) => {
|
|
19
|
+
console.log(`Deploying the builds...`);
|
|
20
|
+
forEachSupportedPlatformFlavour(c, deployTask);
|
|
21
|
+
return true;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const doLatestDevelopmentRelease = (c) => {
|
|
25
|
+
console.log('doLatestDevelopmentRelease');
|
|
26
|
+
return deployBuilds(c);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const doLatestReleaseCandidateRelease = (c) => {
|
|
30
|
+
console.log('doLatestReleaseCandidateRelease');
|
|
31
|
+
deployBuilds(c);
|
|
32
|
+
notifySlack(c);
|
|
33
|
+
|
|
34
|
+
return true;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const doLatestRelease = (c) => {
|
|
38
|
+
console.log('doLatestRelease');
|
|
39
|
+
return deployBuilds(c);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const doDistributionRelease = (c) => {
|
|
43
|
+
console.log('doDistributionRelease');
|
|
44
|
+
|
|
45
|
+
zipBuildsByPlatforms(c);
|
|
46
|
+
deployBuilds(c);
|
|
47
|
+
sentryRelease(c);
|
|
48
|
+
deleteSourceMaps(c);
|
|
49
|
+
githubRelease(c);
|
|
50
|
+
deployToAppCenter(c);
|
|
51
|
+
notifySlack(c);
|
|
52
|
+
|
|
53
|
+
return true;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const releaseAllWithScheme = () => {
|
|
57
|
+
const scheme = process.argv[2];
|
|
58
|
+
if (!scheme) {
|
|
59
|
+
throw new Error ('No scheme name to use found! Please use rnv scheme name as a param.');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const c = getBaseConfig();
|
|
63
|
+
c.runtime.scheme = scheme;
|
|
64
|
+
|
|
65
|
+
switch (scheme) {
|
|
66
|
+
case 'dev:latest':
|
|
67
|
+
doLatestDevelopmentRelease(c);
|
|
68
|
+
break;
|
|
69
|
+
case 'rc:latest':
|
|
70
|
+
doLatestReleaseCandidateRelease(c);
|
|
71
|
+
break;
|
|
72
|
+
case 'release:latest':
|
|
73
|
+
doLatestRelease(c);
|
|
74
|
+
break;
|
|
75
|
+
case 'release:dist':
|
|
76
|
+
doDistributionRelease(c);
|
|
77
|
+
break;
|
|
78
|
+
default:
|
|
79
|
+
throw new Error('Unsupported scheme to release!');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
console.log(JSON.stringify(getDeployLocations(c), null, 4));
|
|
83
|
+
return true;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const startTimestamp = Date.now();
|
|
87
|
+
|
|
88
|
+
releaseAllWithScheme()
|
|
89
|
+
|
|
90
|
+
const scriptTotalTimeInSeconds = Math.ceil((Date.now() - startTimestamp) / 1000);
|
|
91
|
+
console.log(`buildAllWithScheme: done in ${scriptTotalTimeInSeconds} second(s)!`);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const { execSync } = require('child_process');
|
|
2
|
+
|
|
3
|
+
const cmdSync = (command, options) => execSync(command, options);
|
|
4
|
+
|
|
5
|
+
const cmdSyncInheritOut = (command) => cmdSync(command, { stdio: 'inherit' });
|
|
6
|
+
|
|
7
|
+
const cmdSyncPipeOut = (command) => cmdSync(command, { stdio: 'pipe' });
|
|
8
|
+
|
|
9
|
+
const cmdSyncTrimOut = (command) => cmdSync(command).toString().trim();
|
|
10
|
+
|
|
11
|
+
module.exports = {
|
|
12
|
+
cmdSync,
|
|
13
|
+
cmdSyncInheritOut,
|
|
14
|
+
cmdSyncPipeOut,
|
|
15
|
+
cmdSyncTrimOut,
|
|
16
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const { ok } = require('assert').strict;
|
|
3
|
+
|
|
4
|
+
const getFileContentAsString = (filePath) => fs.readFileSync(filePath).toString();
|
|
5
|
+
|
|
6
|
+
const assertPath = (path) => {
|
|
7
|
+
const errorMsg = `File or path ${path} does not exist!`;
|
|
8
|
+
ok(fs.existsSync(path), errorMsg);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
module.exports = {
|
|
12
|
+
getFileContentAsString,
|
|
13
|
+
assertPath,
|
|
14
|
+
};
|