run.sh (7350B)
1 #!/bin/bash 2 3 # CI script for git-jci 4 # This runs in .jci/<commit>/ directory 5 # Environment variables available: 6 # JCI_COMMIT - Full commit hash 7 # JCI_REPO_ROOT - Repository root path 8 # JCI_OUTPUT_DIR - Output directory (where artifacts should go) 9 10 set -eo pipefail 11 12 PIPELINE_NAME="JayporeCI" 13 14 # Summary bookkeeping -------------------------------------------------------- 15 declare -a SUMMARY_PIPELINE=() 16 declare -a SUMMARY_BUILD_MATRIX=() 17 18 add_pipeline_summary() { 19 local icon="$1" 20 local label="$2" 21 local ref="$3" 22 SUMMARY_PIPELINE+=("${icon}|${label}|${ref}") 23 } 24 25 add_build_matrix_entry() { 26 local icon="$1" 27 local label="$2" 28 local artifact="$3" 29 SUMMARY_BUILD_MATRIX+=("${icon}|${label}|${artifact}") 30 } 31 32 print_summary() { 33 local exit_code="$1" 34 local commit="${JCI_COMMIT:-unknown}" 35 local short_sha="${commit:0:12}" 36 local overall_icon="🟢" 37 [[ "${exit_code}" -ne 0 ]] && overall_icon="🔴" 38 39 printf "╔ %s : %s [sha %s]\n" "${overall_icon}" "${PIPELINE_NAME}" "${short_sha}" 40 echo "┏━ Pipeline" 41 echo "┃" 42 43 if [[ ${#SUMMARY_PIPELINE[@]} -eq 0 ]]; then 44 echo "┃ ⚪ : Pipeline exited before recording any steps" 45 else 46 for entry in "${SUMMARY_PIPELINE[@]}"; do 47 IFS='|' read -r icon label ref <<< "${entry}" 48 printf "┃ %s : %-20s [%s]\n" "${icon}" "${label}" "${ref}" 49 done 50 fi 51 52 if [[ ${#SUMMARY_BUILD_MATRIX[@]} -gt 0 ]]; then 53 echo "┃" 54 printf "┃ 🧱 Build Matrix (%d targets)\n" "${#SUMMARY_BUILD_MATRIX[@]}" 55 for entry in "${SUMMARY_BUILD_MATRIX[@]}"; do 56 IFS='|' read -r icon label artifact <<< "${entry}" 57 printf "┃ %s : %-18s [%s]\n" "${icon}" "${label}" "${artifact}" 58 done 59 fi 60 61 echo "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛" 62 } 63 64 run_step() { 65 local label="$1" 66 local ref="$2" 67 shift 2 68 69 set +e 70 "$@" 71 local exit_code=$? 72 set -e 73 74 local icon="🟢" 75 [[ ${exit_code} -ne 0 ]] && icon="🔴" 76 add_pipeline_summary "${icon}" "${label}" "${ref}" 77 78 return ${exit_code} 79 } 80 81 # --------------------------------------------------------------------------- 82 # Helper: build one binary inside its own Docker container. 83 # 84 # Usage: build_target <GOOS> <GOARCH> <OUTPUT_BINARY_NAME> [GOARM] 85 # 86 # Each invocation is fire-and-forget (&); collect PIDs for later wait. 87 # --------------------------------------------------------------------------- 88 PIDS=() 89 TARGETS=() # human-readable label per job, index-matched to PIDS 90 TARGET_ARTIFACTS=() 91 92 build_target() { 93 local goos="$1" 94 local goarch="$2" 95 local output_name="$3" 96 local goarm="${4:-7}" # only meaningful when goarch=arm 97 98 local label="${goos}/${goarch}" 99 [[ "${goarch}" == "arm" ]] && label="${label}v${goarm}" 100 101 echo "[build] Spawning container for ${label} → bin/${output_name}" 102 103 docker run --rm \ 104 -v "$PWD:/tmp/repo" \ 105 -e GOOS="${goos}" \ 106 -e GOARCH="${goarch}" \ 107 -e GOARM="${goarm}" \ 108 -e OUTPUT_BINARY_NAME="${output_name}" \ 109 golang:1.25 \ 110 "/tmp/repo/scripts/build_binary.sh" \ 111 & 112 113 PIDS+=($!) 114 TARGETS+=("${label}") 115 TARGET_ARTIFACTS+=("${output_name}") 116 } 117 118 trap 'print_summary $?' EXIT 119 120 echo "=== JCI CI Pipeline ===" 121 echo "Commit: ${JCI_COMMIT:0:12}" 122 echo "" 123 124 cd "$JCI_REPO_ROOT" 125 126 # --------------------------------------------------------------------------- 127 echo "--- Step 1: Updating code with latest VERSION ---" 128 run_step "Sync Version" "scripts/sync_version.sh" scripts/sync_version.sh 129 echo "" 130 131 # --------------------------------------------------------------------------- 132 # Step 1b: Render examples into README.md, then regenerate the TOC index 133 # --------------------------------------------------------------------------- 134 echo "--- Step 1b: Rendering examples section into README.md ---" 135 run_step "Render Examples" "scripts/render_examples.sh" scripts/render_examples.sh 136 echo "" 137 138 echo "--- Step 1c: Regenerating README index ---" 139 run_step "README Index" "scripts/generate_readme_index.sh" scripts/generate_readme_index.sh 140 echo "" 141 142 # Step 2: Build Docker image (sequential — other steps depend on it) 143 # --------------------------------------------------------------------------- 144 echo "--- Step 2: Building Docker image via scripts/build_image.sh ---" 145 run_step "Build Image" "scripts/build_image.sh" scripts/build_image.sh 146 echo "" 147 148 # --------------------------------------------------------------------------- 149 # Step 3: Static analysis / sanity checks 150 # --------------------------------------------------------------------------- 151 echo "--- Step 3: Go formatting, vet, and build checks ---" 152 run_step "Go Lint" "scripts/check_go.sh" \ 153 docker run --rm -v "$PWD:/tmp/repo" -w /tmp/repo golang:1.25 \ 154 bash -c "/tmp/repo/scripts/check_go.sh" 155 echo "" 156 157 # --------------------------------------------------------------------------- 158 # Step 4: Cross-compile binaries in parallel 159 # 160 # Targets: 161 # Linux amd64 git-jci-linux-amd64 162 # Linux arm64 git-jci-linux-arm64 163 # Linux arm (v7) git-jci-linux-armv7 164 # Linux 386 git-jci-linux-386 165 # Windows amd64 git-jci-windows-amd64.exe 166 # Windows arm64 git-jci-windows-arm64.exe 167 # --------------------------------------------------------------------------- 168 echo "--- Step 4: Building binaries in parallel ---" 169 mkdir -p bin 170 171 build_target linux amd64 git-jci-linux-amd64 172 build_target linux arm64 git-jci-linux-arm64 173 build_target linux arm git-jci-linux-armv7 7 174 build_target linux 386 git-jci-linux-386 175 build_target windows amd64 git-jci-windows-amd64.exe 176 build_target windows arm64 git-jci-windows-arm64.exe 177 178 echo "" 179 echo "Waiting for all build containers to finish..." 180 echo "" 181 182 # --------------------------------------------------------------------------- 183 # Collect results — report each job individually so failures are obvious 184 # --------------------------------------------------------------------------- 185 FAILED=0 186 for i in "${!PIDS[@]}"; do 187 pid="${PIDS[$i]}" 188 label="${TARGETS[$i]}" 189 artifact="${TARGET_ARTIFACTS[$i]}" 190 if wait "${pid}"; then 191 echo "[OK] ${label} → bin/${artifact}" 192 add_build_matrix_entry "🟢" "${label}" "${artifact}" 193 else 194 echo "[FAIL] ${label} → bin/${artifact}" 195 add_build_matrix_entry "🔴" "${label}" "${artifact}" 196 FAILED=$((FAILED + 1)) 197 fi 198 done 199 200 echo "" 201 202 total_targets=${#TARGETS[@]} 203 if [[ "${FAILED}" -gt 0 ]]; then 204 echo "${FAILED} build(s) failed. See output above for details." 205 add_pipeline_summary "🔴" "Build Matrix" "${FAILED}/${total_targets} failed" 206 exit 1 207 fi 208 209 add_pipeline_summary "🟢" "Build Matrix" "${total_targets} targets" 210 211 echo "All binaries built successfully:" 212 ls -lh bin/git-jci-* 213 echo "" 214 215 # --------------------------------------------------------------------------- 216 # Step 5: Build site (sequential — needs the binaries to be present) 217 # --------------------------------------------------------------------------- 218 echo "--- Step 5: Building and publishing site ---" 219 run_step "Docs & Site" "scripts/publish_site.sh" \ 220 docker run --rm -v "$PWD:/tmp/Jaypore CI" jci "/tmp/Jaypore CI/scripts/publish_site.sh" 221 echo "" 222 223 echo "All steps completed successfully!"