cloudron 8.1.1 → 8.1.2
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 +8 -0
- package/package.json +4 -4
- package/src/appstore-actions.js +38 -9
package/bin/cloudron
CHANGED
|
@@ -29,6 +29,14 @@ program.option('--server <server>', 'Cloudron domain')
|
|
|
29
29
|
const appstoreCommand = program.command('appstore').description('Commands for publishing to the Appstore')
|
|
30
30
|
.option('--appstore-token <token>', 'AppStore token');
|
|
31
31
|
|
|
32
|
+
appstoreCommand.command('login')
|
|
33
|
+
.description('Login to the appstore')
|
|
34
|
+
.action(appstoreActions.login);
|
|
35
|
+
|
|
36
|
+
appstoreCommand.command('logout')
|
|
37
|
+
.description('Logout from the appstore')
|
|
38
|
+
.action(appstoreActions.logout);
|
|
39
|
+
|
|
32
40
|
appstoreCommand.command('info')
|
|
33
41
|
.description('List info of published app')
|
|
34
42
|
.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": "8.1.
|
|
3
|
+
"version": "8.1.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Cloudron Commandline Tool",
|
|
6
6
|
"type": "module",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"commander": "^14.0.3",
|
|
24
24
|
"debug": "^4.4.3",
|
|
25
25
|
"easy-table": "^1.2.0",
|
|
26
|
-
"ejs": "^5.0.
|
|
26
|
+
"ejs": "^5.0.2",
|
|
27
27
|
"eventsource": "^4.1.0",
|
|
28
28
|
"micromatch": "^4.0.8",
|
|
29
29
|
"open": "^11.0.0",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@eslint/js": "^10.0.1",
|
|
38
|
-
"eslint": "^10.0
|
|
39
|
-
"globals": "^17.
|
|
38
|
+
"eslint": "^10.2.0",
|
|
39
|
+
"globals": "^17.5.0",
|
|
40
40
|
"mocha": "^11.7.5"
|
|
41
41
|
}
|
|
42
42
|
}
|
package/src/appstore-actions.js
CHANGED
|
@@ -2,7 +2,7 @@ import assert from 'assert';
|
|
|
2
2
|
import * as config from './config.js';
|
|
3
3
|
import { execSync } from 'child_process';
|
|
4
4
|
import fs from 'fs';
|
|
5
|
-
import { exit, locateManifest, parseChangelog } from './helper.js';
|
|
5
|
+
import { exit, locateManifest, parseChangelog, performOidcLogin } from './helper.js';
|
|
6
6
|
import manifestFormat from '@cloudron/manifest-format';
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import safe from '@cloudron/safetydance';
|
|
@@ -14,7 +14,7 @@ const NO_MANIFEST_FOUND_ERROR_STRING = 'No CloudronManifest.json found';
|
|
|
14
14
|
function requestError(response) {
|
|
15
15
|
if (response.status === 401) return 'Invalid token.';
|
|
16
16
|
|
|
17
|
-
return `${response.status} message: ${response.body?.message ||
|
|
17
|
+
return `${response.status} message: ${response.body?.message || JSON.stringify(response.body)}`;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
function createRequest(method, apiPath, options) {
|
|
@@ -392,38 +392,67 @@ async function notify() {
|
|
|
392
392
|
|
|
393
393
|
if (!manifest.forumUrl) return exit(new Error('CloudronManifest.json does not have a forumUrl'));
|
|
394
394
|
const categoryMatch = manifest.forumUrl.match(/category\/(.*)\//);
|
|
395
|
-
if (!categoryMatch) return exit(
|
|
395
|
+
if (!categoryMatch) return exit(`Unable to detect category id from forumUrl: ${manifest.forumUrl}`);
|
|
396
396
|
const categoryId = categoryMatch[1];
|
|
397
397
|
|
|
398
|
+
console.log(`[notify] appId: ${manifest.id} version: ${manifest.version} forumUrl: ${manifest.forumUrl} categoryId: ${categoryId}`);
|
|
399
|
+
|
|
398
400
|
const categoryResponse = await superagent.get(`https://forum.cloudron.io/api/v3/categories/${categoryId}/topics`).set('Authorization', `Bearer ${apiToken}`).ok(() => true);
|
|
399
|
-
if (categoryResponse.status !== 200) return exit(`Unable to get topics of category: ${requestError(categoryResponse)}`);
|
|
400
|
-
|
|
401
|
+
if (categoryResponse.status !== 200) return exit(`Unable to get topics of category (status ${categoryResponse.status}): ${requestError(categoryResponse)}`);
|
|
402
|
+
|
|
403
|
+
const allTopics = categoryResponse.body.response.topics;
|
|
404
|
+
console.log(`[notify] Got ${allTopics.length} topics in category. Titles: ${allTopics.map(t => t.title).join(', ')}`);
|
|
405
|
+
|
|
406
|
+
const topic = allTopics.find(t => t.title.toLowerCase().includes('package updates'));
|
|
401
407
|
if (!topic) return exit('Could not find the Package Update topic');
|
|
402
408
|
const topicId = topic.tid;
|
|
409
|
+
console.log(`[notify] Found "Package Updates" topic tid: ${topicId}`);
|
|
403
410
|
|
|
404
411
|
const pageCountResponse = await superagent.get(`https://forum.cloudron.io/api/topic/pagination/${topicId}`).set('Authorization', `Bearer ${apiToken}`).ok(() => true);
|
|
405
|
-
if (pageCountResponse.status !== 200) return exit(`Unable to get page count of topic: ${requestError(pageCountResponse)}`);
|
|
412
|
+
if (pageCountResponse.status !== 200) return exit(`Unable to get page count of topic (status ${pageCountResponse.status}): ${requestError(pageCountResponse)}`);
|
|
406
413
|
const pageCount = pageCountResponse.body.pagination.pageCount;
|
|
414
|
+
console.log(`[notify] Topic has ${pageCount} pages to scan for duplicates`);
|
|
407
415
|
|
|
408
416
|
for (let page = 1; page <= pageCount; page++) {
|
|
409
417
|
const pageResponse = await superagent.get(`https://forum.cloudron.io/api/topic/${topicId}?page=${page}`).set('Authorization', `Bearer ${apiToken}`).ok(() => true);
|
|
410
|
-
if (pageResponse.status !== 200) return exit(`Unable to get
|
|
411
|
-
|
|
418
|
+
if (pageResponse.status !== 200) return exit(`Unable to get posts of topic page ${page} (status ${pageResponse.status}): ${requestError(pageResponse)}`);
|
|
419
|
+
console.log(`[notify] Page ${page}/${pageCount}: ${pageResponse.body.posts.length} posts`);
|
|
420
|
+
for (const post of pageResponse.body.posts) {
|
|
412
421
|
if (post.content.includes(`[${manifest.version}]`)) return exit(`Version ${manifest.version} is already on the forum.\n${post.content}`);
|
|
413
422
|
}
|
|
414
423
|
}
|
|
415
424
|
|
|
425
|
+
console.log(`[notify] No duplicate found, posting version ${manifest.version}`);
|
|
426
|
+
|
|
416
427
|
// https://docs.nodebb.org/api/write/#tag/topics/paths/~1topics~1%7Btid%7D/post
|
|
417
428
|
const postData = {
|
|
418
429
|
content: postContent,
|
|
419
430
|
toPid: 0 // which post is this post a reply to
|
|
420
431
|
};
|
|
421
432
|
const postResponse = await superagent.post(`https://forum.cloudron.io/api/v3/topics/${topicId}`).set('Authorization', `Bearer ${apiToken}`).send(postData).ok(() => true);
|
|
422
|
-
if (postResponse.status !== 200) return exit(`Unable to create changelog post: ${requestError(postResponse)}`);
|
|
433
|
+
if (postResponse.status !== 200) return exit(`Unable to create changelog post (status ${postResponse.status}): ${requestError(postResponse)}`);
|
|
423
434
|
console.log('Posted to forum');
|
|
424
435
|
}
|
|
425
436
|
|
|
437
|
+
async function login() {
|
|
438
|
+
const origin = config.appStoreOrigin();
|
|
439
|
+
const consoleFqdn = origin.replace('https://', '').replace('api.', 'console.') + '/openid';
|
|
440
|
+
|
|
441
|
+
const token = await performOidcLogin(consoleFqdn);
|
|
442
|
+
if (!token) process.exit(1);
|
|
443
|
+
|
|
444
|
+
config.setAppStoreToken(token);
|
|
445
|
+
console.log('Login successful.');
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
function logout() {
|
|
449
|
+
config.setAppStoreToken(null);
|
|
450
|
+
console.log('Logged out.');
|
|
451
|
+
}
|
|
452
|
+
|
|
426
453
|
export default {
|
|
454
|
+
login,
|
|
455
|
+
logout,
|
|
427
456
|
info,
|
|
428
457
|
listVersions,
|
|
429
458
|
submit,
|