Skip to content

PR - Update Template #1306

PR - Update Template

PR - Update Template #1306

name: PR - Update Template
on:
pull_request:
types: [opened]
workflow_run:
workflows: ["CI - Main Pipeline"]
types: [completed]
jobs:
update-template:
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
actions: read
steps:
- name: Update PR description
uses: actions/github-script@v7
with:
script: |
let prNumber, prBranch, workflowRunId;
// Handle different trigger events
if (context.eventName === 'pull_request') {
// PR opened event
prNumber = context.payload.pull_request.number;
prBranch = context.payload.pull_request.head.ref;
} else if (context.eventName === 'workflow_run') {
// Workflow completed event
workflowRunId = context.payload.workflow_run.id;
// Get PR number from workflow run
const workflowRun = await github.rest.actions.getWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: workflowRunId
});
// Extract PR number from head branch or event
if (!workflowRun.data.pull_requests || workflowRun.data.pull_requests.length === 0) {
console.log('No PR associated with this workflow run');
return;
}
prNumber = workflowRun.data.pull_requests[0].number;
prBranch = workflowRun.data.head_branch;
}
if (!prNumber) {
console.log('Could not determine PR number');
return;
}
// Get current PR details
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
let currentBody = pr.data.body || '';
let updatedBody = currentBody;
// Replace basic placeholders
updatedBody = updatedBody.replace(/\[PR_NUMBER\]/g, prNumber);
updatedBody = updatedBody.replace(/\[PR_BRANCH\]/g, prBranch);
// If we have a workflow run, update job links and badges
if (workflowRunId) {
try {
// Get jobs for this workflow run
const jobs = await github.rest.actions.listJobsForWorkflowRun({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: workflowRunId
});
// Create job mappings with status and links
const jobData = {};
for (const job of jobs.data.jobs) {
const jobName = job.name.toLowerCase();
const status = job.conclusion || job.status || 'pending';
// Map GitHub status to badge colors
const statusMap = {
success: { color: 'brightgreen', text: 'passing' },
failure: { color: 'red', text: 'failing' },
cancelled: { color: 'lightgrey', text: 'cancelled' },
skipped: { color: 'yellow', text: 'skipped' },
};
const { color, text: statusText } = statusMap[status] || { color: 'blue', text: 'running' };
jobData[jobName] = {
url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${workflowRunId}/job/${job.id}`,
status,
color,
statusText,
};
}
// Replace badges with job-specific ones
// Job names match ci-main.yml matrix strategy: "go-tests (component)" and "build (component)"
const badgeReplacements = [
{ name: 'Backend Tests', jobKey: 'go-tests (backend)' },
{ name: 'Collect Tests', jobKey: 'go-tests (collect)' },
{ name: 'Sync Tests', jobKey: 'go-tests (sync)' },
{ name: 'Frontend Tests', jobKey: 'frontend-tests' },
{ name: 'Backend Build', jobKey: 'build (backend)' },
{ name: 'Collect Build', jobKey: 'build (collect)' },
{ name: 'Sync Build', jobKey: 'build (sync)' },
{ name: 'Frontend Build', jobKey: 'build (frontend)' },
{ name: 'Proxy Build', jobKey: 'build (proxy)' }
];
for (const { name, jobKey } of badgeReplacements) {
const job = jobData[jobKey];
if (job) {
// Create badge with proper display name
const badgeUrl = `https://img.shields.io/badge/${encodeURIComponent(name)}-${job.statusText}-${job.color}`;
// Replace the specific badge line
const badgeRegex = new RegExp(`- \\[!\\[${name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\]\\([^\\)]+\\)\\]\\([^\\)]+\\)`, 'g');
updatedBody = updatedBody.replace(badgeRegex, `- [![${name}](${badgeUrl})](${job.url})`);
}
}
} catch (error) {
console.log('Error fetching job details:', error.message);
}
}
// Only update if there were changes
if (updatedBody !== currentBody) {
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber,
body: updatedBody
});
console.log(`Updated PR #${prNumber} description`);
} else {
console.log(`No updates needed for PR #${prNumber}`);
}