chore: Run a local server with docker compose while running from yarn setup (#35636)

## Description
As a user, I want to run my backend server in local machine for running
cypress test cases.


Fixes #`35635`  


## Automation

/ok-to-test tags="@tag.Sanity"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/10469851734>
> Commit: 33c2dbbcf389a6840830e8914738a068d8ab41d9
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=10469851734&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Sanity`
> Spec:
> <hr>Tue, 20 Aug 2024 10:54:22 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No

<img width="1440" alt="Screenshot 2024-08-12 at 10 12 04 PM"
src="https://github.com/user-attachments/assets/4ad51bb1-30f6-4d6c-aa60-f658848492b0">
<img width="1440" alt="Screenshot 2024-08-12 at 10 12 10 PM"
src="https://github.com/user-attachments/assets/03a3242b-302f-422c-b0df-c9da5f08d0c1">
<img width="1440" alt="Screenshot 2024-08-12 at 10 13 03 PM"
src="https://github.com/user-attachments/assets/00b71397-12a4-4471-b6a5-83642d7edc83">
<img width="1440" alt="Screenshot 2024-08-12 at 10 13 10 PM"
src="https://github.com/user-attachments/assets/2d15a205-95fa-4201-b1d1-45453064da8d">
<img width="1029" alt="Screenshot 2024-08-12 at 10 14 11 PM"
src="https://github.com/user-attachments/assets/e1778a43-9690-42ca-8adc-351d7ec95206">



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit


- **New Features**
- Introduced a new function to manage local server setup using Docker
Compose, enhancing the setup process.
	- Added user prompts to guide decisions regarding local server setup.

- **Improvements**
- Implemented a retry mechanism to check Docker services, improving
reliability during setup.
- Enhanced error handling to provide clear feedback when setup
conditions are not met.

- **Refactor**
- Integrated new functionalities into the existing setup process for a
smoother user experience.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Sagar Khalasi 2024-08-20 16:49:13 +05:30 committed by GitHub
parent 6c8d4a9a66
commit cd80904369
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,13 +1,12 @@
const { execSync } = require("child_process");
const { exec, execSync } = require("child_process");
const { existsSync, readFileSync, writeFileSync } = require("fs");
const path = require("path");
const prompt = require("prompt-sync")();
// Function to check if a Docker container is running
function isContainerRunning(containerName) {
try {
const output = execSync(
`docker ps --format '{{.Names}}' | grep -w "${containerName}"`,
`docker ps --filter "name=^/${containerName}$" --format '{{.Names}}'`,
);
return output.length > 0;
} catch (error) {
@ -15,6 +14,98 @@ function isContainerRunning(containerName) {
}
}
// Helper function to execute commands and return a Promise
async function execCommand(command, options) {
return new Promise((resolve, reject) => {
exec(command, options, (error, stdout, stderr) => {
if (error) {
reject(error);
} else {
resolve({ stdout, stderr });
}
});
});
}
function checkDockerCompose() {
try {
execSync("docker-compose --version", { stdio: "ignore" });
return true;
} catch (error) {
console.error(
"ERROR: docker-compose is not installed. Please install Docker Compose.",
);
process.exit(1);
}
}
async function runLocalServer() {
try {
let user_input = prompt(
`Do you wish to continue without setting up the local server with docker? (yes/no): `,
);
user_input = (user_input || "").trim().toLowerCase();
if (user_input === "yes" || user_input === "y") {
console.log(
"INFO",
"Continuing without setting up local backend docker based server.",
);
} else {
// Adjust the path to point to the correct directory
const dockerDir = path.join(__dirname, "../../../../deploy/docker");
if (!existsSync(dockerDir)) {
console.error(`ERROR: Directory ${dockerDir} does not exist.`);
process.exit(1); // Exit if the directory is missing
}
await checkDockerCompose(); // Ensure Docker Compose is available
console.log("INFO: Starting local server using Docker Compose...");
execSync(`cd ${dockerDir} && pwd && docker-compose up -d`, {
stdio: "inherit",
});
// Wait for the services to be fully up and running
let servicesRunning = false;
const maxRetries = 30;
const retryInterval = 7000; // 7 seconds
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const { stdout } = await execCommand("docker-compose ps", {
cwd: dockerDir,
});
if (stdout.includes("Up")) {
servicesRunning = true;
break;
}
} catch (error) {
console.error("ERROR: Error checking service status:", error.message);
process.exit(1); // Exit if checking service status fails
}
console.log(
`INFO: Waiting for services to be fully up and running... (attempt ${attempt}/${maxRetries})`,
);
await new Promise((resolve) => setTimeout(resolve, retryInterval));
}
if (servicesRunning) {
console.log("INFO: Local server is up and running.");
return true;
} else {
console.error(
"ERROR: Services did not become available within the expected time.",
);
process.exit(1); // Exit if services are not up
}
}
} catch (error) {
console.error("ERROR: Error starting local server:", error.message);
process.exit(1); // Exit if starting local server fails
}
}
function ensureTEDIsRunning() {
// Check if TED is running. If not, then ask user if they wish to pull and run the TED container
const isTedRunning = isContainerRunning("ted");
@ -147,7 +238,7 @@ async function setupCypress() {
// Get the baseUrl from cypress.config.ts file
let repoRoot = path.join(__dirname, "..", "..");
let baseUrl = getBaseUrl(repoRoot);
await runLocalServer();
await checkIfAppsmithIsRunning(baseUrl);
// Install Cypress using yarn install on the app/client repository