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
68 changes: 48 additions & 20 deletions .github/actions/setup-api-client/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -241,27 +241,55 @@ runs:
# lru-cache is an explicit transitive dep of @octokit/auth-app required for
# GitHub App token minting; pin it here so npm always hoists a specific version
# even if a prior cached node_modules state is missing it.
# Capture stderr for debugging if the command fails
npm_output=$(mktemp)
npm_cmd=(npm install --no-save --location=project \
@octokit/rest@20.0.2 \
@octokit/plugin-retry@6.0.1 \
@octokit/plugin-paginate-rest@9.1.5 \
@octokit/auth-app@6.0.3 \
lru-cache@10.4.3)
if "${npm_cmd[@]}" 2>"$npm_output"; then
rm -f "$npm_output"
else
echo "::warning::npm install failed with: $(cat "$npm_output")"
echo "::warning::Retrying with --legacy-peer-deps"
#
# Retry with exponential backoff to survive transient npm registry errors
# (e.g. 403 Forbidden from CDN/rate-limit on safe-buffer, undici, etc.).
NPM_PACKAGES=(
@octokit/rest@20.0.2
@octokit/plugin-retry@6.0.1
@octokit/plugin-paginate-rest@9.1.5
@octokit/auth-app@6.0.3
lru-cache@10.4.3
)
NPM_MAX_RETRIES=3
NPM_BACKOFF=5 # seconds; doubles each retry (5, 10, 20)
npm_installed=false

for (( attempt=1; attempt<=NPM_MAX_RETRIES; attempt++ )); do
npm_output=$(mktemp)

if npm install --no-save --location=project "${NPM_PACKAGES[@]}" 2>"$npm_output"; then
rm -f "$npm_output"
npm_installed=true
break
fi

npm_err=$(cat "$npm_output")
rm -f "$npm_output"
npm_cmd=(npm install --no-save --legacy-peer-deps --location=project \
@octokit/rest@20.0.2 \
@octokit/plugin-retry@6.0.1 \
@octokit/plugin-paginate-rest@9.1.5 \
@octokit/auth-app@6.0.3 \
lru-cache@10.4.3)
"${npm_cmd[@]}"
echo "::warning::npm install attempt $attempt/$NPM_MAX_RETRIES failed: $npm_err"

# On first failure, also try --legacy-peer-deps in case it's a peer dep conflict
if [ "$attempt" -eq 1 ]; then
echo "::warning::Retrying with --legacy-peer-deps"
npm_output=$(mktemp)
if npm install --no-save --legacy-peer-deps --location=project "${NPM_PACKAGES[@]}" 2>"$npm_output"; then
rm -f "$npm_output"
npm_installed=true
break
fi
rm -f "$npm_output"
fi

if [ "$attempt" -lt "$NPM_MAX_RETRIES" ]; then
echo "::notice::Waiting ${NPM_BACKOFF}s before retry..."
sleep "$NPM_BACKOFF"
NPM_BACKOFF=$((NPM_BACKOFF * 2))
fi
done

if [ "$npm_installed" != "true" ]; then
echo "::error::npm install failed after $NPM_MAX_RETRIES attempts"
exit 1
fi

