cloudron 5.9.0 → 5.11.0

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 CHANGED
@@ -36,8 +36,9 @@ program.option('--server <server>', 'Cloudron domain')
36
36
  .option('--allow-selfsigned', 'Accept self signed SSL certificate')
37
37
  .option('--accept-selfsigned', 'Accept self signed SSL certificate');
38
38
 
39
- // this is a separate binary since global options are not applicable
39
+ // these are separate binaries since global options are not applicable
40
40
  program.command('appstore', 'Cloudron appstore commands');
41
+ program.command('repo', 'Cloudron repo commands');
41
42
 
42
43
  const backupCommand = program.command('backup')
43
44
  .description('App backup commands');
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+
3
+ 'use strict';
4
+
5
+ const { program } = require('commander'),
6
+ repoActions = require('../src/repo-actions.js');
7
+
8
+ program.version(require('../package.json').version);
9
+
10
+ program.command('tag <version>')
11
+ .description('Creates a new release with given tag')
12
+ .action(repoActions.tag);
13
+
14
+ program.command('publish')
15
+ .description('Publish to appstore')
16
+ .action(repoActions.publish);
17
+
18
+ program.parse(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudron",
3
- "version": "5.9.0",
3
+ "version": "5.11.0",
4
4
  "license": "MIT",
5
5
  "description": "Cloudron Commandline Tool",
6
6
  "main": "main.js",
@@ -72,7 +72,7 @@ async function authenticate(options) {
72
72
 
73
73
  config.setAppStoreToken(null);
74
74
 
75
- const response = await superagent.post(createUrl('/api/v1/login')).auth(email, password).send({ totpToken: options.totpToken });
75
+ const response = await superagent.post(createUrl('/api/v1/login')).auth(email, password).send({ totpToken: options.totpToken }).ok(() => true);
76
76
  if (response.statusCode === 401 && response.body.message.indexOf('TOTP') !== -1) {
77
77
  if (response.body.message === 'TOTP token missing') console.log('A 2FA TOTP Token is required for this account.');
78
78
 
@@ -323,7 +323,7 @@ function build(options) {
323
323
  url = readlineSync.question('Enter build service URL: ', { });
324
324
  }
325
325
 
326
- if (!url.startsWith('https://')) url = `https://${url}`;
326
+ if (url.indexOf('://') === -1) url = `https://${url}`;
327
327
  buildService.url = url;
328
328
  }
329
329
 
@@ -0,0 +1,97 @@
1
+ /* jshint node:true */
2
+
3
+ 'use strict';
4
+
5
+ const { exit, locateManifest } = require('./helper.js'),
6
+ execSync = require('child_process').execSync,
7
+ fs = require('fs'),
8
+ manifestFormat = require('cloudron-manifestformat'),
9
+ path = require('path'),
10
+ safe = require('safetydance'),
11
+ semver = require('semver');
12
+
13
+ exports = module.exports = {
14
+ tag,
15
+ publish
16
+ };
17
+
18
+ async function tag(version, options) {
19
+ const basename = `${path.basename(process.cwd())}`;
20
+ if (!basename.endsWith('-app')) return exit('Does not look like a app repo. Has to end with -app');
21
+
22
+ if (!semver.valid(version)) return exit(`${version} is not a valid semver`);
23
+
24
+ const latestTag = safe.child_process.execSync('git describe --tags --abbrev=0', { encoding: 'utf8' });
25
+ if (safe.error) return exit(`Failed to get last release tag: ${safe.error.message}`);
26
+
27
+ const manifestFilePath = locateManifest();
28
+ if (!manifestFilePath) return exit('Could not locate CloudronManifest.json');
29
+
30
+ const latestVersion = latestTag.match(/v(.*)/)[1];
31
+
32
+ if (semver.lte(version, latestVersion)) return exit(`${version} is less than or equal to last repo tag ${latestVersion}`);
33
+ if (semver.inc(latestVersion, 'major') !== version
34
+ && semver.inc(latestVersion, 'minor') !== version
35
+ && semver.inc(latestVersion, 'patch') !== version) {
36
+ return exit(`${version} is not the next major/minor/patch of last published version ${latestVersion}`);
37
+ }
38
+
39
+ const latestRenovateCommit = safe.child_process.execSync('git log -n 1 --committer=renovatebot@cloudron.io --pretty="format:%h,%aI,%s"', { encoding: 'utf8' });
40
+ if (!latestRenovateCommit) return exit('Could not find a commit from renovate bot');
41
+
42
+ const [ abbrevHash, commitDate, commitMessage ] = latestRenovateCommit.split(',');
43
+ const cleanDate = commitDate.replace(/T.*/, '').replace(/[-]/g, '');
44
+ const repoDir = path.dirname(manifestFilePath);
45
+ const repoName = path.basename(repoDir).replace('-app', '');
46
+ const dockerImage = options.image || `cloudron/${repoName}:${cleanDate}-${abbrevHash}`;
47
+ const upstreamVersion = commitMessage.match(/update dependency .* to (.*)/)[1];
48
+
49
+ const result = manifestFormat.parseFile(manifestFilePath);
50
+ if (result.error) throw new Error(`Invalid CloudronManifest.json: ${result.error.message}`);
51
+ const { manifest } = result;
52
+
53
+ console.log(`Enter the changelog for ${upstreamVersion}: (press ctrl+D to finish)`);
54
+ const rawChangelog = fs.readFileSync(0, 'utf-8');
55
+ const mdChangelog = rawChangelog.split('\n').map(line => {
56
+ line = line.trim();
57
+ line = line.replace(/[\u{0080}-\u{FFFF}]/gu, ''); // only ascii
58
+ line = line.replace(/^\* /, ''); // replace any "* " in the front
59
+ return line ? `* ${line}` : '';
60
+ }).join('\n');
61
+ const newChangelog = `\n[${version}]\n* Update ${manifest.title} to ${upstreamVersion}\n${mdChangelog}\n`;
62
+ const changelogFile = `${repoDir}/${manifest.changelog.replace('file://', '')}`; // sometimes CHANGELOG, sometimes CHANGELOG.md
63
+ fs.appendFileSync(changelogFile, newChangelog);
64
+
65
+ manifest.version = version;
66
+ manifest.upstreamVersion = upstreamVersion;
67
+ fs.writeFileSync('CloudronManifest.json', JSON.stringify(manifest, null, 2));
68
+
69
+ // set GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL if needed
70
+ execSync(`git commit -a -m 'Version ${version}'`);
71
+ execSync(`git tag v${version} -a -m 'Version ${version}'`);
72
+ safe.child_process.execSync('git push --tags origin');
73
+ if (safe.error) return exit(`Failed to push tag and commits: ${safe.error.message}`);
74
+
75
+ console.log('Created tag and pushed to git');
76
+ }
77
+
78
+ async function publish(options) {
79
+ const manifestFilePath = locateManifest();
80
+ if (!manifestFilePath) return exit('Could not locate CloudronManifest.json');
81
+
82
+ const latestRenovateCommit = safe.child_process.execSync('git log -n 1 --committer=renovatebot@cloudron.io --pretty="format:%h,%aI,%s"', { encoding: 'utf8' });
83
+ if (!latestRenovateCommit) return exit('Could not find a commit from renovate bot');
84
+
85
+ const [ abbrevHash, commitDate ] = latestRenovateCommit.split(',');
86
+ const cleanDate = commitDate.replace(/T.*/, '').replace(/[-]/g, '');
87
+ const repoDir = path.dirname(manifestFilePath);
88
+ const repoName = path.basename(repoDir).replace('-app', '');
89
+ const dockerImage = options.image || `cloudron/${repoName}:${cleanDate}-${abbrevHash}`;
90
+
91
+ safe.child_process.execSync(`cloudron appstore upload --image ${dockerImage}`);
92
+ if (safe.error) return exit(`Failed to publish image to appstore: ${safe.error.message}`);
93
+ execSync(`cloudron appstore submit`);
94
+ execSync(`cloudron appstore approve`);
95
+
96
+ console.log('Published to appstore');
97
+ }