cloudron 5.11.8 → 5.11.10
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/bin/cloudron-appstore +1 -4
- package/package.json +2 -2
- package/src/appstore-actions.js +28 -64
package/bin/cloudron-appstore
CHANGED
|
@@ -32,16 +32,13 @@ program.command('info')
|
|
|
32
32
|
program.command('approve')
|
|
33
33
|
.description('Approve a submitted app version')
|
|
34
34
|
.option('--appstore-id <appid@version>', 'Appstore id and version')
|
|
35
|
+
.option('--no-git-push', 'Do not attempt to push to git repo')
|
|
35
36
|
.action(appstoreActions.approve);
|
|
36
37
|
|
|
37
38
|
program.command('notify')
|
|
38
39
|
.description('Notify forum about successful app submission')
|
|
39
40
|
.action(appstoreActions.notify);
|
|
40
41
|
|
|
41
|
-
program.command('tag <version>')
|
|
42
|
-
.description('Tag the repo')
|
|
43
|
-
.action(appstoreActions.tag);
|
|
44
|
-
|
|
45
42
|
program.command('revoke')
|
|
46
43
|
.description('Revoke a published app version')
|
|
47
44
|
.option('--appstore-id <appid@version>', 'Appstore id and version')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cloudron",
|
|
3
|
-
"version": "5.11.
|
|
3
|
+
"version": "5.11.10",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Cloudron Commandline Tool",
|
|
6
6
|
"main": "main.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"author": "Cloudron Developers <support@cloudron.io>",
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"async": "^3.2.5",
|
|
21
|
-
"cloudron-manifestformat": "^5.
|
|
21
|
+
"cloudron-manifestformat": "^5.26.2",
|
|
22
22
|
"commander": "^12.1.0",
|
|
23
23
|
"debug": "^4.3.5",
|
|
24
24
|
"easy-table": "^1.2.0",
|
package/src/appstore-actions.js
CHANGED
|
@@ -25,7 +25,6 @@ exports = module.exports = {
|
|
|
25
25
|
revoke,
|
|
26
26
|
approve,
|
|
27
27
|
|
|
28
|
-
tag,
|
|
29
28
|
notify
|
|
30
29
|
};
|
|
31
30
|
|
|
@@ -305,7 +304,7 @@ async function upload(localOptions, cmd) {
|
|
|
305
304
|
|
|
306
305
|
const [repo, tag] = manifest.dockerImage.split(':');
|
|
307
306
|
const [tagError, tagResponse] = await safe(superagent.get(`https://hub.docker.com/v2/repositories/${repo}/tags/${tag}`).ok(() => true));
|
|
308
|
-
if (tagError || tagResponse.statusCode !== 200) return exit(`Failed to find docker image in dockerhub. check https://hub.docker.com/r/${repo}/tags : ${requestError(tagResponse)}`);
|
|
307
|
+
if (tagError || tagResponse.statusCode !== 200) return exit(`Failed to find docker image in dockerhub. check https://hub.docker.com/r/${repo}/tags : ${tagError || requestError(tagResponse)}`);
|
|
309
308
|
|
|
310
309
|
// ensure the app is known on the appstore side
|
|
311
310
|
const baseDir = path.dirname(manifestFilePath);
|
|
@@ -366,9 +365,36 @@ async function approve(localOptions, cmd) {
|
|
|
366
365
|
|
|
367
366
|
console.log(`Approving ${appstoreId}@${version}`);
|
|
368
367
|
|
|
368
|
+
let defaultBranch, latestTag;
|
|
369
|
+
if (options.gitPush) {
|
|
370
|
+
// Git repo pre-flight checks: checking if latest tag matches latest commit
|
|
371
|
+
defaultBranch = safe.child_process.execSync(`git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'`, { encoding: 'utf8' });
|
|
372
|
+
if (safe.error) return exit(`Failed to get default branch: ${safe.error.message}`);
|
|
373
|
+
defaultBranch = defaultBranch.trim();
|
|
374
|
+
|
|
375
|
+
let defaultBranchSha = safe.child_process.execSync(`git rev-parse ${defaultBranch}`, { encoding: 'utf8' });
|
|
376
|
+
if (safe.error) return exit(`Failed to get head of ${defaultBranch}: ${safe.error.message}`);
|
|
377
|
+
defaultBranchSha = defaultBranchSha.trim();
|
|
378
|
+
|
|
379
|
+
latestTag = safe.child_process.execSync('git describe --tags --abbrev=0', { encoding: 'utf8' });
|
|
380
|
+
if (safe.error) return exit(`Failed to get latest tag: ${safe.error.message}`);
|
|
381
|
+
latestTag = latestTag.trim();
|
|
382
|
+
|
|
383
|
+
let latestTagSha = safe.child_process.execSync(`git rev-list -n 1 ${latestTag}`, { encoding: 'utf8' });
|
|
384
|
+
if (safe.error) return exit(`Failed to get head of ${defaultBranch}: ${safe.error.message}`);
|
|
385
|
+
latestTagSha = latestTagSha.trim();
|
|
386
|
+
|
|
387
|
+
if (defaultBranchSha !== latestTagSha) return exit(`Latest tag ${latestTag} does not match HEAD of ${defaultBranch}`);
|
|
388
|
+
}
|
|
389
|
+
|
|
369
390
|
const response = await createRequest('POST', `/api/v1/developers/apps/${appstoreId}/versions/${version}/approve`, options);
|
|
370
391
|
if (response.statusCode !== 200) return exit(`Failed to approve version: ${requestError(response)}`);
|
|
371
392
|
|
|
393
|
+
if (options.gitPush) {
|
|
394
|
+
safe.child_process.execSync(`git push --atomic origin ${defaultBranch} ${latestTag}`, { encoding: 'utf8' });
|
|
395
|
+
if (safe.error) return exit(`Failed to get last release tag: ${safe.error.message}`);
|
|
396
|
+
}
|
|
397
|
+
|
|
372
398
|
console.log('Approved.');
|
|
373
399
|
console.log('');
|
|
374
400
|
|
|
@@ -382,68 +408,6 @@ async function approve(localOptions, cmd) {
|
|
|
382
408
|
console.log('');
|
|
383
409
|
}
|
|
384
410
|
|
|
385
|
-
async function tag(version) {
|
|
386
|
-
const basename = `${path.basename(process.cwd())}`;
|
|
387
|
-
if (!basename.endsWith('-app')) return exit('Does not look like a app repo. Has to end with -app');
|
|
388
|
-
|
|
389
|
-
if (!semver.valid(version)) return exit(`${version} is not a valid semver`);
|
|
390
|
-
|
|
391
|
-
const latestTag = safe.child_process.execSync('git describe --tags --abbrev=0', { encoding: 'utf8' });
|
|
392
|
-
if (safe.error) return exit(`Failed to get last release tag: ${safe.error.message}`);
|
|
393
|
-
|
|
394
|
-
const manifestFilePath = locateManifest();
|
|
395
|
-
if (!manifestFilePath) return exit('Could not locate CloudronManifest.json');
|
|
396
|
-
|
|
397
|
-
const result = manifestFormat.parseFile(manifestFilePath);
|
|
398
|
-
if (result.error) return exit(new Error(`Invalid CloudronManifest.json: ${result.error.message}`));
|
|
399
|
-
const { manifest } = result;
|
|
400
|
-
|
|
401
|
-
const latestVersion = latestTag.match(/v(.*)/)[1];
|
|
402
|
-
|
|
403
|
-
if (semver.lte(version, latestVersion)) return exit(`${version} is less than or equal to last repo tag ${latestVersion}`);
|
|
404
|
-
if (semver.inc(latestVersion, 'major') !== version
|
|
405
|
-
&& semver.inc(latestVersion, 'minor') !== version
|
|
406
|
-
&& semver.inc(latestVersion, 'patch') !== version) {
|
|
407
|
-
return exit(`${version} is not the next major/minor/patch of last published version ${latestVersion}`);
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
const latestRenovateCommit = safe.child_process.execSync('git log -n 1 --committer=renovatebot@cloudron.io --pretty="format:%h,%aI,%s"', { encoding: 'utf8' });
|
|
411
|
-
if (!latestRenovateCommit) return exit('Could not find a commit from renovate bot');
|
|
412
|
-
|
|
413
|
-
const [ , , commitMessage ] = latestRenovateCommit.split(',');
|
|
414
|
-
const repoDir = path.dirname(manifestFilePath);
|
|
415
|
-
const upstreamVersion = commitMessage.match(/update dependency .* to (.*)/)[1];
|
|
416
|
-
|
|
417
|
-
console.log(`Enter the changelog for ${upstreamVersion}: (press ctrl+D to finish)`);
|
|
418
|
-
const rawChangelog = fs.readFileSync(0, 'utf-8');
|
|
419
|
-
const mdChangelog = rawChangelog.split('\n').map(line => {
|
|
420
|
-
line = line.trim();
|
|
421
|
-
line = line.replace(/[\u{0080}-\u{FFFF}]/gu, ''); // only ascii
|
|
422
|
-
line = line.replace(/^\* /, ''); // replace any "* " in the front
|
|
423
|
-
return line ? `* ${line}` : '';
|
|
424
|
-
}).join('\n');
|
|
425
|
-
const newChangelog = `\n[${version}]\n* Update ${manifest.title} to ${upstreamVersion}\n${mdChangelog}\n`;
|
|
426
|
-
const changelogFile = `${repoDir}/${manifest.changelog.replace('file://', '')}`; // sometimes CHANGELOG, sometimes CHANGELOG.md
|
|
427
|
-
fs.appendFileSync(changelogFile, newChangelog);
|
|
428
|
-
|
|
429
|
-
manifest.version = version;
|
|
430
|
-
manifest.upstreamVersion = upstreamVersion;
|
|
431
|
-
fs.writeFileSync('CloudronManifest.json', JSON.stringify(manifest, null, 2));
|
|
432
|
-
|
|
433
|
-
// git branch --show-current does not work in CI :/
|
|
434
|
-
const mainOrMaster = safe.child_process.execSync('git branch -r --list origin/master origin/main', { encoding: 'utf8' });
|
|
435
|
-
if (safe.error) return exit('Could not determine branch name');
|
|
436
|
-
const branch = mainOrMaster.includes('master') ? 'master' : 'main';
|
|
437
|
-
|
|
438
|
-
execSync(`git commit -a -m 'Version ${version}'`, { encoding: 'utf8' });
|
|
439
|
-
execSync(`git tag v${version} -a -m 'Version ${version}'`, { encoding: 'utf8' });
|
|
440
|
-
console.log(`git push --atomic origin ${branch} v${version}`);
|
|
441
|
-
execSync(`git push --atomic origin HEAD:${branch} v${version}`, { encoding: 'utf8' }); // push this tag only. in CI, we might have a git cache
|
|
442
|
-
if (safe.error) return exit(`Failed to push tag v${version} and branch ${branch}: ${safe.error.message}`, { encoding: 'utf8' });
|
|
443
|
-
|
|
444
|
-
console.log(`Created tag v${version} and pushed branch ${branch}`);
|
|
445
|
-
}
|
|
446
|
-
|
|
447
411
|
// https://docs.nodebb.org/api/read/
|
|
448
412
|
// https://docs.nodebb.org/api/write/
|
|
449
413
|
async function notify() {
|