|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +# Script to create PR body using named arguments |
| 4 | +# Usage: create-pr-body.sh --arch ARCH --build-time TIME --total-time TIME --passed N --failed N [--arch ...] --run-id ID --comparison SECTION --repo REPO [--commit-file FILE] |
| 5 | + |
| 6 | +set -euo pipefail |
| 7 | + |
| 8 | +# Arrays to track architectures and their data |
| 9 | +declare -a ARCHS=() |
| 10 | +declare -A ARCH_DATA |
| 11 | + |
| 12 | +# Global parameters |
| 13 | +RUN_ID="" |
| 14 | +COMPARISON_SECTION="" |
| 15 | +REPO="" |
| 16 | +COMMIT_MESSAGE_FILE="" |
| 17 | + |
| 18 | +CURRENT_ARCH="" |
| 19 | + |
| 20 | +while [[ $# -gt 0 ]]; do |
| 21 | + case "$1" in |
| 22 | + --arch) |
| 23 | + [[ $# -lt 2 ]] && { echo "Error: --arch requires a value" >&2; exit 1; } |
| 24 | + CURRENT_ARCH="$2" |
| 25 | + # Only add to ARCHS array if not already present |
| 26 | + if [[ ! " ${ARCHS[@]:-} " =~ " ${CURRENT_ARCH} " ]]; then |
| 27 | + ARCHS+=("$CURRENT_ARCH") |
| 28 | + fi |
| 29 | + shift 2 |
| 30 | + ;; |
| 31 | + --build-time) |
| 32 | + [[ $# -lt 2 ]] && { echo "Error: --build-time requires a value" >&2; exit 1; } |
| 33 | + [[ -z "$CURRENT_ARCH" ]] && { echo "Error: --arch must be specified before --build-time" >&2; exit 1; } |
| 34 | + ARCH_DATA["${CURRENT_ARCH}_build_time"]="$2" |
| 35 | + shift 2 |
| 36 | + ;; |
| 37 | + --total-time) |
| 38 | + [[ $# -lt 2 ]] && { echo "Error: --total-time requires a value" >&2; exit 1; } |
| 39 | + [[ -z "$CURRENT_ARCH" ]] && { echo "Error: --arch must be specified before --total-time" >&2; exit 1; } |
| 40 | + ARCH_DATA["${CURRENT_ARCH}_total_time"]="$2" |
| 41 | + shift 2 |
| 42 | + ;; |
| 43 | + --passed) |
| 44 | + [[ $# -lt 2 ]] && { echo "Error: --passed requires a value" >&2; exit 1; } |
| 45 | + [[ -z "$CURRENT_ARCH" ]] && { echo "Error: --arch must be specified before --passed" >&2; exit 1; } |
| 46 | + ARCH_DATA["${CURRENT_ARCH}_passed"]="$2" |
| 47 | + shift 2 |
| 48 | + ;; |
| 49 | + --failed) |
| 50 | + [[ $# -lt 2 ]] && { echo "Error: --failed requires a value" >&2; exit 1; } |
| 51 | + [[ -z "$CURRENT_ARCH" ]] && { echo "Error: --arch must be specified before --failed" >&2; exit 1; } |
| 52 | + ARCH_DATA["${CURRENT_ARCH}_failed"]="$2" |
| 53 | + shift 2 |
| 54 | + ;; |
| 55 | + --run-id) |
| 56 | + [[ $# -lt 2 ]] && { echo "Error: --run-id requires a value" >&2; exit 1; } |
| 57 | + RUN_ID="$2" |
| 58 | + shift 2 |
| 59 | + ;; |
| 60 | + --comparison) |
| 61 | + [[ $# -lt 2 ]] && { echo "Error: --comparison requires a value" >&2; exit 1; } |
| 62 | + COMPARISON_SECTION="$2" |
| 63 | + shift 2 |
| 64 | + ;; |
| 65 | + --repo) |
| 66 | + [[ $# -lt 2 ]] && { echo "Error: --repo requires a value" >&2; exit 1; } |
| 67 | + REPO="$2" |
| 68 | + shift 2 |
| 69 | + ;; |
| 70 | + --commit-file) |
| 71 | + [[ $# -lt 2 ]] && { echo "Error: --commit-file requires a value" >&2; exit 1; } |
| 72 | + COMMIT_MESSAGE_FILE="$2" |
| 73 | + shift 2 |
| 74 | + ;; |
| 75 | + *) |
| 76 | + echo "Error: Unknown option: $1" >&2 |
| 77 | + echo "Usage: $0 --arch ARCH --build-time TIME --total-time TIME --passed N --failed N [--arch ...] --run-id ID --comparison SECTION --repo REPO [--commit-file FILE]" >&2 |
| 78 | + exit 1 |
| 79 | + ;; |
| 80 | + esac |
| 81 | +done |
| 82 | + |
| 83 | +# Validate required parameters |
| 84 | +[[ ${#ARCHS[@]} -eq 0 ]] && { echo "Error: At least one --arch required" >&2; exit 1; } |
| 85 | +[[ -z "$RUN_ID" ]] && { echo "Error: --run-id required" >&2; exit 1; } |
| 86 | +[[ -z "$COMPARISON_SECTION" ]] && { echo "Error: --comparison required" >&2; exit 1; } |
| 87 | +[[ -z "$REPO" ]] && { echo "Error: --repo required" >&2; exit 1; } |
| 88 | +[[ -z "$COMMIT_MESSAGE_FILE" ]] && COMMIT_MESSAGE_FILE="/tmp/commit_message.txt" |
| 89 | + |
| 90 | +# Check if commit message file exists |
| 91 | +if [ ! -f "$COMMIT_MESSAGE_FILE" ]; then |
| 92 | + echo "Error: Commit message file not found: $COMMIT_MESSAGE_FILE" >&2 |
| 93 | + exit 1 |
| 94 | +fi |
| 95 | + |
| 96 | +# Validate each arch has all required data |
| 97 | +for arch in "${ARCHS[@]}"; do |
| 98 | + [[ -z "${ARCH_DATA[${arch}_build_time]:-}" ]] && { echo "Error: Missing --build-time for $arch" >&2; exit 1; } |
| 99 | + [[ -z "${ARCH_DATA[${arch}_total_time]:-}" ]] && { echo "Error: Missing --total-time for $arch" >&2; exit 1; } |
| 100 | + [[ -z "${ARCH_DATA[${arch}_passed]:-}" ]] && { echo "Error: Missing --passed for $arch" >&2; exit 1; } |
| 101 | + [[ -z "${ARCH_DATA[${arch}_failed]:-}" ]] && { echo "Error: Missing --failed for $arch" >&2; exit 1; } |
| 102 | +done |
| 103 | + |
| 104 | +# Convert seconds to minutes for better readability |
| 105 | +convert_time() { |
| 106 | + local seconds="${1%s}" # Remove 's' suffix if present |
| 107 | + local minutes=$((seconds / 60)) |
| 108 | + local remaining_seconds=$((seconds % 60)) |
| 109 | + echo "${minutes}m ${remaining_seconds}s" |
| 110 | +} |
| 111 | + |
| 112 | +# Determine if multi-arch |
| 113 | +MULTIARCH=false |
| 114 | +if [ ${#ARCHS[@]} -gt 1 ]; then |
| 115 | + MULTIARCH=true |
| 116 | +fi |
| 117 | + |
| 118 | +# Convert times for all architectures |
| 119 | +for arch in "${ARCHS[@]}"; do |
| 120 | + ARCH_DATA["${arch}_build_time_readable"]=$(convert_time "${ARCH_DATA[${arch}_build_time]}") |
| 121 | + ARCH_DATA["${arch}_total_time_readable"]=$(convert_time "${ARCH_DATA[${arch}_total_time]}") |
| 122 | +done |
| 123 | + |
| 124 | +# Generate PR body |
| 125 | +cat << EOF |
| 126 | +## Summary |
| 127 | +This PR has been automatically created after successful completion of all CI stages. |
| 128 | +
|
| 129 | +## Commit Message(s) |
| 130 | +
|
| 131 | +EOF |
| 132 | + |
| 133 | +cat "$COMMIT_MESSAGE_FILE" |
| 134 | +echo "" |
| 135 | + |
| 136 | +cat << EOF |
| 137 | +
|
| 138 | +## Test Results |
| 139 | +
|
| 140 | +### ✅ Build Stage |
| 141 | +EOF |
| 142 | + |
| 143 | +# Build Stage - conditional formatting |
| 144 | +if [ "$MULTIARCH" = true ]; then |
| 145 | + cat << EOF |
| 146 | +
|
| 147 | +| Architecture | Build Time | Total Time | |
| 148 | +|--------------|------------|------------| |
| 149 | +EOF |
| 150 | + for arch in "${ARCHS[@]}"; do |
| 151 | + echo "| ${arch} | ${ARCH_DATA[${arch}_build_time_readable]} | ${ARCH_DATA[${arch}_total_time_readable]} |" |
| 152 | + done |
| 153 | +else |
| 154 | + ARCH1="${ARCHS[0]}" |
| 155 | + cat << EOF |
| 156 | +- Status: Passed (${ARCH1}) |
| 157 | +- Build Time: ${ARCH_DATA[${ARCH1}_build_time_readable]} |
| 158 | +- Total Time: ${ARCH_DATA[${ARCH1}_total_time_readable]} |
| 159 | +EOF |
| 160 | +fi |
| 161 | + |
| 162 | +cat << EOF |
| 163 | +
|
| 164 | +- [View build logs](https://github.com/${REPO}/actions/runs/${RUN_ID}) |
| 165 | +
|
| 166 | +### ✅ Boot Verification |
| 167 | +EOF |
| 168 | + |
| 169 | +# Boot Verification - conditional formatting |
| 170 | +if [ "$MULTIARCH" = true ]; then |
| 171 | + echo "- Status: Passed (all architectures)" |
| 172 | +else |
| 173 | + echo "- Status: Passed (${ARCHS[0]})" |
| 174 | +fi |
| 175 | + |
| 176 | +cat << EOF |
| 177 | +- [View boot logs](https://github.com/${REPO}/actions/runs/${RUN_ID}) |
| 178 | +
|
| 179 | +### ✅ Kernel Selftests |
| 180 | +EOF |
| 181 | + |
| 182 | +# Kernel Selftests - conditional formatting |
| 183 | +if [ "$MULTIARCH" = true ]; then |
| 184 | + cat << EOF |
| 185 | +
|
| 186 | +| Architecture | Passed | Failed | |
| 187 | +|--------------|---------|--------| |
| 188 | +EOF |
| 189 | + for arch in "${ARCHS[@]}"; do |
| 190 | + echo "| ${arch} | ${ARCH_DATA[${arch}_passed]} | ${ARCH_DATA[${arch}_failed]} |" |
| 191 | + done |
| 192 | +else |
| 193 | + ARCH1="${ARCHS[0]}" |
| 194 | + cat << EOF |
| 195 | +
|
| 196 | +- **Architecture:** ${ARCH1} |
| 197 | +- **Passed:** ${ARCH_DATA[${ARCH1}_passed]} |
| 198 | +- **Failed:** ${ARCH_DATA[${ARCH1}_failed]} |
| 199 | +EOF |
| 200 | +fi |
| 201 | + |
| 202 | +cat << EOF |
| 203 | +
|
| 204 | +- [View kselftest logs](https://github.com/${REPO}/actions/runs/${RUN_ID}) |
| 205 | +
|
| 206 | +${COMPARISON_SECTION} |
| 207 | +
|
| 208 | +--- |
| 209 | +🤖 This PR was automatically generated by GitHub Actions |
| 210 | +Run ID: ${RUN_ID} |
| 211 | +EOF |
0 commit comments