cloudron 5.10.0 → 5.11.1
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 +2 -1
- package/bin/cloudron-repo +18 -0
- package/package.json +1 -1
- package/src/repo-actions.js +100 -0
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
|
-
//
|
|
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
|
@@ -0,0 +1,100 @@
|
|
|
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
|
+
const branch = safe.child_process.execSync('git branch --show-current', { encoding: 'utf8' }); // master or main
|
|
71
|
+
if (safe.error) return exit('Could not determine branch name');
|
|
72
|
+
|
|
73
|
+
execSync(`git commit -a -m 'Version ${version}'`);
|
|
74
|
+
execSync(`git tag v${version} -a -m 'Version ${version}'`);
|
|
75
|
+
execSync(`git push origin v${version} ${branch}`); // push this tag only. in CI, we might have a git cache
|
|
76
|
+
if (safe.error) return exit(`Failed to push tag v${version} and branch ${branch}: ${safe.error.message}`);
|
|
77
|
+
|
|
78
|
+
console.log('Created tag and pushed to git');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function publish(options) {
|
|
82
|
+
const manifestFilePath = locateManifest();
|
|
83
|
+
if (!manifestFilePath) return exit('Could not locate CloudronManifest.json');
|
|
84
|
+
|
|
85
|
+
const latestRenovateCommit = safe.child_process.execSync('git log -n 1 --committer=renovatebot@cloudron.io --pretty="format:%h,%aI,%s"', { encoding: 'utf8' });
|
|
86
|
+
if (!latestRenovateCommit) return exit('Could not find a commit from renovate bot');
|
|
87
|
+
|
|
88
|
+
const [ abbrevHash, commitDate ] = latestRenovateCommit.split(',');
|
|
89
|
+
const cleanDate = commitDate.replace(/T.*/, '').replace(/[-]/g, '');
|
|
90
|
+
const repoDir = path.dirname(manifestFilePath);
|
|
91
|
+
const repoName = path.basename(repoDir).replace('-app', '');
|
|
92
|
+
const dockerImage = options.image || `cloudron/${repoName}:${cleanDate}-${abbrevHash}`;
|
|
93
|
+
|
|
94
|
+
safe.child_process.execSync(`cloudron appstore upload --image ${dockerImage}`);
|
|
95
|
+
if (safe.error) return exit(`Failed to publish image to appstore: ${safe.error.message}`);
|
|
96
|
+
execSync(`cloudron appstore submit`);
|
|
97
|
+
execSync(`cloudron appstore approve`);
|
|
98
|
+
|
|
99
|
+
console.log('Published to appstore');
|
|
100
|
+
}
|