@payfit/nx-core 5.3.0-ephemeral-labels-executor.0 → 5.3.0-ephemeral-labels-executor.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.
Files changed (27) hide show
  1. package/dist/src/executors/publisher/frontend.js +2 -1
  2. package/dist/src/executors/publisher/frontend.js.map +1 -1
  3. package/dist/src/executors/publisher/helm.js +3 -5
  4. package/dist/src/executors/publisher/helm.js.map +1 -1
  5. package/dist/src/executors/publisher/lambda.js +1 -1
  6. package/dist/src/executors/publisher/lambda.js.map +1 -1
  7. package/dist/src/generators/local-lambda-setup/files/docker-compose/docker-compose.yml.template +21 -0
  8. package/dist/src/generators/local-lambda-setup/files/scripts/invoke_lambda_local.sh.template +97 -0
  9. package/dist/src/generators/local-lambda-setup/local-lambda-setup.d.ts +25 -0
  10. package/dist/src/generators/local-lambda-setup/local-lambda-setup.js +167 -0
  11. package/dist/src/generators/local-lambda-setup/local-lambda-setup.js.map +1 -0
  12. package/dist/src/generators/local-lambda-setup/schema.json +24 -0
  13. package/dist/src/scripts/nx-core-updater.js +311 -60
  14. package/dist/src/utils/common/oci.d.ts +17 -3
  15. package/dist/src/utils/common/oci.js +36 -4
  16. package/dist/src/utils/common/oci.js.map +1 -1
  17. package/dist/src/utils/common/octokit.js +1 -1
  18. package/dist/src/utils/common/octokit.js.map +1 -1
  19. package/dist/src/utils/helm.d.ts +1 -1
  20. package/dist/src/utils/helm.js +8 -3
  21. package/dist/src/utils/helm.js.map +1 -1
  22. package/dist/src/utils/spacelift/lib/__generated__/gql.js +1 -1
  23. package/dist/src/utils/spacelift/lib/__generated__/graphql.d.ts +4 -4
  24. package/dist/src/utils/spacelift/lib/__generated__/graphql.js +3 -3
  25. package/dist/src/utils/spacelift/lib/__generated__/graphql.js.map +1 -1
  26. package/generators.json +5 -0
  27. package/package.json +3 -2
@@ -7,8 +7,17 @@ const { promisify } = require('util')
7
7
 
8
8
  const execAsync = promisify(exec)
9
9
 
10
- // Configuration
11
- const NX_CORE_VERSION = '4.60.1'
10
+ // Configuration (can be overridden via CLI flags)
11
+ const NX_CORE_VERSION = '5.2.4'
12
+ const NX_VERSION = '22.0.2' // e.g. '21.3.11'
13
+ const CHANGELOG_MODE = 'combined' // 'combined' | 'raw'
14
+
15
+ // Read optional Jira ticket URL from env only
16
+ const JIRA_TICKET_URL = undefined
17
+
18
+ // Collect PR URLs created during this run
19
+ const CREATED_PR_URLS = []
20
+
12
21
  const REPOSITORIES = [
13
22
  'authorization',
14
23
  'company-lifecycle',
@@ -22,6 +31,7 @@ const REPOSITORIES = [
22
31
  'jetlang',
23
32
  'organization-structure',
24
33
  'payfit-domains',
34
+ 'payroll',
25
35
  'talent-management',
26
36
  'time-absences',
27
37
  ]
@@ -68,117 +78,208 @@ async function run(command, cwd = process.cwd()) {
68
78
  }
69
79
  }
70
80
 