# Restore vendored package metadata that npm may have overwritten
Expand Down
4 changes: 2 additions & 2 deletions .github/scripts/verifier_ci_query.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ async function fetchWorkflowRun({
const category = getErrorCategory(error);
// 404 errors are expected for workflows that don't exist in consumer repos
// Use info level instead of warning to reduce noise
const isNotFound = category === ERROR_CATEGORIES.RESOURCE || error.status === 404;
const isNotFound = category === ERROR_CATEGORIES.resource || error.status === 404;
const logFn = isNotFound ? core?.info?.bind(core) : core?.warning?.bind(core);
logFn?.(
`Failed to fetch workflow runs for ${workflowId}: ${error.message}; category=${category}`
Expand Down Expand Up @@ -189,7 +189,7 @@ async function fetchWorkflowJobs({
return { jobs, error: null };
} catch (error) {
const category = getErrorCategory(error);
const isNotFound = category === ERROR_CATEGORIES.RESOURCE || error.status === 404;
const isNotFound = category === ERROR_CATEGORIES.resource || error.status === 404;
const logFn = isNotFound ? core?.info?.bind(core) : core?.warning?.bind(core);
logFn?.(`Failed to fetch workflow jobs for ${runId}: ${error.message}; category=${category}`);
return { jobs: [], error: { category, message: error.message } };
Expand Down
76 changes: 52 additions & 24 deletions templates/consumer-repo/.github/actions/setup-api-client/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,8 @@ runs:
CREATED_PACKAGE_JSON=true
fi

# Check if already installed (including lru-cache, a required transitive dep
# of @octokit/auth-app used for GitHub App token minting).
# Check if already installed (including lru-cache@10.4.3, a required
# transitive dep of @octokit/auth-app used for GitHub App token minting).
if [ -d "node_modules/@octokit/rest" ] && [ -d "node_modules/lru-cache" ]; then
echo "✅ @octokit/rest already installed"
else
Expand All @@ -239,29 +239,57 @@ runs:

# Install with pinned versions for consistency.
# lru-cache is an explicit transitive dep of @octokit/auth-app required for
# GitHub App token minting; pin it here so npm always hoists it to the top
# level even if a prior cached node_modules state is missing it.
# Capture stderr for debugging if the command fails
npm_output=$(mktemp)
npm_cmd=(npm install --no-save --location=project \
@octokit/rest@20.0.2 \
@octokit/plugin-retry@6.0.1 \
@octokit/plugin-paginate-rest@9.1.5 \
@octokit/auth-app@6.0.3 \
lru-cache@^10.0.0)
if "${npm_cmd[@]}" 2>"$npm_output"; then
rm -f "$npm_output"
else
echo "::warning::npm install failed with: $(cat "$npm_output")"
echo "::warning::Retrying with --legacy-peer-deps"
# GitHub App token minting; pin it here so npm always hoists a specific version
# even if a prior cached node_modules state is missing it.
#
# Retry with exponential backoff to survive transient npm registry errors
# (e.g. 403 Forbidden from CDN/rate-limit on safe-buffer, undici, etc.).
NPM_PACKAGES=(
@octokit/rest@20.0.2
@octokit/plugin-retry@6.0.1
@octokit/plugin-paginate-rest@9.1.5
@octokit/auth-app@6.0.3
lru-cache@10.4.3
)
NPM_MAX_RETRIES=3
NPM_BACKOFF=5 # seconds; doubles each retry (5, 10, 20)
npm_installed=false

for (( attempt=1; attempt<=NPM_MAX_RETRIES; attempt++ )); do
npm_output=$(mktemp)

if npm install --no-save --location=project "${NPM_PACKAGES[@]}" 2>"$npm_output"; then
rm -f "$npm_output"
npm_installed=true
break
fi

npm_err=$(cat "$npm_output")
rm -f "$npm_output"
npm_cmd=(npm install --no-save --legacy-peer-deps --location=project \
@octokit/rest@20.0.2 \
@octokit/plugin-retry@6.0.1 \
@octokit/plugin-paginate-rest@9.1.5 \
@octokit/auth-app@6.0.3 \
lru-cache@^10.0.0)
"${npm_cmd[@]}"
echo "::warning::npm install attempt $attempt/$NPM_MAX_RETRIES failed: $npm_err"

# On first failure, also try --legacy-peer-deps in case it's a peer dep conflict
if [ "$attempt" -eq 1 ]; then
echo "::warning::Retrying with --legacy-peer-deps"
npm_output=$(mktemp)
if npm install --no-save --legacy-peer-deps --location=project "${NPM_PACKAGES[@]}" 2>"$npm_output"; then
rm -f "$npm_output"
npm_installed=true
break
fi
rm -f "$npm_output"
fi

if [ "$attempt" -lt "$NPM_MAX_RETRIES" ]; then
echo "::notice::Waiting ${NPM_BACKOFF}s before retry..."
sleep "$NPM_BACKOFF"
NPM_BACKOFF=$((NPM_BACKOFF * 2))
fi
done

if [ "$npm_installed" != "true" ]; then
echo "::error::npm install failed after $NPM_MAX_RETRIES attempts"
exit 1
fi

# Restore vendored package metadata that npm may have overwritten
Expand Down
4 changes: 2 additions & 2 deletions templates/consumer-repo/.github/scripts/verifier_ci_query.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ async function fetchWorkflowRun({
const category = getErrorCategory(error);
// 404 errors are expected for workflows that don't exist in consumer repos
// Use info level instead of warning to reduce noise
const isNotFound = category === ERROR_CATEGORIES.RESOURCE || error.status === 404;
const isNotFound = category === ERROR_CATEGORIES.resource || error.status === 404;
const logFn = isNotFound ? core?.info?.bind(core) : core?.warning?.bind(core);
logFn?.(
`Failed to fetch workflow runs for ${workflowId}: ${error.message}; category=${category}`
Expand Down Expand Up @@ -189,7 +189,7 @@ async function fetchWorkflowJobs({
return { jobs, error: null };
} catch (error) {
const category = getErrorCategory(error);
const isNotFound = category === ERROR_CATEGORIES.RESOURCE || error.status === 404;
const isNotFound = category === ERROR_CATEGORIES.resource || error.status === 404;
const logFn = isNotFound ? core?.info?.bind(core) : core?.warning?.bind(core);
logFn?.(`Failed to fetch workflow jobs for ${runId}: ${error.message}; category=${category}`);
return { jobs: [], error: { category, message: error.message } };
Expand Down