Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 37 additions & 14 deletions src/commands/commerce/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ import { promptConfirm } from '../../utils/prompt.js'
import config from '@adobe/aio-lib-core-config'
import { createRepo, modifyFstab, modifySidekickConfig } from '../../utils/github.js'
import { initialization } from '../../utils/initialization.js'
import { createMesh, checkAndRetryMeshUpdate, getMeshDetailsPage, confirmAPIMeshCreation } from '../../utils/mesh.js'
import { createMesh, getMeshDetailsPage, confirmAPIMeshCreation } from '../../utils/mesh.js'
import { spawn } from 'child_process'
import { openSync } from 'fs'
import Logger from '@adobe/aio-lib-core-logging'
const aioLogger = Logger('commerce:init.js')

const reset = '\x1b[0m'
const boldWhite = '\x1b[1m\x1b[37m'
Expand All @@ -38,6 +42,34 @@ export class InitCommand extends Command {
if (shouldCreateMesh) {
const installedPlugins = this.config.plugins
await createMesh(runAIOCommand, installedPlugins)
console.log(
'⏳ Verifying Mesh provisioning behind the scenes. Please check mesh-verify.log for details, or run "aio commerce:mesh-verify" if there are failures.'
)
// Spawn detached child process to verify mesh in the background, without disrupting user's CLI session.
try {
const out = openSync('./mesh-verify.log', 'w')
const err = openSync('./mesh-verify.log', 'a')
const { org, project, workspace } = config.get('console')
const orgID = org.id
const projectID = project.id
const workspaceID = workspace.id

const childProcess = spawn(
'aio',
['commerce:mesh-verify', '--orgId', orgID, '--projectId', projectID, '--workspaceId', workspaceID],
{
detached: false,
stdio: ['ignore', out, err]
}
)
// Detach from the parent process
childProcess.unref()
} catch (error) {
aioLogger.debug(error)
console.log(
'❌ Unable to verify mesh provisioning. Please try again with "aio commerce:mesh-verify"'
)
}
} else {
// this means the user chose a non-demo endpoint and still opted out of
// API Mesh creation. Use their endpoints in configs.js
Expand All @@ -50,6 +82,9 @@ export class InitCommand extends Command {
console.log('Not creating API Mesh - will use demo environment.')
}

const meshDetailsPageURL = getMeshDetailsPage()
const meshUrl = config.get('commerce.datasource.meshUrl')

await createRepo()
await modifyFstab()
await modifySidekickConfig()
Expand All @@ -65,28 +100,16 @@ export class InitCommand extends Command {
await previewContent(filePaths)
await publishContent()

// TODO: this fails with
// 2025-02-04T17:42:36.664Z [commerce:mesh.js] error: TypeError: Cannot read properties of undefined (reading 'id')
// at getMeshDetailsPage (aio-cli-plugin-commerce/src/utils/mesh.js:378:35)
// const meshDetailsPageURL = getMeshDetailsPage()
const meshUrl = config.get('commerce.datasource.meshUrl')

console.log(`🎉 ${boldWhite}Setup complete!${reset} 🎉`)
console.log(`${boldWhite}Customize your code:${reset} https://github.com/${githubOrg}/${githubRepo}`)
console.log(`${boldWhite}Edit your content:${reset} https://da.live/#/${githubOrg}/${githubRepo}`)
console.log(`${boldWhite}Manage your config:${reset} https://da.live/sheet#/${githubOrg}/${githubRepo}/configs-stage`)
console.log(`${boldWhite}Preview your storefront:${reset} https://main--${githubRepo}--${githubOrg}.aem.page/`)
meshUrl && console.log(`${boldWhite}Try out your API:${reset} ${meshUrl}`)
// meshDetailsPageURL && console.log(`${boldWhite}View your Mesh details:${reset} ${meshDetailsPageURL}`)
meshDetailsPageURL && console.log(`${boldWhite}View your Mesh details:${reset} ${meshDetailsPageURL}`)
console.log(`${boldWhite}Run locally:${reset} "aio commerce:dev"`)
console.log('For next steps, including how to customize your storefront and make it your own, check out our docs:\nhttps://experienceleague.adobe.com/developer/commerce/storefront/')

// if we created a mesh, wait for verification to complete before exiting
// TODO: Replace with detached childProcess.
if (shouldCreateMesh) {
await checkAndRetryMeshUpdate(runAIOCommand)
}

// cleanup
config.delete('commerce')
// reset github org and repo, for aio commerce:dev command
Expand Down
70 changes: 70 additions & 0 deletions src/commands/commerce/mesh-verify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
Copyright 2024 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/
import { Command, Flags } from '@oclif/core'

import { checkAndRetryMeshUpdate } from '../../utils/mesh.js'
import { runCommand } from '../../utils/runCommand.js'

const MESH_RETRIES = 2
const MESH_RETRY_INTERVAL = 90000 // 1.5 minutes

export class MeshVerify extends Command {
async run () {
const { flags } = await this.parse(MeshVerify)
const runAIOCommand = async (command, args) => {
return await this.config.runCommand(command, args)
}

try {
const { orgId, projectId, workspaceId } = flags

console.log(`Setting orgId: ${orgId}`)
await runCommand(`aio console org select ${orgId}`)

console.log(`Setting projectId: ${projectId}`)
await runCommand(`aio console project select ${projectId}`)

console.log(`Setting workspaceId: ${workspaceId}`)
await runCommand(`aio console workspace select ${workspaceId}`)
} catch (e) {
// If the user does not provide the required arguments, we will not attempt to select them and depend on preselected options from aio config.
}

await checkAndRetryMeshUpdate(
runAIOCommand,
MESH_RETRIES,
MESH_RETRY_INTERVAL
)
}
}

MeshVerify.flags = {
orgId: Flags.string({
name: 'orgId',
char: 'o',
required: false,
description: 'Organization ID'
}),
projectId: Flags.string({
name: 'projectId',
required: false,
description: 'Project ID'
}),
workspaceId: Flags.string({
name: 'workspaceId',
required: false,
description: 'Workspace ID'
})
}

MeshVerify.description =
'Verifies that the Mesh is deployed and attempts to recreate it if deployment fails.'
28 changes: 22 additions & 6 deletions src/commands/commerce/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,31 @@ OF ANY KIND, either express or implied. See the License for the specific languag
governing permissions and limitations under the License.
*/
import { Command, Help } from '@oclif/core'
import { checkAndRetryMeshUpdate } from '../../utils/mesh.js'
import { spawn } from 'child_process'
import { openSync } from 'fs'


export class TestCommand extends Command {
async run () {
const runAIOCommand = async (command, args) => {
return await this.config.runCommand(command, args)
}
await checkAndRetryMeshUpdate(runAIOCommand)
const { args } = this.parse(TestCommand)

// Spawn a detached child process to run the background task
try {
const out = openSync('./mesh-verify.log', 'w')
const err = openSync('./mesh-verify.log', 'a')
const childProcess = spawn(
'aio',
['commerce:mesh-verify'],
{
detached: true,
stdio: ['ignore', out, err]
}
)
// Detach from the parent process
childProcess.unref()
} catch (error) {}
}
}

TestCommand.description = 'Spin up an Adobe Commerce Storefront on EDS using this CLI tool'
TestCommand.description =
"Spin up an Adobe Commerce Storefront on EDS using this CLI tool";