71
- // Check if package.json exists and needs update
72
- async function needsUpdate(repoPath) {
81
+ // Check if @payfit/nx-core in package.json needs update
82
+ async function needsNxCoreUpdate(repoPath) {
73
83
  try {
74
84
  const packageJsonPath = path.join(repoPath, 'package.json')
75
85
  const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'))
76
86
  const currentVersion = packageJson.devDependencies?.['@payfit/nx-core']
77
87
 
78
88
  if (!currentVersion) {
79
- console.log(` ℹ @payfit/nx-core not found in devDependencies`)
89
+ console.log(`ℹ @payfit/nx-core not found in devDependencies`)
80
90
  return { needsUpdate: false, currentVersion: null }
81
91
  }
82
92
 
83
93
  if (compareVersions(currentVersion, NX_CORE_VERSION) === 0) {
84
- console.log(` ℹ Already on version ${NX_CORE_VERSION}`)
94
+ console.log(`ℹ Already on version ${NX_CORE_VERSION}`)
95
+ return { needsUpdate: false, currentVersion }
96
+ }
97
+
98
+ console.log(
99
+ `📦 Current version: ${currentVersion}, target: ${NX_CORE_VERSION}`,
100
+ )
101
+ return { needsUpdate: true, currentVersion }
102
+ } catch (error) {
103
+ console.error(`❌ Could not read package.json: ${error.message}`)
104
+ return { needsUpdate: false, currentVersion: null }
105
+ }
106
+ }
107
+
108
+ // Check if Nx in package.json needs update
109
+ async function needsNxUpdate(repoPath) {
110
+ if (!NX_VERSION) {
111
+ return { needsUpdate: false, currentVersion: null }
112
+ }
113
+ try {
114
+ const packageJsonPath = path.join(repoPath, 'package.json')
115
+ const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'))
116
+ const currentVersion =
117
+ packageJson.devDependencies?.['nx'] ?? packageJson.dependencies?.['nx']
118
+
119
+ if (!currentVersion) {
120
+ console.log(`ℹ nx not found in package.json`)
121
+ return { needsUpdate: false, currentVersion: null }
122
+ }
123
+
124
+ if (compareVersions(currentVersion, NX_VERSION) === 0) {
125
+ console.log(`ℹ Nx already on version ${NX_VERSION}`)
85
126
  return { needsUpdate: false, currentVersion }
86
127
  }
87
128
 
88
129
  console.log(
89
- ` 📦 Current version: ${currentVersion}, target: ${NX_CORE_VERSION}`,
130
+ `📦 Nx current version: ${currentVersion}, target: ${NX_VERSION}`,
90
131
  )
91
132
  return { needsUpdate: true, currentVersion }
92
133
  } catch (error) {
93
- console.error(` ❌ Could not read package.json: ${error.message}`)
134
+ console.error(`❌ Could not read package.json for Nx: ${error.message}`)
94
135
  return { needsUpdate: false, currentVersion: null }
95
136
  }
96
137
  }
97
138
 
98
139
  // Process a single repository
99
140
  async function processRepo(repoName) {
100
- console.log(`\n🚀 Processing ${repoName}`)
141
+ console.log(`🚀 Processing ${repoName}`)
101
142
 
102
143
  const repoPath = path.join(WORK_DIR, repoName)
103
144
 
104
145
  try {
105
146
  // Clone repo
106
- console.log(` 📥 Cloning repository...`)
147
+ console.log(`📥 Cloning repository...`)
107
148
  await run(
108
149
  `git clone https://github.com/PayFit/${repoName}.git ${repoPath}`,
109
150
  WORK_DIR,
110
151
  )
111
152
 
112
- // Check if update needed
113
- const updateInfo = await needsUpdate(repoPath)
114
- if (!updateInfo.needsUpdate) {
115
- console.log(` ⏭️ Skipping ${repoName} - no update needed`)
153
+ // Check if updates needed
154
+ const [nxCoreUpdateInfo, nxUpdateInfo] = await Promise.all([
155
+ needsNxCoreUpdate(repoPath),
156
+ needsNxUpdate(repoPath),
157
+ ])
158
+ if (!nxCoreUpdateInfo.needsUpdate && !nxUpdateInfo.needsUpdate) {
159
+ console.log(`⏭️ Skipping ${repoName} - no update needed`)
116
160
  return
117
161
  }
118
162
 
119
- // Get changelogs between current and target version
120
- const releaseNotes = await getChangelogBetweenVersions(
121
- updateInfo.currentVersion,
122
- NX_CORE_VERSION,
123
- )
163
+ // Get changelogs between current and target version (nx-core only)
164
+ const releaseNotes = nxCoreUpdateInfo.needsUpdate
165
+ ? await getChangelogBetweenVersions(
166
+ nxCoreUpdateInfo.currentVersion,
167
+ NX_CORE_VERSION,
168
+ )
169
+ : ''
124
170
 
125
171
  // Create branch
126
- const branchName = `nx-core-v${NX_CORE_VERSION}`
127
- console.log(` 🌿 Creating branch ${branchName}`)
172
+ const branchNameParts = []
173
+ if (nxCoreUpdateInfo.needsUpdate)
174
+ branchNameParts.push(`nx-core-v${NX_CORE_VERSION}`)
175
+ if (nxUpdateInfo.needsUpdate) branchNameParts.push(`nx-v${NX_VERSION}`)
176
+ const branchName = branchNameParts.join('-') || `nx-maintenance`
177
+ console.log(`🌿 Creating branch ${branchName}`)
128
178
  await run('git checkout main', repoPath)
129
179
  await run(`git checkout -b ${branchName}`, repoPath)
130
180
 
131
181
  // Install dependencies and migrate
132
- console.log(` 📦 Installing dependencies...`)
182
+ console.log(`📦 Installing dependencies...`)
133
183
  await run('yarn', repoPath)
134
184
 
135
- console.log(` 🔄 Migrating nx-core to version ${NX_CORE_VERSION}...`)
136
- await run(`yarn nx migrate '@payfit/nx-core@${NX_CORE_VERSION}'`, repoPath)
185
+ // Plan migrations
186
+ if (nxUpdateInfo.needsUpdate) {
187
+ console.log(`🔄 Planning Nx migration to version ${NX_VERSION}...`)
188
+ await run(`yarn nx migrate 'nx@${NX_VERSION}'`, repoPath)
189
+ }
190
+ if (nxCoreUpdateInfo.needsUpdate) {
191
+ console.log(
192
+ `🔄 Planning nx-core migration to version ${NX_CORE_VERSION}...`,
193
+ )
194
+ await run(
195
+ `yarn nx migrate '@payfit/nx-core@${NX_CORE_VERSION}'`,
196
+ repoPath,
197
+ )
198
+ }
137
199
 
138
- console.log(` 📦 Installing dependencies after migration...`)
200
+ console.log(`📦 Installing dependencies after migration...`)
139
201
  await run('yarn', repoPath)
140
202
 
141
- console.log(` 📦 Run migrations...`)
203
+ console.log(`📦 Run migrations...`)
142
204
  await run(`yarn nx migrate --run-migrations --ifExists`, repoPath)
143
205
 
206
+ // If targeting Nx >= 22, ensure nx.json release.version.updateDependents = "auto"
207
+ if (nxUpdateInfo.needsUpdate && NX_VERSION) {
208
+ const major = parseInt(extractVersion(NX_VERSION).split('.')[0], 10) || 0
209
+ if (major >= 22) {
210
+ console.log(
211
+ `🔧 Ensuring nx.json has release.version.updateDependents = "auto" for Nx >= 22...`,
212
+ )
213
+ const nxJsonChanged = await ensureUpdateDependentsAuto(repoPath)
214
+ if (nxJsonChanged) {
215
+ console.log('🧹 Formatting workspace (npx nx format)...')
216
+ await run('npx nx format', repoPath)
217
+ }
218
+ }
219
+ }
220
+
144
221
  // Stage, commit and push
145
- console.log(` 📝 Staging and committing changes...`)
222
+ console.log(`📝 Staging and committing changes...`)
146
223
  await run('git add .', repoPath)
147
- await run(
148
- `git commit -m "chore(nx-core): update nx-core from ${updateInfo.currentVersion} to ${NX_CORE_VERSION}"`,
149
- repoPath,
150
- )
151
- await run(`git push origin ${branchName}`, repoPath)
224
+ const commitParts = []
225
+ if (nxUpdateInfo.needsUpdate) {
226
+ commitParts.push(
227
+ `chore(nx): update Nx from ${nxUpdateInfo.currentVersion} to ${NX_VERSION}`,
228
+ )
229
+ }
230
+ if (nxCoreUpdateInfo.needsUpdate) {
231
+ commitParts.push(
232
+ `chore(nx-core): update nx-core from ${nxCoreUpdateInfo.currentVersion} to ${NX_CORE_VERSION}`,
233
+ )
234
+ }
235
+ const commitMessage = commitParts.join('')
236
+ await run(`git commit -m ${JSON.stringify(commitMessage)}`, repoPath)
237
+ await run(`git push -q origin ${branchName}`, repoPath)
152
238
 
153
239
  // Create PR if it doesn't exist
154
- console.log(` 🔍 Checking for existing pull requests...`)
240
+ console.log(`🔍 Checking for existing pull requests...`)
155
241
  const existingPRs = await run(
156
242
  `gh pr list --repo PayFit/${repoName} --head ${branchName} --json number`,
157
243
  )
158
244
  if (JSON.parse(existingPRs).length === 0) {
159
- console.log(` 📋 Creating pull request...`)
245
+ console.log(`📋 Creating pull request...`)
160
246
 
161
247
  // Create PR body with release notes
162
- const prBody = `Update @payfit/nx-core from ${updateInfo.currentVersion} to ${NX_CORE_VERSION}
163
-
164
- ## Changelog
248
+ const prTitleParts = []
249
+ if (nxUpdateInfo.needsUpdate) prTitleParts.push(`Nx to v${NX_VERSION}`)
250
+ if (nxCoreUpdateInfo.needsUpdate)
251
+ prTitleParts.push(`@payfit/nx-core to v${NX_CORE_VERSION}`)
252
+ const prTitle = `chore(nx): update ${prTitleParts.join(' and ')}`
253
+
254
+ let prBody = ''
255
+ if (nxUpdateInfo.needsUpdate) {
256
+ prBody += `Update Nx from ${nxUpdateInfo.currentVersion} to ${NX_VERSION}\n\n`
257
+ }
258
+ if (nxCoreUpdateInfo.needsUpdate) {
259
+ prBody += `Update @payfit/nx-core from ${nxCoreUpdateInfo.currentVersion} to ${NX_CORE_VERSION}\n\n`
260
+ prBody += `## Changelog\n\n${releaseNotes}\n`
261
+ }
165
262
 
166
- ${releaseNotes}
167
- `
263
+ if (JIRA_TICKET_URL) {
264
+ prBody += `\n\nJira: ${JIRA_TICKET_URL}\n`
265
+ }
168
266
 
169
267
  // Write PR body to a file to preserve formatting (newlines, markdown)
170
268
  const prBodyPath = path.join(repoPath, 'nx-core-pr-body.md')
171
269
  await fs.writeFile(prBodyPath, prBody, 'utf8')
172
270
 
173
- await run(
174
- `gh pr create --repo PayFit/${repoName} --title "chore(nx-core): update nx-core from ${updateInfo.currentVersion} to ${NX_CORE_VERSION}" --body-file "${prBodyPath}" --head ${branchName}`,
271
+ const prUrl = await run(
272
+ `gh pr create --repo PayFit/${repoName} --title ${JSON.stringify(
273
+ prTitle,
274
+ )} --body-file "${prBodyPath}" --head ${branchName}`,
175
275
  )
176
- console.log(` ✅ Successfully created PR for ${repoName}`)
276
+ if (prUrl) CREATED_PR_URLS.push(prUrl)
277
+ console.log(`✅ Successfully created PR for ${repoName}: ${prUrl}`)
177
278
  } else {
178
- console.log(` ℹ️ PR already exists for ${repoName}`)
279
+ console.log(`ℹ️ PR already exists for ${repoName}`)
179
280
  }
180
281
  } catch (error) {
181
- console.error(` ❌ Failed to process ${repoName}: ${error.message}`)
282
+ console.error(`❌ Failed to process ${repoName}: ${error.message}`)
182
283
  throw error
183
284
  }
184
285
  }
@@ -187,7 +288,7 @@ ${releaseNotes}
187
288
  async function getChangelogBetweenVersions(currentVersion, targetVersion) {
188
289
  try {
189
290
  console.log(
190
- ` 📋 Fetching changelogs from ${currentVersion} to ${targetVersion}...`,
291
+ `📋 Fetching changelogs from ${currentVersion} to ${targetVersion}...`,
191
292
  )
192
293
 
193
294
  // Get only nx-core releases from the repository, filtered at CLI level
@@ -222,36 +323,178 @@ async function getChangelogBetweenVersions(currentVersion, targetVersion) {
222
323
 
223
324
  // Fetch detailed release notes for each relevant release
224
325
  console.log(
225
- ` 📝 Fetching detailed release notes for ${relevantReleases.length} release(s)...`,
326
+ `📝 Fetching detailed release notes for ${relevantReleases.length} release(s)...`,
226
327
  )
227
- let changelog = ''
328
+ const releaseEntries = []
228
329
  for (const release of relevantReleases) {
229
330
  try {
230
331
  const releaseBody = await run(
231
332
  `gh release view ${release.tagName} --repo PayFit/nx-common-packages --json body --jq '.body'`,
232
333
  )
233
334
  const body = releaseBody.replace(/^"|"$/g, '') // Remove surrounding quotes from jq output
234
- changelog += `### ${release.tagName}\n\n`
235
- changelog += `${body || 'No release notes available.'}\n\n`
335
+ releaseEntries.push({
336
+ tag: release.tagName,
337
+ body: body || 'No release notes available.',
338
+ })
236
339
  } catch (error) {
237
340
  console.log(
238
- ` ⚠️ Could not fetch release notes for ${release.tagName}: ${error.message}`,
341
+ ` ⚠️ Could not fetch release notes for ${release.tagName}: ${error.message}`,
239
342
  )
240
- changelog += `### ${release.tagName}\n\n`
241
- changelog += `Release notes could not be retrieved.\n\n`
343
+ releaseEntries.push({
344
+ tag: release.tagName,
345
+ body: 'Release notes could not be retrieved.',
346
+ })
242
347
  }
243
348
  }
244
349
 
245
350
  console.log(
246
- ` ✅ Retrieved ${relevantReleases.length} nx-core release(s) between versions`,
351
+ `✅ Retrieved ${relevantReleases.length} nx-core release(s) between versions`,
247
352
  )
248
- return changelog.trim()
353
+
354
+ if (CHANGELOG_MODE === 'raw') {
355
+ // Plain concatenation with clear spacing
356
+ let raw = ''
357
+ for (const entry of releaseEntries) {
358
+ raw += `### ${entry.tag}\n\n${entry.body}\n\n`
359
+ }
360
+ return raw.trim()
361
+ }
362
+
363
+ // Combined/aggregated changelog
364
+ return buildCombinedChangelog(releaseEntries)
249
365
  } catch (error) {
250
- console.log(` ⚠️ Could not fetch release notes: ${error.message}`)
366
+ console.log(`⚠️ Could not fetch release notes: ${error.message}`)
251
367
  return `Release notes could not be retrieved between ${currentVersion} and ${targetVersion}.`
252
368
  }
253
369
  }
