pr feedback

pull/767/head
Frostebite 2025-12-11 19:51:33 +00:00
parent 35c6d45981
commit 2d522680ec
6 changed files with 97 additions and 12 deletions

49
dist/index.js vendored
View File

@ -3476,8 +3476,30 @@ class LocalDockerCloudRunner {
for (const x of secrets) {
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) {
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) {
// core.info(JSON.stringify(content, undefined, 4));
@ -5977,11 +5999,22 @@ class RemoteClientLogger {
return;
}
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
// Write multiple times to increase chance of capture if kubectl is having issues
if (cloud_runner_options_1.default.providerStrategy === 'k8s') {
process.stdout.write(`${collectedLogsMessage}\n`, 'utf8');
process.stderr.write(`${collectedLogsMessage}\n`, 'utf8');
// Write to stdout multiple times to increase chance of capture
for (let i = 0; i < 3; i++) {
process.stdout.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
cloud_runner_logger_1.default.log(collectedLogsMessage);
@ -7749,10 +7782,16 @@ class Docker {
if (!(0, node_fs_1.existsSync)(githubWorkflow))
(0, node_fs_1.mkdirSync)(githubWorkflow);
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 \
--workdir ${dockerWorkspacePath} \
--rm \
${image_environment_factory_1.default.getEnvVarString(parameters, additionalVariables)} \
${hostMappingFlag} \
${envVarString} \
--env GITHUB_WORKSPACE=${dockerWorkspacePath} \
--env GIT_CONFIG_EXTENSIONS \
${gitPrivateToken ? `--env GIT_PRIVATE_TOKEN="${gitPrivateToken}"` : ''} \

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -91,8 +91,34 @@ class LocalDockerCloudRunner implements ProviderInterface {
for (const x of secrets) {
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) {
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) {

View File

@ -50,11 +50,23 @@ export class RemoteClientLogger {
}
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
// Write multiple times to increase chance of capture if kubectl is having issues
if (CloudRunnerOptions.providerStrategy === 'k8s') {
process.stdout.write(`${collectedLogsMessage}\n`, 'utf8');
process.stderr.write(`${collectedLogsMessage}\n`, 'utf8');
// Write to stdout multiple times to increase chance of capture
for (let i = 0; i < 3; i++) {
process.stdout.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

View File

@ -109,7 +109,8 @@ commands: echo "test"`;
const buildContainsPreBuildStepMessage = results2.includes('before-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(buildContainsPreBuildHookRunMessage).toBeTruthy();

View File

@ -57,10 +57,17 @@ class Docker {
if (!existsSync(githubWorkflow)) mkdirSync(githubWorkflow);
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 \
--workdir ${dockerWorkspacePath} \
--rm \
${ImageEnvironmentFactory.getEnvVarString(parameters, additionalVariables)} \
${hostMappingFlag} \
${envVarString} \
--env GITHUB_WORKSPACE=${dockerWorkspacePath} \
--env GIT_CONFIG_EXTENSIONS \
${gitPrivateToken ? `--env GIT_PRIVATE_TOKEN="${gitPrivateToken}"` : ''} \