Skip to content
Draft
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
121 changes: 121 additions & 0 deletions .github/scripts/diagnostic-quiet-build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#!/bin/bash
set -euo pipefail

log_dir=".buildchain/diagnostics"
log_file="${log_dir}/quiet-build.log"
process_context_file="${log_dir}/process-context.log"
mkdir -p "${log_dir}"
: > "${log_file}"
: > "${process_context_file}"

echo "quiet build stdout/stderr: ${log_file}"
echo "quiet process context: ${process_context_file}"
echo "quiet build started: $(date -u +%Y-%m-%dT%H:%M:%SZ)"

ps_one() {
pid="$1"
ps -o pid=,ppid=,pgid=,sess=,tty=,stat=,nice=,pri=,user=,command= -p "${pid}" 2>/dev/null \
|| ps -o pid=,ppid=,pgid=,tty=,stat=,nice=,user=,command= -p "${pid}" 2>/dev/null \
|| true
}

parent_pid() {
pid="$1"
ps -o ppid= -p "${pid}" 2>/dev/null | awk '{print $1}' || true
}

collect_process_context() {
label="$1"
{
echo
echo "## process context: ${label}"
echo "timestamp: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "whoami: $(whoami 2>/dev/null || true)"
echo "pwd: $(pwd)"
echo "uname: $(uname -a 2>/dev/null || true)"
echo "shell: ${SHELL:-}"
echo "bash_pid: ${BASHPID:-}"
echo "shell_pid: $$"
echo "parent_pid: ${PPID:-}"
echo "stdout_is_tty: $(test -t 1 && echo yes || echo no)"
echo "stderr_is_tty: $(test -t 2 && echo yes || echo no)"
echo "github_actions: ${GITHUB_ACTIONS:-}"
echo "github_workflow: ${GITHUB_WORKFLOW:-}"
echo "github_job: ${GITHUB_JOB:-}"
echo "github_action: ${GITHUB_ACTION:-}"
echo "github_ref: ${GITHUB_REF:-}"
echo "github_sha: ${GITHUB_SHA:-}"
echo "runner_name: ${RUNNER_NAME:-}"
echo "runner_os: ${RUNNER_OS:-}"
echo "runner_arch: ${RUNNER_ARCH:-}"
echo "runner_temp: ${RUNNER_TEMP:-}"
echo "runner_workspace: ${RUNNER_WORKSPACE:-}"
echo
echo "### stdio fds"
ls -l /dev/fd/0 /dev/fd/1 /dev/fd/2 2>/dev/null || true
if command -v lsof >/dev/null 2>&1; then
lsof -a -p "$$" -d 0,1,2 2>/dev/null || true
fi
echo
echo "### parent chain"
current="$$"
depth=0
while [ -n "${current}" ] && [ "${current}" != "0" ] && [ "${depth}" -lt 16 ]; do
ps_one "${current}"
next="$(parent_pid "${current}")"
[ "${next}" = "${current}" ] && break
current="${next}"
depth=$((depth + 1))
done
echo
echo "### relevant process snapshot"
ps -axo pid=,ppid=,pgid=,sess=,tty=,stat=,nice=,pri=,user=,pcpu=,etime=,command= 2>/dev/null \
| grep -E 'Runner\\.|actions-runner|diagnostic-quiet-build|buildchain\\.mjs|node-make|make -j|make -C out|corepack pnpm|ccache|clang' \
| grep -v 'grep -E' \
|| true
} >> "${process_context_file}" 2>&1
}

heartbeat() {
while true; do
sleep 60
echo "quiet build heartbeat: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
collect_process_context "heartbeat"
if command -v ccache >/dev/null 2>&1; then
ccache --show-stats 2>/dev/null | sed -n '1,5p' || true
fi
done
}

collect_process_context "script-start"

heartbeat &
heartbeat_pid="$!"
trap 'kill "${heartbeat_pid}" >/dev/null 2>&1 || true' EXIT

run_quiet() {
name="$1"
shift
{
echo
echo "## ${name}"
echo "start: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
printf '$'
printf ' %q' "$@"
echo
} >> "${log_file}"
echo "quiet build step start: ${name}"
collect_process_context "before-${name}"
"$@" >> "${log_file}" 2>&1
collect_process_context "after-${name}"
{
echo "end: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
} >> "${log_file}"
echo "quiet build step end: ${name}"
}