254
370
 
371
+ // Normalize a section heading to a canonical bucket
372
+ function normalizeSection(title) {
373
+ const t = String(title).trim().toLowerCase()
374
+ if (/breaking|migration/.test(t)) return 'Breaking Changes'
375
+ if (/feature/.test(t)) return 'Features'
376
+ if (/fix|bug/.test(t)) return 'Bug Fixes'
377
+ if (/perf|performance/.test(t)) return 'Performance'
378
+ if (/refactor/.test(t)) return 'Refactor'
379
+ if (/doc/.test(t)) return 'Docs'
380
+ if (/chore/.test(t)) return 'Chore'
381
+ if (/revert/.test(t)) return 'Reverts'
382
+ return null
383
+ }
384
+
385
+ // Build a combined changelog from multiple release markdown bodies
386
+ function buildCombinedChangelog(entries) {
387
+ const sectionOrder = [
388
+ 'Breaking Changes',
389
+ 'Features',
390
+ 'Bug Fixes',
391
+ 'Performance',
392
+ 'Refactor',
393
+ 'Docs',
394
+ 'Chore',
395
+ 'Reverts',
396
+ 'Other Changes',
397
+ ]
398
+
399
+ const aggregated = new Map()
400
+ for (const key of sectionOrder) aggregated.set(key, [])
401
+
402
+ for (const { tag, body } of entries) {
403
+ const lines = String(body).split('\n')
404
+ let current = null
405
+ let inCodeBlock = false
406
+ let pendingBullet = null
407
+
408
+ const flushPending = () => {
409
+ if (pendingBullet) {
410
+ const bucket = current || 'Other Changes'
411
+ aggregated.get(bucket).push(pendingBullet.trim())
412
+ pendingBullet = null
413
+ }
414
+ }
415
+
416
+ for (const raw of lines) {
417
+ const line = raw.replace(/\r$/, '')
418
+
419
+ // Handle fenced code blocks so we don't ingest code as bullets
420
+ if (/^```/.test(line.trim())) {
421
+ inCodeBlock = !inCodeBlock
422
+ continue
423
+ }
424
+ if (inCodeBlock) continue
425
+
426
+ // Headings like ##, ###, ####
427
+ const headingMatch = line.match(/^#{2,4}\s+(.+?)\s*$/)
428
+ if (headingMatch) {
429
+ flushPending()
430
+ const canonical = normalizeSection(headingMatch[1])
431
+ current = canonical
432
+ continue
433
+ }
434
+
435
+ // Bullet points
436
+ const bulletMatch = line.match(/^\s*[-*]\s+(.+)$/)
437
+ if (bulletMatch) {
438
+ // Flush previous bullet before starting new
439
+ flushPending()
440
+ pendingBullet = bulletMatch[1]
441
+ continue
442
+ }
443
+
444
+ // Continuation lines for multi-line bullets
445
+ if (pendingBullet && line.trim().length > 0) {
446
+ pendingBullet += ` ${line.trim()}`
447
+ } else if (!pendingBullet && current && line.trim().length > 0) {
448
+ // Non-bullet content under a recognized section
449
+ aggregated.get(current).push(line.trim())
450
+ }
451
+ }
452
+ flushPending()
453
+ }
454
+
455
+ // Build markdown
456
+ let out = ''
457
+ for (const key of sectionOrder) {
458
+ if (key === 'Other Changes') continue // discard Other Changes entirely
459
+ const items = aggregated.get(key)
460
+ if (!items || items.length === 0) continue
461
+ out += `#### ${key}\n\n`
462
+ for (const item of items) {
463
+ out += `- ${item}\n`
464
+ }
465
+ out += `\n`
466
+ }
467
+ return out.trim()
468
+ }
469
+
470
+ // Ensure nx.json has release.version.updateDependents = "auto" for Nx >= 22
471
+ async function ensureUpdateDependentsAuto(repoPath) {
472
+ const nxJsonPath = path.join(repoPath, 'nx.json')
473
+ try {
474
+ const content = await fs.readFile(nxJsonPath, 'utf8')
475
+ const data = JSON.parse(content)
476
+ if (!data.release) data.release = {}
477
+ if (!data.release.version) data.release.version = {}
478
+ if (data.release.version.updateDependents === undefined) {
479
+ data.release.version.updateDependents = 'auto'
480
+ await fs.writeFile(
481
+ nxJsonPath,
482
+ JSON.stringify(data, null, 2) + '\n',
483
+ 'utf8',
484
+ )
485
+ console.log(
486
+ '🧩 Set release.version.updateDependents to "auto" in nx.json',
487
+ )
488
+ return true
489
+ }
490
+ console.log('ℹ nx.json already has release.version.updateDependents')
491
+ return false
492
+ } catch (error) {
493
+ console.log(`⚠️ Skipped nx.json update: ${error.message}`)
494
+ return false
495
+ }
496
+ }
497
+
255
498
  // Check if gh CLI is installed and user is authenticated
256
499
  async function checkGhCli() {
257
500
  try {
@@ -274,7 +517,9 @@ async function checkGhCli() {
274
517
 
275
518
  // Main function
276
519
  async function main() {
277
- console.log(`🎯 nx-core Updater - version ${NX_CORE_VERSION}`)
520
+ console.log(
521
+ `🎯 nx-core Updater - nx-core target ${NX_CORE_VERSION}${NX_VERSION ? `, Nx target ${NX_VERSION}` : ''}`,
522
+ )
278
523
  console.log(`📋 Processing ${REPOSITORIES.length} repositories`)
279
524
 
280
525
  try {
@@ -289,19 +534,25 @@ async function main() {
289
534
  await fs.mkdir(WORK_DIR, { recursive: true })
290
535
 
291
536
  // Process repositories sequentially
292
- console.log(`\n🔄 Processing repositories...`)
537
+ console.log(`🔄 Processing repositories...`)
293
538
  for (const repo of REPOSITORIES) {
294
539
  await processRepo(repo)
295
540
  }
296
541
 
297
542
  // Cleanup
298
- console.log(`\n🧹 Cleaning up work directory...`)
543
+ console.log(`🧹 Cleaning up work directory...`)
299
544
  await fs.rm(WORK_DIR, { recursive: true, force: true }).catch(() => {
300
545
  // ignore error if directory does not exist
301
546
  })
302
- console.log('\n🎉 Done!')
547
+ if (CREATED_PR_URLS.length > 0) {
548
+ console.log('🔗 Created PRs:')
549
+ for (const url of CREATED_PR_URLS) {
550
+ console.log(`- ${url}`)
551
+ }
552
+ }
553
+ console.log('🎉 Done!')
303
554
  } catch (error) {
304
- console.error(`\n💥 Script failed: ${error.message}`)
555
+ console.error(`💥 Script failed: ${error.message}`)
305
556
  process.exit(1)
306
557
  }
307
558
  }
@@ -1,8 +1,22 @@
1
+ import { ArtifactType } from './enums';
1
2
  /**
2
- * Pushes Lambda function package.json as OCI artifact to ECR using ORAS.
3
+ * Pushes Lambda, frontend function package.json as OCI artifact to ECR using ORAS.
3
4
  *
4
5
  * @param ecrRepository - ECR repository name
5
6
  * @param tag - Version tag for the artifact
6
- * @param pathToPackageJson - Path to package.json file
7
+ * @param artifactPath - Path to artifact to package
8
+ * @param type - Artifact type
9
+ * @param ecrRegistry - ECR registry
7
10
  */
8
- export declare function pushImageToEcr(ecrRepository: string, tag: string, pathToPackageJson: string, type: 'lambda' | 'frontend', ecrRegistry: string): Promise<void>;
11
+ export declare function pushImageToEcr(ecrRepository: string, tag: string, artifactPath: string, type: ArtifactType.LAMBDA | ArtifactType.FRONTEND, ecrRegistry: string): Promise<void>;
12
+ /**
13
+ * Pushes helm chart as OCI artifact to ECR using ORAS.
14
+ *
15
+ * @param ecrRepository - ECR repository name
16
+ * @param tag - Version tag for the artifact
17
+ * @param artifactPath - Path to artifact to package
18
+ * @param type - Artifact type
19
+ * @param ecrRegistry - ECR registry
20
+ * @param chartConfigPath - Path to chart config file in JSON format
21
+ */
22
+ export declare function pushHelmOciToEcr(ecrRepository: string, tag: string, artifactPath: string, ecrRegistry: string, chartConfigPath: string): Promise<void>;
@@ -1,25 +1,57 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.pushImageToEcr = pushImageToEcr;
4
+ exports.pushHelmOciToEcr = pushHelmOciToEcr;
4
5
  const consola_1 = require("consola");
5
6
  const exec_1 = require("./exec");
6
7
  const github_1 = require("./github");
7
8
  /**
8
- * Pushes Lambda function package.json as OCI artifact to ECR using ORAS.
9
+ * Pushes Lambda, frontend function package.json as OCI artifact to ECR using ORAS.
9
10
  *
10
11
  * @param ecrRepository - ECR repository name
11
12
  * @param tag - Version tag for the artifact
12
- * @param pathToPackageJson - Path to package.json file
13
+ * @param artifactPath - Path to artifact to package
14
+ * @param type - Artifact type
15
+ * @param ecrRegistry - ECR registry
13
16
  */
14
- async function pushImageToEcr(ecrRepository, tag, pathToPackageJson, type, ecrRegistry) {
17
+ async function pushImageToEcr(ecrRepository, tag, artifactPath, type, ecrRegistry) {
18
+ consola_1.consola.log(`OCI: Pushing image to ECR: ${ecrRegistry}/${ecrRepository}:${tag}`);
15
19
  const commitSha = await (0, github_1.getCurrentGitCommitSha)();
16
20
  const gitRepoUrl = await (0, github_1.getSanitizedCurrentGitRepoUrl)();
21
+ const artifactType = `application/vnd.payfit.${type}.manifest`;
17
22
  const orasPushCommand = [
18
23
  `oras push ${ecrRegistry}/${ecrRepository}:${tag}`,
19
24
  `--annotation "org.opencontainers.image.source=${gitRepoUrl}"`,
20
25
  `--annotation "org.opencontainers.image.revision=${commitSha}"`,
21
26
  `--disable-path-validation`,
22
- `--artifact-type application/vnd.payfit.${type}.manifest ${pathToPackageJson}`,
27
+ `--artifact-type ${artifactType} ${artifactPath}`,
28
+ ].join(' ');
29
+ const uploadToOci = await (0, exec_1.exec)(orasPushCommand, {
30
+ throwOnError: true,
31
+ });
32
+ consola_1.consola.log(uploadToOci.stdout);
33
+ }
34
+ /**
35
+ * Pushes helm chart as OCI artifact to ECR using ORAS.
36
+ *
37
+ * @param ecrRepository - ECR repository name
38
+ * @param tag - Version tag for the artifact
39
+ * @param artifactPath - Path to artifact to package
40
+ * @param type - Artifact type
41
+ * @param ecrRegistry - ECR registry
42
+ * @param chartConfigPath - Path to chart config file in JSON format
43
+ */
44
+ async function pushHelmOciToEcr(ecrRepository, tag, artifactPath, ecrRegistry, chartConfigPath) {
45
+ consola_1.consola.log(`OCI: Pushing image to ECR: ${ecrRegistry}/${ecrRepository}:${tag}`);
46
+ const commitSha = await (0, github_1.getCurrentGitCommitSha)();
47
+ const gitRepoUrl = await (0, github_1.getSanitizedCurrentGitRepoUrl)();
48
+ const orasPushCommand = [
49
+ `oras push ${ecrRegistry}/${ecrRepository}:${tag}`,
50
+ `--annotation "org.opencontainers.image.source=${gitRepoUrl}"`,
51
+ `--annotation "org.opencontainers.image.revision=${commitSha}"`,
52
+ `--disable-path-validation`,
53
+ `--config ${chartConfigPath}:application/vnd.cncf.helm.config.v1+json`,
54
+ `${artifactPath}:application/vnd.cncf.helm.chart.content.v1.tar+gzip`,
23
55
  ].join(' ');
24
56
  const uploadToOci = await (0, exec_1.exec)(orasPushCommand, {
25
57
  throwOnError: true,
@@ -1 +1 @@
1
- {"version":3,"file":"oci.js","sourceRoot":"","sources":["../../../../src/utils/common/oci.ts"],"names":[],"mappings":";;AAYA,wCAoBC;AAhCD,qCAAiC;AAEjC,iCAA6B;AAC7B,qCAAgF;AAEhF;;;;;;GAMG;AACI,KAAK,UAAU,cAAc,CAClC,aAAqB,EACrB,GAAW,EACX,iBAAyB,EACzB,IAA2B,EAC3B,WAAmB;IAEnB,MAAM,SAAS,GAAG,MAAM,IAAA,+BAAsB,GAAE,CAAA;IAChD,MAAM,UAAU,GAAG,MAAM,IAAA,sCAA6B,GAAE,CAAA;IACxD,MAAM,eAAe,GAAG;QACtB,aAAa,WAAW,IAAI,aAAa,IAAI,GAAG,EAAE;QAClD,iDAAiD,UAAU,GAAG;QAC9D,mDAAmD,SAAS,GAAG;QAC/D,2BAA2B;QAC3B,0CAA0C,IAAI,aAAa,iBAAiB,EAAE;KAC/E,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACX,MAAM,WAAW,GAAG,MAAM,IAAA,WAAI,EAAC,eAAe,EAAE;QAC9C,YAAY,EAAE,IAAI;KACnB,CAAC,CAAA;IACF,iBAAO,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;AACjC,CAAC"}
1
+ {"version":3,"file":"oci.js","sourceRoot":"","sources":["../../../../src/utils/common/oci.ts"],"names":[],"mappings":";;AAeA,wCAwBC;AAYD,4CAwBC;AA3ED,qCAAiC;AAGjC,iCAA6B;AAC7B,qCAAgF;AAEhF;;;;;;;;GAQG;AACI,KAAK,UAAU,cAAc,CAClC,aAAqB,EACrB,GAAW,EACX,YAAoB,EACpB,IAAiD,EACjD,WAAmB;IAEnB,iBAAO,CAAC,GAAG,CACT,8BAA8B,WAAW,IAAI,aAAa,IAAI,GAAG,EAAE,CACpE,CAAA;IACD,MAAM,SAAS,GAAG,MAAM,IAAA,+BAAsB,GAAE,CAAA;IAChD,MAAM,UAAU,GAAG,MAAM,IAAA,sCAA6B,GAAE,CAAA;IACxD,MAAM,YAAY,GAAG,0BAA0B,IAAI,WAAW,CAAA;IAC9D,MAAM,eAAe,GAAG;QACtB,aAAa,WAAW,IAAI,aAAa,IAAI,GAAG,EAAE;QAClD,iDAAiD,UAAU,GAAG;QAC9D,mDAAmD,SAAS,GAAG;QAC/D,2BAA2B;QAC3B,mBAAmB,YAAY,IAAI,YAAY,EAAE;KAClD,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACX,MAAM,WAAW,GAAG,MAAM,IAAA,WAAI,EAAC,eAAe,EAAE;QAC9C,YAAY,EAAE,IAAI;KACnB,CAAC,CAAA;IACF,iBAAO,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;AACjC,CAAC;AAED;;;;;;;;;GASG;AACI,KAAK,UAAU,gBAAgB,CACpC,aAAqB,EACrB,GAAW,EACX,YAAoB,EACpB,WAAmB,EACnB,eAAuB;IAEvB,iBAAO,CAAC,GAAG,CACT,8BAA8B,WAAW,IAAI,aAAa,IAAI,GAAG,EAAE,CACpE,CAAA;IACD,MAAM,SAAS,GAAG,MAAM,IAAA,+BAAsB,GAAE,CAAA;IAChD,MAAM,UAAU,GAAG,MAAM,IAAA,sCAA6B,GAAE,CAAA;IACxD,MAAM,eAAe,GAAG;QACtB,aAAa,WAAW,IAAI,aAAa,IAAI,GAAG,EAAE;QAClD,iDAAiD,UAAU,GAAG;QAC9D,mDAAmD,SAAS,GAAG;QAC/D,2BAA2B;QAC3B,YAAY,eAAe,2CAA2C;QACtE,GAAG,YAAY,sDAAsD;KACtE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACX,MAAM,WAAW,GAAG,MAAM,IAAA,WAAI,EAAC,eAAe,EAAE;QAC9C,YAAY,EAAE,IAAI;KACnB,CAAC,CAAA;IACF,iBAAO,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;AACjC,CAAC"}
@@ -5,7 +5,7 @@ const auth_app_1 = require("@octokit/auth-app");
5
5
  const rest_1 = require("@octokit/rest");
6
6
  const environment_1 = require("./environment");
7
7
  function OctokitAuth() {
8
- if ((0, environment_1.getEnvVar)('GITHUB_TOKEN')) {
8
+ if (process.env.GITHUB_TOKEN) {
9
9
  return new rest_1.Octokit({ auth: process.env.GITHUB_TOKEN });
10
10
  }
11
11
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"octokit.js","sourceRoot":"","sources":["../../../../src/utils/common/octokit.ts"],"names":[],"mappings":";;AAKA,kCAaC;AAlBD,gDAAiD;AACjD,wCAAuC;AAEvC,+CAAyC;AAEzC,SAAgB,WAAW;IACzB,IAAI,IAAA,uBAAS,EAAC,cAAc,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,cAAO,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAA;IACxD,CAAC;SAAM,CAAC;QACN,OAAO,IAAI,cAAO,CAAC;YACjB,YAAY,EAAE,wBAAa;YAC3B,IAAI,EAAE;gBACJ,KAAK,EAAE,IAAA,uBAAS,EAAC,eAAe,CAAC;gBACjC,UAAU,EAAE,IAAA,uBAAS,EAAC,oBAAoB,CAAC;gBAC3C,cAAc,EAAE,IAAA,uBAAS,EAAC,wBAAwB,CAAC;aACpD;SACF,CAAC,CAAA;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"octokit.js","sourceRoot":"","sources":["../../../../src/utils/common/octokit.ts"],"names":[],"mappings":";;AAKA,kCAaC;AAlBD,gDAAiD;AACjD,wCAAuC;AAEvC,+CAAyC;AAEzC,SAAgB,WAAW;IACzB,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC7B,OAAO,IAAI,cAAO,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAA;IACxD,CAAC;SAAM,CAAC;QACN,OAAO,IAAI,cAAO,CAAC;YACjB,YAAY,EAAE,wBAAa;YAC3B,IAAI,EAAE;gBACJ,KAAK,EAAE,IAAA,uBAAS,EAAC,eAAe,CAAC;gBACjC,UAAU,EAAE,IAAA,uBAAS,EAAC,oBAAoB,CAAC;gBAC3C,cAAc,EAAE,IAAA,uBAAS,EAAC,wBAAwB,CAAC;aACpD;SACF,CAAC,CAAA;IACJ,CAAC;AACH,CAAC"}
@@ -60,5 +60,5 @@ export declare function pushPackagedHelm(packagedHelmChartFilePath: string, pack
60
60
  * @param packagedHelmChartFilePath
61
61
  * @param ecrRepositoryPath
62
62
  */
63
- export declare function pushOciPackagedHelm(packagedHelmChartFilePath: string, ecrRepositoryPath: string): Promise<import("tinyexec").Output>;
63
+ export declare function pushOciPackagedHelm(packagedHelmChartFilePath: string, ecrRepositoryPath: string, version: string, chartConfigPath: string): Promise<void>;
64
64
  export {};
@@ -15,6 +15,7 @@ const aws_auth_1 = require("./common/aws-auth");
15
15
  const ecr_1 = require("./common/ecr");
16
16
  const exec_1 = require("./common/exec");
17
17
  const logger_1 = require("./common/logger");
18
+ const oci_1 = require("./common/oci");
18
19
  const tshProxy = 'http://localhost';
19
20
  /**
20
21
  * Read & parse the Helm chart.yaml file
@@ -151,10 +152,14 @@ async function pushPackagedHelm(packagedHelmChartFilePath, packagedHelmChartName
151
152
  * @param packagedHelmChartFilePath
152
153
  * @param ecrRepositoryPath
153
154
  */
154
- async function pushOciPackagedHelm(packagedHelmChartFilePath, ecrRepositoryPath) {
155
+ async function pushOciPackagedHelm(packagedHelmChartFilePath, ecrRepositoryPath, version, chartConfigPath) {
155
156
  // Login to ECR
156
157
  await (0, aws_auth_1.loginToEcr)((0, ecr_1.getAwsEcrRegistry)());
157
- // Push the Helm chart to ECR using OCI format
158
- return (0, exec_1.exec)(`helm push ${packagedHelmChartFilePath} oci://${ecrRepositoryPath}`);
158
+ const [ecrRegistry, ecrRepository] = ecrRepositoryPath.split(/\/(.*)/s);
159
+ // config file should be pushed to OCI in JSON format
160
+ const chartConfig = YAML.parse(fs.readFileSync(chartConfigPath, 'utf8'));
161
+ fs.writeFileSync('Chart.json', JSON.stringify(chartConfig, null, 2));
162
+ //Push the Helm chart to ECR using OCI format
163
+ await (0, oci_1.pushHelmOciToEcr)(ecrRepository, version, packagedHelmChartFilePath, ecrRegistry, 'Chart.json');
159
164
  }
160
165
  //# sourceMappingURL=helm.js.map