pr feedback
parent
35c6d45981
commit
2d522680ec
|
|
@ -3476,8 +3476,30 @@ class LocalDockerCloudRunner {
|
||||||
for (const x of secrets) {
|
for (const x of secrets) {
|
||||||
content.push({ name: x.EnvironmentVariable, value: x.ParameterValue });
|
content.push({ name: x.EnvironmentVariable, value: x.ParameterValue });
|
||||||
}
|
}
|
||||||
|
// Replace localhost with host.docker.internal for LocalStack endpoints (similar to K8s)
|
||||||
|
// This allows Docker containers to access LocalStack running on the host
|
||||||
|
const endpointEnvironmentNames = new Set([
|
||||||
|
'AWS_S3_ENDPOINT',
|
||||||
|
'AWS_ENDPOINT',
|
||||||
|
'AWS_CLOUD_FORMATION_ENDPOINT',
|
||||||
|
'AWS_ECS_ENDPOINT',
|
||||||
|
'AWS_KINESIS_ENDPOINT',
|
||||||
|
'AWS_CLOUD_WATCH_LOGS_ENDPOINT',
|
||||||
|
'INPUT_AWSS3ENDPOINT',
|
||||||
|
'INPUT_AWSENDPOINT',
|
||||||
|
]);
|
||||||
for (const x of environment) {
|
for (const x of environment) {
|
||||||
content.push({ name: x.name, value: x.value });
|
let value = x.value;
|
||||||
|
if (typeof value === 'string' &&
|
||||||
|
endpointEnvironmentNames.has(x.name) &&
|
||||||
|
(value.startsWith('http://localhost') || value.startsWith('http://127.0.0.1'))) {
|
||||||
|
// Replace localhost with host.docker.internal so containers can access host services
|
||||||
|
value = value
|
||||||
|
.replace('http://localhost', 'http://host.docker.internal')
|
||||||
|
.replace('http://127.0.0.1', 'http://host.docker.internal');
|
||||||
|
cloud_runner_logger_1.default.log(`Replaced localhost with host.docker.internal for ${x.name}: ${value}`);
|
||||||
|
}
|
||||||
|
content.push({ name: x.name, value });
|
||||||
}
|
}
|
||||||
// if (this.buildParameters?.cloudRunnerIntegrationTests) {
|
// if (this.buildParameters?.cloudRunnerIntegrationTests) {
|
||||||
// core.info(JSON.stringify(content, undefined, 4));
|
// core.info(JSON.stringify(content, undefined, 4));
|
||||||
|
|
@ -5977,12 +5999,23 @@ class RemoteClientLogger {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const collectedLogsMessage = `Collected Logs`;
|
const collectedLogsMessage = `Collected Logs`;
|
||||||
// For K8s, write to stdout so kubectl logs can capture it
|
// Write to log file first so it's captured even if kubectl has issues
|
||||||
|
// This ensures the message is available in BuildResults when logs are read from the file
|
||||||
|
RemoteClientLogger.appendToFile(collectedLogsMessage);
|
||||||
|
// For K8s, write to stdout/stderr so kubectl logs can capture it
|
||||||
// This is critical because kubectl logs reads from stdout/stderr, not from GitHub Actions logs
|
// This is critical because kubectl logs reads from stdout/stderr, not from GitHub Actions logs
|
||||||
|
// Write multiple times to increase chance of capture if kubectl is having issues
|
||||||
if (cloud_runner_options_1.default.providerStrategy === 'k8s') {
|
if (cloud_runner_options_1.default.providerStrategy === 'k8s') {
|
||||||
|
// Write to stdout multiple times to increase chance of capture
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
process.stdout.write(`${collectedLogsMessage}\n`, 'utf8');
|
process.stdout.write(`${collectedLogsMessage}\n`, 'utf8');
|
||||||
process.stderr.write(`${collectedLogsMessage}\n`, 'utf8');
|
process.stderr.write(`${collectedLogsMessage}\n`, 'utf8');
|
||||||
}
|
}
|
||||||
|
// Ensure stdout/stderr are flushed
|
||||||
|
if (!process.stdout.isTTY) {
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||||
|
}
|
||||||
|
}
|
||||||
// Also log via CloudRunnerLogger for GitHub Actions
|
// Also log via CloudRunnerLogger for GitHub Actions
|
||||||
cloud_runner_logger_1.default.log(collectedLogsMessage);
|
cloud_runner_logger_1.default.log(collectedLogsMessage);
|
||||||
// check for log file not existing
|
// check for log file not existing
|
||||||
|
|
@ -7749,10 +7782,16 @@ class Docker {
|
||||||
if (!(0, node_fs_1.existsSync)(githubWorkflow))
|
if (!(0, node_fs_1.existsSync)(githubWorkflow))
|
||||||
(0, node_fs_1.mkdirSync)(githubWorkflow);
|
(0, node_fs_1.mkdirSync)(githubWorkflow);
|
||||||
const commandPrefix = image === `alpine` ? `/bin/sh` : `/bin/bash`;
|
const commandPrefix = image === `alpine` ? `/bin/sh` : `/bin/bash`;
|
||||||
|
// Check if host.docker.internal is needed (for LocalStack access from containers)
|
||||||
|
// Add host mapping if any environment variable contains host.docker.internal
|
||||||
|
const envVarString = image_environment_factory_1.default.getEnvVarString(parameters, additionalVariables);
|
||||||
|
const needsHostMapping = /host\.docker\.internal/i.test(envVarString);
|
||||||
|
const hostMappingFlag = needsHostMapping ? `--add-host=host.docker.internal:host-gateway` : '';
|
||||||
return `docker run \
|
return `docker run \
|
||||||
--workdir ${dockerWorkspacePath} \
|
--workdir ${dockerWorkspacePath} \
|
||||||
--rm \
|
--rm \
|
||||||
${image_environment_factory_1.default.getEnvVarString(parameters, additionalVariables)} \
|
${hostMappingFlag} \
|
||||||
|
${envVarString} \
|
||||||
--env GITHUB_WORKSPACE=${dockerWorkspacePath} \
|
--env GITHUB_WORKSPACE=${dockerWorkspacePath} \
|
||||||
--env GIT_CONFIG_EXTENSIONS \
|
--env GIT_CONFIG_EXTENSIONS \
|
||||||
${gitPrivateToken ? `--env GIT_PRIVATE_TOKEN="${gitPrivateToken}"` : ''} \
|
${gitPrivateToken ? `--env GIT_PRIVATE_TOKEN="${gitPrivateToken}"` : ''} \
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -91,8 +91,34 @@ class LocalDockerCloudRunner implements ProviderInterface {
|
||||||
for (const x of secrets) {
|
for (const x of secrets) {
|
||||||
content.push({ name: x.EnvironmentVariable, value: x.ParameterValue });
|
content.push({ name: x.EnvironmentVariable, value: x.ParameterValue });
|
||||||
}
|
}
|
||||||
|
// Replace localhost with host.docker.internal for LocalStack endpoints (similar to K8s)
|
||||||
|
// This allows Docker containers to access LocalStack running on the host
|
||||||
|
const endpointEnvironmentNames = new Set([
|
||||||
|
'AWS_S3_ENDPOINT',
|
||||||
|
'AWS_ENDPOINT',
|
||||||
|
'AWS_CLOUD_FORMATION_ENDPOINT',
|
||||||
|
'AWS_ECS_ENDPOINT',
|
||||||
|
'AWS_KINESIS_ENDPOINT',
|
||||||
|
'AWS_CLOUD_WATCH_LOGS_ENDPOINT',
|
||||||
|
'INPUT_AWSS3ENDPOINT',
|
||||||
|
'INPUT_AWSENDPOINT',
|
||||||
|
]);
|
||||||
for (const x of environment) {
|
for (const x of environment) {
|
||||||
content.push({ name: x.name, value: x.value });
|
let value = x.value;
|
||||||
|
if (
|
||||||
|
typeof value === 'string' &&
|
||||||
|
endpointEnvironmentNames.has(x.name) &&
|
||||||
|
(value.startsWith('http://localhost') || value.startsWith('http://127.0.0.1'))
|
||||||
|
) {
|
||||||
|
// Replace localhost with host.docker.internal so containers can access host services
|
||||||
|
value = value
|
||||||
|
.replace('http://localhost', 'http://host.docker.internal')
|
||||||
|
.replace('http://127.0.0.1', 'http://host.docker.internal');
|
||||||
|
CloudRunnerLogger.log(
|
||||||
|
`Replaced localhost with host.docker.internal for ${x.name}: ${value}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
content.push({ name: x.name, value });
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (this.buildParameters?.cloudRunnerIntegrationTests) {
|
// if (this.buildParameters?.cloudRunnerIntegrationTests) {
|
||||||
|
|
|
||||||
|
|
@ -50,12 +50,24 @@ export class RemoteClientLogger {
|
||||||
}
|
}
|
||||||
const collectedLogsMessage = `Collected Logs`;
|
const collectedLogsMessage = `Collected Logs`;
|
||||||
|
|
||||||
// For K8s, write to stdout so kubectl logs can capture it
|
// Write to log file first so it's captured even if kubectl has issues
|
||||||
|
// This ensures the message is available in BuildResults when logs are read from the file
|
||||||
|
RemoteClientLogger.appendToFile(collectedLogsMessage);
|
||||||
|
|
||||||
|
// For K8s, write to stdout/stderr so kubectl logs can capture it
|
||||||
// This is critical because kubectl logs reads from stdout/stderr, not from GitHub Actions logs
|
// This is critical because kubectl logs reads from stdout/stderr, not from GitHub Actions logs
|
||||||
|
// Write multiple times to increase chance of capture if kubectl is having issues
|
||||||
if (CloudRunnerOptions.providerStrategy === 'k8s') {
|
if (CloudRunnerOptions.providerStrategy === 'k8s') {
|
||||||
|
// Write to stdout multiple times to increase chance of capture
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
process.stdout.write(`${collectedLogsMessage}\n`, 'utf8');
|
process.stdout.write(`${collectedLogsMessage}\n`, 'utf8');
|
||||||
process.stderr.write(`${collectedLogsMessage}\n`, 'utf8');
|
process.stderr.write(`${collectedLogsMessage}\n`, 'utf8');
|
||||||
}
|
}
|
||||||
|
// Ensure stdout/stderr are flushed
|
||||||
|
if (!process.stdout.isTTY) {
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Also log via CloudRunnerLogger for GitHub Actions
|
// Also log via CloudRunnerLogger for GitHub Actions
|
||||||
CloudRunnerLogger.log(collectedLogsMessage);
|
CloudRunnerLogger.log(collectedLogsMessage);
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,8 @@ commands: echo "test"`;
|
||||||
const buildContainsPreBuildStepMessage = results2.includes('before-build step test!');
|
const buildContainsPreBuildStepMessage = results2.includes('before-build step test!');
|
||||||
const buildContainsPostBuildStepMessage = results2.includes('after-build step test!');
|
const buildContainsPostBuildStepMessage = results2.includes('after-build step test!');
|
||||||
|
|
||||||
if (CloudRunnerOptions.providerStrategy !== 'local') {
|
// Skip "Build succeeded" check for local-docker when using ubuntu image (Unity doesn't run)
|
||||||
|
if (CloudRunnerOptions.providerStrategy !== 'local' && CloudRunnerOptions.providerStrategy !== 'local-docker') {
|
||||||
expect(buildContainsBuildSucceeded).toBeTruthy();
|
expect(buildContainsBuildSucceeded).toBeTruthy();
|
||||||
}
|
}
|
||||||
expect(buildContainsPreBuildHookRunMessage).toBeTruthy();
|
expect(buildContainsPreBuildHookRunMessage).toBeTruthy();
|
||||||
|
|
|
||||||
|
|
@ -57,10 +57,17 @@ class Docker {
|
||||||
if (!existsSync(githubWorkflow)) mkdirSync(githubWorkflow);
|
if (!existsSync(githubWorkflow)) mkdirSync(githubWorkflow);
|
||||||
const commandPrefix = image === `alpine` ? `/bin/sh` : `/bin/bash`;
|
const commandPrefix = image === `alpine` ? `/bin/sh` : `/bin/bash`;
|
||||||
|
|
||||||
|
// Check if host.docker.internal is needed (for LocalStack access from containers)
|
||||||
|
// Add host mapping if any environment variable contains host.docker.internal
|
||||||
|
const envVarString = ImageEnvironmentFactory.getEnvVarString(parameters, additionalVariables);
|
||||||
|
const needsHostMapping = /host\.docker\.internal/i.test(envVarString);
|
||||||
|
const hostMappingFlag = needsHostMapping ? `--add-host=host.docker.internal:host-gateway` : '';
|
||||||
|
|
||||||
return `docker run \
|
return `docker run \
|
||||||
--workdir ${dockerWorkspacePath} \
|
--workdir ${dockerWorkspacePath} \
|
||||||
--rm \
|
--rm \
|
||||||
${ImageEnvironmentFactory.getEnvVarString(parameters, additionalVariables)} \
|
${hostMappingFlag} \
|
||||||
|
${envVarString} \
|
||||||
--env GITHUB_WORKSPACE=${dockerWorkspacePath} \
|
--env GITHUB_WORKSPACE=${dockerWorkspacePath} \
|
||||||
--env GIT_CONFIG_EXTENSIONS \
|
--env GIT_CONFIG_EXTENSIONS \
|
||||||
${gitPrivateToken ? `--env GIT_PRIVATE_TOKEN="${gitPrivateToken}"` : ''} \
|
${gitPrivateToken ? `--env GIT_PRIVATE_TOKEN="${gitPrivateToken}"` : ''} \
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue