diff --git a/.github/workflows/auto-fix-build-errors.yml b/.github/workflows/auto-fix-build-errors.yml
index 8c01f26..47857b9 100644
--- a/.github/workflows/auto-fix-build-errors.yml
+++ b/.github/workflows/auto-fix-build-errors.yml
@@ -23,56 +23,27 @@ jobs:
git lfs install
git lfs pull
- - name: Download Artifacts
- uses: actions/github-script@v7
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
with:
- script: |
- const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
- owner: context.repo.owner,
- repo: context.repo.repo,
- run_id: ${{ github.event.workflow_run.id }}
- });
-
- const buildLog = artifacts.data.artifacts.find(artifact => artifact.name === "ipa-files");
- if (!buildLog) {
- console.log("No build log artifacts found.");
- return;
- }
-
- const download = await github.rest.actions.downloadArtifact({
- owner: context.repo.owner,
- repo: context.repo.repo,
- artifact_id: buildLog.id,
- archive_format: 'zip'
- });
-
- const fs = require('fs');
- fs.writeFileSync('artifact.zip', Buffer.from(download.data));
-
- console.log("Downloaded artifact.zip");
+ node-version: '20'
- - name: Extract Artifacts
+ - name: Download Artifacts
run: |
- mkdir -p artifact-contents
- unzip -o artifact.zip -d artifact-contents || echo "No artifacts to extract"
- ls -la artifact-contents || echo "No artifact contents"
+ # Make scripts executable
+ chmod +x scripts/ci/*.sh
- if [ -f "artifact-contents/build_log.txt" ]; then
- echo "Build log found, copying for analysis..."
- cp artifact-contents/build_log.txt ./
- else
- echo "::warning::No build log found in artifacts"
- fi
-
- - name: Install Python Dependencies
- run: |
- pip3 install html
+ # Download artifacts using the helper script
+ ./scripts/ci/download-artifacts.sh "${{ github.event.workflow_run.id }}"
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Run Build Error Analysis
id: analysis
run: |
- chmod +x scripts/ci/auto-fix-build-errors.py
+ # No special Python libraries needed - using standard library only
+ # Run analysis script
if [ -f "build_log.txt" ]; then
echo "Analyzing build log..."
python3 scripts/ci/auto-fix-build-errors.py build_log.txt || echo "Analysis completed with errors"
@@ -105,45 +76,15 @@ jobs:
- name: Generate Summary
if: steps.analysis.outputs.report_generated == 'true'
run: |
- echo "## 📊 Build Error Analysis Report" > $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "A detailed analysis of the build errors has been generated." >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- # Extract summary information from the JSON report
- if [ -f "build_error_report.json" ]; then
- ERROR_COUNT=$(grep -o '"error_count":[0-9]*' build_error_report.json | cut -d ":" -f2)
- WARNING_COUNT=$(grep -o '"warning_count":[0-9]*' build_error_report.json | cut -d ":" -f2)
-
- echo "### Summary" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "* 🛑 **Errors**: ${ERROR_COUNT:-0}" >> $GITHUB_STEP_SUMMARY
- echo "* ⚠️ **Warnings**: ${WARNING_COUNT:-0}" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- fi
-
- echo "### Common Issues" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- # Include top issues from the report
- if [ -f "build_error_report.txt" ]; then
- # Extract top error types
- echo "#### Top Error Types" >> $GITHUB_STEP_SUMMARY
- echo '```' >> $GITHUB_STEP_SUMMARY
- grep -A 5 "ERROR TYPES:" build_error_report.txt >> $GITHUB_STEP_SUMMARY || echo "No error types found"
- echo '```' >> $GITHUB_STEP_SUMMARY
- fi
-
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "Please download the full HTML report from the artifacts for a comprehensive analysis." >> $GITHUB_STEP_SUMMARY
+ # Use the dedicated script to generate the GitHub step summary
+ ./scripts/ci/generate-report-summary.sh
- - name: Create Comment on PR
+ - name: Determine PR Number
+ id: pr-finder
if: github.event.workflow_run.event == 'pull_request' && steps.analysis.outputs.report_generated == 'true'
uses: actions/github-script@v7
with:
script: |
- const fs = require('fs');
-
// Get PR number from the workflow run
const run = await github.rest.actions.getWorkflowRun({
owner: context.repo.owner,
@@ -153,43 +94,19 @@ jobs:
// Extract PR number from the run data
const prNumber = run.data.pull_requests[0]?.number;
- if (!prNumber) {
+ if (prNumber) {
+ console.log(`Found PR number: ${prNumber}`);
+ return prNumber;
+ } else {
console.log("Could not determine PR number from workflow run");
- return;
+ return '';
}
-
- // Read summary information from the JSON report
- if (fs.existsSync('build_error_report.json')) {
- const reportData = JSON.parse(fs.readFileSync('build_error_report.json', 'utf8'));
- const errorCount = reportData.summary.error_count;
- const warningCount = reportData.summary.warning_count;
-
- // Create a comment on the PR
- const body = `## 🔍 Build Error Analysis Report
-
-This PR contains:
-- 🛑 **${errorCount} errors**
-- ⚠️ **${warningCount} warnings**
-
-
-Click to see error type breakdown
+ result-encoding: string
-\`\`\`
-${Object.entries(reportData.summary.error_types)
- .map(([type, count]) => `${type}: ${count}`)
- .join('\n')}
-\`\`\`
-
-
-Please check the workflow run for the full HTML report with error details and suggestions for fixing them.
- `;
-
- await github.rest.issues.createComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: prNumber,
- body: body.replace(/^\s+/gm, '') // Remove leading spaces
- });
-
- console.log(`Created comment on PR #${prNumber}`);
- }
+ - name: Create Comment on PR
+ if: github.event.workflow_run.event == 'pull_request' && steps.analysis.outputs.report_generated == 'true' && steps.pr-finder.outputs.result != ''
+ run: |
+ # Use dedicated script to create PR comment
+ ./scripts/ci/create-pr-comment.sh "${{ steps.pr-finder.outputs.result }}"
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/scripts/ci/create-pr-comment.sh b/scripts/ci/create-pr-comment.sh
new file mode 100755
index 0000000..c0ad508
--- /dev/null
+++ b/scripts/ci/create-pr-comment.sh
@@ -0,0 +1,112 @@
+#!/bin/bash
+set -eo pipefail
+
+# This script creates a PR comment with build error analysis
+# It requires a GitHub token and PR number
+
+echo "💬 Creating PR comment with build error analysis..."
+
+# Validate input parameters
+PR_NUMBER="$1"
+if [ -z "$PR_NUMBER" ]; then
+ echo "::error::No PR number provided"
+ exit 1
+fi
+
+if [ ! -f "build_error_report.json" ]; then
+ echo "::error::No build error report found"
+ exit 1
+fi
+
+# Create a temporary directory for the Node.js script
+mkdir -p temp
+cat > temp/create-comment.js << 'EOL'
+const fs = require('fs');
+
+async function createComment() {
+ try {
+ // Parse inputs
+ const prNumber = process.env.PR_NUMBER;
+ const token = process.env.GITHUB_TOKEN;
+ const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/');
+
+ if (!prNumber || !token || !owner || !repo) {
+ console.error('Missing required environment variables');
+ process.exit(1);
+ }
+
+ console.log(`Creating comment on PR #${prNumber} in ${owner}/${repo}`);
+
+ // Create the Octokit client
+ const { Octokit } = require('@octokit/rest');
+ const octokit = new Octokit({ auth: token });
+
+ // Read the error report data
+ if (!fs.existsSync('build_error_report.json')) {
+ console.error('Error report JSON file not found');
+ process.exit(1);
+ }
+
+ const reportData = JSON.parse(fs.readFileSync('build_error_report.json', 'utf8'));
+ const errorCount = reportData.summary.error_count;
+ const warningCount = reportData.summary.warning_count;
+
+ // Format error types for display
+ let errorTypesList = '';
+ if (reportData.summary.error_types) {
+ errorTypesList = Object.entries(reportData.summary.error_types)
+ .map(([type, count]) => `${type}: ${count}`)
+ .join('\n');
+ }
+
+ // Create the comment body
+ const body = `## 🔍 Build Error Analysis Report
+
+This PR contains:
+- 🛑 **${errorCount} errors**
+- ⚠️ **${warningCount} warnings**
+
+
+Click to see error type breakdown
+
+\`\`\`
+${errorTypesList}
+\`\`\`
+
+
+Please check the workflow run for the full HTML report with error details and suggestions for fixing them.
+`;
+
+ // Create the comment
+ await octokit.issues.createComment({
+ owner,
+ repo,
+ issue_number: prNumber,
+ body
+ });
+
+ console.log(`Successfully created comment on PR #${prNumber}`);
+ process.exit(0);
+ } catch (error) {
+ console.error('Error creating PR comment:', error.message);
+ process.exit(1);
+ }
+}
+
+createComment();
+EOL
+
+# Install octokit if not already installed
+npm install @octokit/rest
+
+# Set environment variables and run the script
+export PR_NUMBER="$PR_NUMBER"
+export GITHUB_TOKEN="${GITHUB_TOKEN}"
+
+echo "Running comment creation script..."
+node temp/create-comment.js
+
+# Clean up temporary files
+rm -rf temp
+
+echo "✅ PR comment creation complete"
diff --git a/scripts/ci/download-artifacts.sh b/scripts/ci/download-artifacts.sh
new file mode 100755
index 0000000..df7dee8
--- /dev/null
+++ b/scripts/ci/download-artifacts.sh
@@ -0,0 +1,142 @@
+#!/bin/bash
+set -eo pipefail
+
+# This script downloads and extracts artifacts from a failed workflow run
+# It's designed to be called from the auto-fix-build-errors workflow
+
+echo "📥 Starting artifact download process..."
+
+# Validate required inputs
+WORKFLOW_RUN_ID="$1"
+if [ -z "$WORKFLOW_RUN_ID" ]; then
+ echo "::error::No workflow run ID provided"
+ exit 1
+fi
+
+# Create a directory for the Node.js script
+mkdir -p temp
+cat > temp/download-artifacts.js << 'EOL'
+const fs = require('fs');
+const path = require('path');
+
+async function downloadArtifacts() {
+ try {
+ // Parse inputs
+ const workflowRunId = process.env.WORKFLOW_RUN_ID;
+ const token = process.env.GITHUB_TOKEN;
+ const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/');
+
+ if (!workflowRunId || !token || !owner || !repo) {
+ console.error('Missing required environment variables');
+ process.exit(1);
+ }
+
+ console.log(`Downloading artifacts for workflow run ${workflowRunId} in ${owner}/${repo}`);
+
+ // Create the Octokit client
+ const { Octokit } = require('@octokit/rest');
+ const octokit = new Octokit({ auth: token });
+
+ // List artifacts
+ const { data: artifactsList } = await octokit.actions.listWorkflowRunArtifacts({
+ owner,
+ repo,
+ run_id: workflowRunId
+ });
+
+ console.log(`Found ${artifactsList.artifacts.length} artifacts`);
+
+ // Find the build log artifact
+ const buildLog = artifactsList.artifacts.find(artifact =>
+ artifact.name === "ipa-files" ||
+ artifact.name.includes("build") ||
+ artifact.name.includes("log")
+ );
+
+ if (!buildLog) {
+ console.log("No build log artifacts found");
+ process.exit(0);
+ }
+
+ console.log(`Found build log artifact: ${buildLog.name} (${buildLog.id})`);
+
+ // Download the artifact
+ const download = await octokit.actions.downloadArtifact({
+ owner,
+ repo,
+ artifact_id: buildLog.id,
+ archive_format: 'zip'
+ });
+
+ // Save the zip file
+ fs.writeFileSync('artifact.zip', Buffer.from(download.data));
+ console.log('Artifact downloaded successfully to artifact.zip');
+
+ // Create a manifest file with artifact details
+ fs.writeFileSync('artifact-manifest.json', JSON.stringify({
+ artifact_id: buildLog.id,
+ artifact_name: buildLog.name,
+ workflow_run_id: workflowRunId
+ }, null, 2));
+
+ console.log('Successfully created artifact manifest');
+ process.exit(0);
+ } catch (error) {
+ console.error('Error downloading artifacts:', error.message);
+ process.exit(1);
+ }
+}
+
+downloadArtifacts();
+EOL
+
+# Install octokit
+npm install @octokit/rest
+
+# Set environment variables and run the script
+export WORKFLOW_RUN_ID="$WORKFLOW_RUN_ID"
+export GITHUB_TOKEN="${GITHUB_TOKEN}"
+
+echo "Running download script..."
+node temp/download-artifacts.js
+
+# Extract the artifacts
+echo "Extracting artifacts..."
+mkdir -p artifact-contents
+unzip -o artifact.zip -d artifact-contents || {
+ echo "::warning::Failed to extract artifacts, possibly empty or corrupt"
+ ls -la
+ exit 0
+}
+
+# List extracted contents
+echo "Extracted artifact contents:"
+ls -la artifact-contents
+
+# Look for build logs - try multiple common names
+if [ -f "artifact-contents/build_log.txt" ]; then
+ echo "Build log found, copying for analysis..."
+ cp artifact-contents/build_log.txt ./
+elif [ -f "artifact-contents/buildlog.txt" ]; then
+ echo "Build log found as buildlog.txt, copying for analysis..."
+ cp artifact-contents/buildlog.txt ./build_log.txt
+elif [ -f "artifact-contents/xcodebuild.log" ]; then
+ echo "Build log found as xcodebuild.log, copying for analysis..."
+ cp artifact-contents/xcodebuild.log ./build_log.txt
+else
+ # If we can't find a specific log file, look for any text file
+ TEXT_FILE=$(find artifact-contents -name "*.txt" -or -name "*.log" | head -n 1)
+ if [ -n "$TEXT_FILE" ]; then
+ echo "Using $TEXT_FILE as build log..."
+ cp "$TEXT_FILE" ./build_log.txt
+ else
+ echo "::warning::No build log found in artifacts"
+ # Create an empty log file to prevent errors in subsequent steps
+ echo "No build log found. This is a placeholder." > build_log.txt
+ fi
+fi
+
+# Clean up temporary files
+rm -rf temp
+
+echo "✅ Artifact processing complete"
diff --git a/scripts/ci/generate-report-summary.sh b/scripts/ci/generate-report-summary.sh
new file mode 100755
index 0000000..e720516
--- /dev/null
+++ b/scripts/ci/generate-report-summary.sh
@@ -0,0 +1,77 @@
+#!/bin/bash
+set -eo pipefail
+
+# This script generates a GitHub Actions workflow summary from build error reports
+# It's designed to be called from the auto-fix-build-errors workflow
+
+echo "📝 Generating build error report summary..."
+
+# Create the summary markdown file
+echo "## 📊 Build Error Analysis Report" > $GITHUB_STEP_SUMMARY
+echo "" >> $GITHUB_STEP_SUMMARY
+echo "A detailed analysis of the build errors has been generated." >> $GITHUB_STEP_SUMMARY
+echo "" >> $GITHUB_STEP_SUMMARY
+
+# Extract summary information from the JSON report
+if [ -f "build_error_report.json" ]; then
+ ERROR_COUNT=$(grep -o '"error_count":[0-9]*' build_error_report.json | cut -d ":" -f2)
+ WARNING_COUNT=$(grep -o '"warning_count":[0-9]*' build_error_report.json | cut -d ":" -f2)
+
+ echo "### Summary" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "* 🛑 **Errors**: ${ERROR_COUNT:-0}" >> $GITHUB_STEP_SUMMARY
+ echo "* ⚠️ **Warnings**: ${WARNING_COUNT:-0}" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Extract error types if available
+ ERROR_TYPES_JSON=$(grep -o '"error_types":{[
+^
+}]*}' build_error_report.json)
+ if [ -n "$ERROR_TYPES_JSON" ]; then
+ echo "### Error Types" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "```" >> $GITHUB_STEP_SUMMARY
+ # Format the JSON for better readability
+ echo "$ERROR_TYPES_JSON" | sed 's/"error_types"://' | sed 's/{//' | sed 's/}//' | sed 's/,/\n/g' | sed 's/"//g' | sed 's/:/: /g' >> $GITHUB_STEP_SUMMARY
+ echo "```" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ fi
+else
+ echo "### Summary" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "No detailed error report was generated." >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+fi
+
+# Include top issues from the text report
+if [ -f "build_error_report.txt" ]; then
+ echo "### Common Issues" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Extract top error types
+ ERROR_TYPES_SECTION=$(grep -A 10 "ERROR TYPES:" build_error_report.txt)
+ if [ -n "$ERROR_TYPES_SECTION" ]; then
+ echo "```" >> $GITHUB_STEP_SUMMARY
+ echo "$ERROR_TYPES_SECTION" >> $GITHUB_STEP_SUMMARY
+ echo "```" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Extract a few example errors for quick reference
+ echo "### Example Errors" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "```" >> $GITHUB_STEP_SUMMARY
+ grep -A 2 "ERROR:" build_error_report.txt | head -n 9 >> $GITHUB_STEP_SUMMARY
+ echo "```" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+fi
+
+echo "📦 Artifact Information" >> $GITHUB_STEP_SUMMARY
+echo "" >> $GITHUB_STEP_SUMMARY
+echo "A detailed HTML report has been uploaded as an artifact." >> $GITHUB_STEP_SUMMARY
+echo "Download it from the workflow run page for a more comprehensive analysis." >> $GITHUB_STEP_SUMMARY
+
+echo "✅ Report summary generation complete"
+
+# Output success so CI knows we completed successfully
+exit 0