cloudron 5.11.8 → 5.11.9

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.
@@ -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.8",
3
+ "version": "5.11.9",
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.24.0",
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",
@@ -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,32 @@ 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
+
374
+ const defaultBranchSha = safe.child_process.execSync(`git rev-parse ${defaultBranch}`, { encoding: 'utf8' });
375
+ if (safe.error) return exit(`Failed to get head of ${defaultBranch}: ${safe.error.message}`);
376
+
377
+ latestTag = safe.child_process.execSync('git describe --tags --abbrev=0', { encoding: 'utf8' });
378
+ if (safe.error) return exit(`Failed to get latest tag: ${safe.error.message}`);
379
+
380
+ const latestTagSha = safe.child_process.execSync(`git rev-list -n 1 ${latestTag}`, { encoding: 'utf8' });
381
+ if (safe.error) return exit(`Failed to get head of ${defaultBranch}: ${safe.error.message}`);
382
+
383
+ if (defaultBranchSha !== latestTagSha) return exit(`Latest tag ${latestTag} does not match HEAD of ${defaultBranch}`);
384
+ }
385
+
369
386
  const response = await createRequest('POST', `/api/v1/developers/apps/${appstoreId}/versions/${version}/approve`, options);
370
387
  if (response.statusCode !== 200) return exit(`Failed to approve version: ${requestError(response)}`);
371
388
 
389
+ if (options.gitPush) {
390
+ safe.child_process.execSync(`git push --atomic origin ${defaultBranch} ${latestTag}`, { encoding: 'utf8' });
391
+ if (safe.error) return exit(`Failed to get last release tag: ${safe.error.message}`);
392
+ }
393
+
372
394
  console.log('Approved.');
373
395
  console.log('');
374
396
 
@@ -382,68 +404,6 @@ async function approve(localOptions, cmd) {
382
404
  console.log('');
383
405
  }
384
406
 
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
407
  // https://docs.nodebb.org/api/read/
448
408
  // https://docs.nodebb.org/api/write/
449
409
  async function notify() {