Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Export Cloud Build Failure Logs#1762

Export Cloud Build Failure Logs

Export Cloud Build Failure Logs #1762

# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
name:Export Cloud Build Failure Logs
permissions:
contents:read
checks:read
issues:write
pull-requests:write
on:
check_suite:
types:[completed]
concurrency:
group:${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress:true
jobs:
detect-build-failure:
name:Detect Cloud Build Failures
runs-on:ubuntu-latest
outputs:
failure_detected:${{ steps.detect_failures.outputs.failure_detected }}
failed_checks:${{ steps.detect_failures.outputs.failed_checks }}
pr_number:${{ steps.detect_pr_number.outputs.pr_number }}
steps:
-name:Checkout repository
uses:actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8# v6
-name:Install GitHub CLI
run:sudo apt-get update && sudo apt-get install -y gh
-name:Detect PR number using gh CLI
id:detect_pr_number
env:
GH_TOKEN:${{ secrets.GITHUB_TOKEN }}
run:|
PR_NUMBER=$(gh pr list --search "${{ github.event.check_suite.head_sha }}" --state open --json number --jq '.[0].number')
if [ -z "$PR_NUMBER" ]; then
echo "No associated PR found."
echo "failure_detected=false" >> $GITHUB_OUTPUT
exit 0
else
echo "PR Number is $PR_NUMBER"
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
fi
-name:Detect all failed Cloud Build checks
id:detect_failures
uses:actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd# v8
env:
PR_NUMBER:${{ steps.detect_pr_number.outputs.pr_number }}
with:
github-token:${{ secrets.GITHUB_TOKEN }}
script:|
const prefixes = [
'core-python-sdk-pr-',
'langchain-python-sdk-pr-',
'llamaindex-python-sdk-pr-',
];
const pr_number = process.env.PR_NUMBER;
if (!pr_number) {
core.setOutput('failure_detected', 'false');
return;
}
const { owner, repo } = context.repo;
const sha = context.payload.check_suite.head_sha;
const { data: checks } = await github.rest.checks.listForRef({ owner, repo, ref: sha, per_page: 100 });
const failed = checks.check_runs.filter(
c =>
prefixes.some(prefix => c.name.startsWith(prefix)) &&
c.status === 'completed' &&
c.conclusion === 'failure'
);
if (failed.length === 0) {
core.setOutput('failure_detected', 'false');
return;
}
core.setOutput('failure_detected', 'true');
core.setOutput('failed_checks', JSON.stringify(failed.map(f => ({ name: f.name, id: f.id, html_url: f.html_url, details_url: f.details_url, external_id: f.external_id || '' }))));
core.setOutput('pr_number', pr_number);
process-failed-builds:
needs:detect-build-failure
if:needs.detect-build-failure.outputs.failure_detected == 'true'
runs-on:ubuntu-latest
env:
GCLOUD_SERVICE_KEY:${{ secrets.GCLOUD_SERVICE_KEY }}
strategy:
matrix:
include:${{ fromJson(needs.detect-build-failure.outputs.failed_checks) }}
steps:
-name:Parse build ID and set project ID
id:parse_build_info
run:|
details_url="${{ matrix.details_url }}"
build_id=$(echo "$details_url" | sed -n 's#.*/builds/\([^?]*\).*#\1#p')
project_id=$(echo '${{ env.GCLOUD_SERVICE_KEY }}' | jq -r '.project_id')
echo "Build ID: $build_id"
echo "build_id=$build_id" >> $GITHUB_OUTPUT
echo "project_id=$project_id" >> $GITHUB_OUTPUT
-name:Authenticate to Google Cloud
uses:google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093# v3
with:
credentials_json:${{ env.GCLOUD_SERVICE_KEY }}
-name:Fetch Cloud Build logs
id:fetch_cloud_build_logs
run:|
LOG_FILE="cloudbuild_error_logs.txt"
GCLOUD_OUTPUT=$(gcloud builds log "${{ steps.parse_build_info.outputs.build_id }}" --project="${{ steps.parse_build_info.outputs.project_id }}" 2>&1)
if echo "$GCLOUD_OUTPUT" | grep -q "ERROR"; then
echo "Failed to fetch logs from gcloud builds log." > "${LOG_FILE}"
echo "--- gcloud command output ---" >> "${LOG_FILE}"
echo "$GCLOUD_OUTPUT" >> "${LOG_FILE}"
echo "-----------------------------" >> "${LOG_FILE}"
echo "Log URL: ${{ matrix.details_url }}" >> "${LOG_FILE}"
elif [ -z "$GCLOUD_OUTPUT" ]; then
echo "Warning: No logs found or gcloud command returned empty output." > "${LOG_FILE}"
echo "Log URL: ${{ matrix.details_url }}" >> "${LOG_FILE}"
else
echo "$GCLOUD_OUTPUT" > "${LOG_FILE}"
fi
echo "log_file_name=${LOG_FILE}" >> $GITHUB_OUTPUT
-name:Upload Logs as Artifact
uses:actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f# v6
with:
name:logs-${{ matrix.name }}-${{ steps.parse_build_info.outputs.build_id }}
path:${{ steps.fetch_cloud_build_logs.outputs.log_file_name }}
retention-days:15
post-pr-comment:
needs:[detect-build-failure, process-failed-builds]
runs-on:ubuntu-latest
if:always()
steps:
-name:Compose and post PR comment with artifact links
uses:actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd# v8
env:
PR_NUMBER:${{ needs.detect-build-failure.outputs.pr_number }}
with:
github-token:${{ secrets.GITHUB_TOKEN }}
script:|
const prNumber = process.env.PR_NUMBER;
if (!prNumber) {
core.info('No PR number was passed from the detection job. Skipping.');
return;
}
const { owner, repo } = context.repo;
const run_id = context.runId;
const { data: artifacts } = await github.rest.actions.listWorkflowRunArtifacts({ owner, repo, run_id });
const logArtifacts = artifacts.artifacts.filter(a => a.name.startsWith('logs-'));
const { data: comments } = await github.rest.issues.listComments({ owner, repo, issue_number: prNumber });
// The botLogin is 'github-actions' when using GITHUB_TOKEN
// You should filter comments by user.login for robustness
const botLogin = 'github-actions[bot]';
const existing = comments.find(c => c.user.login === 'github-actions[bot]' && c.body && c.body.includes('**Download Error logs:**'));
if (logArtifacts.length > 0) {
let body = '🔗 **Download Error logs:**\n\n';
for (const artifact of logArtifacts) {
const url = `https://github.com/${owner}/${repo}/actions/runs/${run_id}/artifacts/${artifact.id}`;
const openParenIndex = artifact.name.indexOf('(');
let displayName;
if (openParenIndex !== -1) {
displayName = artifact.name.substring(0, openParenIndex);
} else {
displayName = artifact.name.replace(/^logs-/, '');
}
displayName = displayName.trim();
body += `- [${displayName}](${url})\n`;
}
if (existing) {
await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body });
core.info(`Updated existing comment in PR #${prNumber}.`);
} else {
await github.rest.issues.createComment({ owner, repo, issue_number: prNumber, body });
core.info(`Posted new comment in PR #${prNumber}.`);
}
} else if (existing) {
await github.rest.issues.deleteComment({ owner, repo, comment_id: existing.id });
core.info(`Deleted previous failure comment in PR #${prNumber} as all tests now pass.`);
} else {
core.info('No failures found and no existing comment to delete.');
}

[8]ページ先頭

©2009-2025 Movatter.jp