run_quiet "make" corepack pnpm make
run_quiet "build" node .gyp/run-with-env.js KF_SKIP_MAKE_LIBNODE=true -- corepack pnpm build
run_quiet "package" corepack pnpm package

echo "quiet build finished: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
8 changes: 6 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,12 @@ jobs:
artifact-name-template: '{artifact}-{platform}-{sha}'
artifact-paths: |
build/stage
release-candidate: ${{ startsWith(github.base_ref, 'alpha/') }}
publish-channel: ${{ startsWith(github.base_ref, 'alpha/') && 'alpha' || 'none' }}
platforms-json: >-
${{ github.event_name == 'pull_request' && startsWith(github.base_ref, 'alpha/') && github.head_ref == 'feature/macos-alpha-diagnostic' && '[{"id":"macos-arm64","name":"macOS ARM64","runner":"[\"self-hosted\",\"macOS\",\"ARM64\",\"kungfu-build-v4-macos-arm64\"]"}]' || '' }}
release-candidate: ${{ startsWith(github.base_ref, 'alpha/') && github.head_ref != 'feature/macos-alpha-diagnostic' }}
publish-channel: ${{ startsWith(github.base_ref, 'alpha/') && github.head_ref != 'feature/macos-alpha-diagnostic' && 'alpha' || 'none' }}
build-command: >-
${{ github.event_name == 'pull_request' && startsWith(github.base_ref, 'alpha/') && github.head_ref == 'feature/macos-alpha-diagnostic' && 'bash .github/scripts/diagnostic-quiet-build.sh' || '' }}
expected-artifacts-json: >-
{"minFiles":1,"minTotalBytes":10000000}
artifact-retention-days: 14
22 changes: 20 additions & 2 deletions .gyp/node-make.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ function runCacheTool(tool, args) {
run(tool, args, { check: false });
}

function showDirectorySize(label, dir) {
if (!dir || !fs.existsSync(dir) || process.platform === 'win32' || !commandExists('du')) return;
console.log(`compiler cache ${label} size:`);
runCacheTool('du', ['-sh', dir]);
}

function prepareUnixCompilerCache(mode) {
if (mode === 'sccache') {
const sccache = commandExists('sccache');
Expand Down Expand Up @@ -102,6 +108,16 @@ function showCompilerCacheStats() {
}
}

function showCompilerCacheDiagnostics(stage) {
console.log(`compiler cache diagnostics (${stage}):`);
for (const name of ['KF_COMPILER_CACHE', 'KF_COMPILER_CACHE_ROOT', 'CCACHE_DIR', 'SCCACHE_DIR', 'CC', 'CXX']) {
console.log(`${name}=${process.env[name] || ''}`);
}
showDirectorySize('ccache dir', process.env.CCACHE_DIR);
showDirectorySize('sccache dir', process.env.SCCACHE_DIR);
showCompilerCacheStats();
}

function cleanNodeBuildState() {
const generatedPaths = ['out', 'Release', 'Debug', 'config.gypi', 'config.mk'];
for (const entry of generatedPaths) {
Expand Down Expand Up @@ -190,18 +206,20 @@ const buildWin = () => {
cleanNodeBuildState();
prepareWindowsPythonEnv();
const cacheArgs = prepareCompilerCache();
showCompilerCacheDiagnostics('before build');
run(path.join('.', 'vcbuild.bat'), ['dll', arch, 'release', 'projgen', 'nobuild', ...cacheArgs], { cwd: nodeSrcDir });
runWinPatch();
run(path.join('.', 'vcbuild.bat'), ['dll', 'noprojgen', ...cacheArgs], { cwd: nodeSrcDir });
showCompilerCacheStats();
showCompilerCacheDiagnostics('after build');
};

const buildUnix = () => {
cleanNodeBuildState();
prepareCompilerCache();
showCompilerCacheDiagnostics('before build');
run('sh', [path.join('.', 'configure'), '--shared'], { cwd: nodeSrcDir });
run('make', ['-j', `${buildJobs()}`], { cwd: nodeSrcDir });
showCompilerCacheStats();
showCompilerCacheDiagnostics('after build');
};

const build = process.platform === 'win32' ? buildWin : buildUnix;
Expand Down
Loading