cloudmason2 2.0.0 → 2.0.202609012352

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.
@@ -185,10 +185,14 @@ class MasonApp extends ELMNT
185
185
 
186
186
  static VersionRow(v){
187
187
  const mm = v.version.split('.').slice(0, 2).join('.');
188
+ // Buyers upgrade with upgrade.yaml. Older manifests predate upgrade_url,
189
+ // so fall back to deriving it from stack_url (publish guarantees it exists
190
+ // for every published version)
191
+ const url = v.upgrade_url || (v.stack_url || '').replace(/stack\.yaml$/, 'upgrade.yaml');
188
192
  return `<div class="row">
189
193
  <span class="ver">v${mm}<span class="full">${v.version}</span></span>
190
194
  <span class="date">${MasonApp.#FormatDate(v.publish_date)}</span>
191
- <button class="copy" data-url="${v.stack_url || ''}" aria-label="Copy Cloudformation Stack URL">
195
+ <button class="copy" data-url="${url}" aria-label="Copy Cloudformation Stack URL">
192
196
  <svg class="ic-copy" viewBox="0 0 32 32" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z"/><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z"/></svg>
193
197
  <svg class="ic-check" viewBox="0 0 32 32" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M13 24l-9-9 1.41-1.41L13 21.17 26.59 7.59 28 9 13 24z"/></svg>
194
198
  </button>
@@ -31,6 +31,38 @@ exports.main = async function(args){
31
31
  const fullVersion = version.version;
32
32
  const vFolder = fullVersion.split('.').slice(0, 2).join('.'); // storage folder is major.minor
33
33
 
34
+ // --- REPAIR MODE ---
35
+ // -repair [true|false]: rebuild upgrade.yaml from the current stack and set the
36
+ // manifest published flag (default true), without contacting the marketplace
37
+ if (args.repair !== undefined){
38
+ if (args.repair !== null && args.repair !== 'true' && args.repair !== 'false'){
39
+ throw new Error('-repair accepts true or false');
40
+ }
41
+ const publishedValue = args.repair !== 'false';
42
+ if (!manifest.productId){ throw new Error('Missing productId in manifest. Run update-listing -pid') }
43
+
44
+ const rStackKey = `${appPrefix}/versions/${vFolder}/stack.yaml`;
45
+ const rStackText = await getFileText(s3, bucket, rStackKey);
46
+ if (rStackText === null){ throw new Error('No stack found for v' + fullVersion) }
47
+ const rAlias = `resolve:ssm:/aws/service/marketplace/${manifest.productId}/${fullVersion.toLowerCase()}`;
48
+ const rUpgradeKey = `${appPrefix}/versions/${vFolder}/upgrade.yaml`;
49
+ await s3.send(new PutObjectCommand({
50
+ Bucket: bucket,
51
+ Key: rUpgradeKey,
52
+ Body: buildUpgradeTemplate(rStackText, rAlias),
53
+ ContentType: Mime.contentType(rUpgradeKey)
54
+ }));
55
+ console.log(`Rebuilt upgrade template s3://${bucket}/${rUpgradeKey}`);
56
+
57
+ version.published = publishedValue;
58
+ version.upgrade_url = `https://${bucket}.s3.${cfg.region}.amazonaws.com/${rUpgradeKey}`;
59
+ if (publishedValue && !version.publish_date){ version.publish_date = new Date().toISOString() }
60
+ await putManifest(s3, bucket, appPrefix, manifest);
61
+ console.log(`Set published: ${publishedValue} for v${fullVersion}`);
62
+ return true;
63
+ }
64
+ if (!args.desc){ throw new Error('Missing required arg desc') }
65
+
34
66
  // --- I CHECK REQUIRED FIELDS ---
35
67
  const role = await getMarketplaceRole(bucket);
36
68
  if (!role){ throw new Error('No marketplace access role found for this CDN. Run create-cdn first') }
@@ -116,6 +148,7 @@ exports.main = async function(args){
116
148
  if (version.published !== true){
117
149
  version.published = true;
118
150
  version.publish_date = new Date().toISOString();
151
+ version.upgrade_url = `https://${bucket}.s3.${cfg.region}.amazonaws.com/${upgradeKey}`;
119
152
  await putManifest(s3, bucket, appPrefix, manifest);
120
153
  console.log(`Marked v${version.version} published in manifest`);
121
154
  } else {
package/main.js CHANGED
@@ -85,9 +85,10 @@ const Commands = {
85
85
  exec: require('./commands/publish').main,
86
86
  args: [
87
87
  {n: 'app', desc: 'Name of existing app', pattern: `^[A-Za-z]{2,20}$`, r: true},
88
- {n: 'desc', desc: 'Description of Changes', r: true},
88
+ {n: 'desc', desc: 'Description of Changes (required except with -repair)', r: false},
89
89
  {n: 'v', desc: 'Version to launch', pattern: `[0-9]{1,20}`, r: true},
90
- {n: 'await', desc: 'Wait for marketplace processing to complete (up to 90m)', r: false}
90
+ {n: 'await', desc: 'Wait for marketplace processing to complete (up to 90m)', r: false},
91
+ {n: 'repair', desc: 'Rebuild upgrade.yaml and set published true/false (default true) without contacting the marketplace', pattern: `^true$|^false$`, r: false}
91
92
  ]
92
93
  },
93
94
  /////
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudmason2",
3
- "version": "2.0.0",
3
+ "version": "2.0.202609012352",
4
4
  "description": "",
5
5
  "main": "main.js",
6
6
  "files": [