SapMachine #2250: Add adjustments to heap dumps for the buildpack #8
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # | |
| # Copyright (c) 2026 SAP SE. All rights reserved. | |
| # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
| # | |
| # This code is free software; you can redistribute it and/or modify it | |
| # under the terms of the GNU General Public License version 2 only, as | |
| # published by the Free Software Foundation. Oracle designates this | |
| # particular file as subject to the "Classpath" exception as provided | |
| # by Oracle in the LICENSE file that accompanied this code. | |
| # | |
| # This code is distributed in the hope that it will be useful, but WITHOUT | |
| # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| # version 2 for more details (a copy is included in the LICENSE file that | |
| # accompanied this code). | |
| # | |
| # You should have received a copy of the GNU General Public License version | |
| # 2 along with this work; if not, write to the Free Software Foundation, | |
| # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
| # | |
| # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
| # or visit www.oracle.com if you need additional information or have any | |
| # questions. | |
| # | |
| # Fires in the upstream repo context when a PR from a fork is opened or updated. | |
| # Polls the fork repo's Actions API for the "SapMachine GHA Sanity Checks" | |
| # run on the PR head commit, then mirrors every individual job as a native | |
| # Check Run on the upstream PR — matching the appearance of the fork's own | |
| # checks tab. No submit branches are created; no CI is re-run upstream. | |
| name: 'Mirror Checks from Source Fork' | |
| on: | |
| pull_request_target: | |
| types: | |
| - opened | |
| - synchronize | |
| - reopened | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| checks: write | |
| pull-requests: read | |
| jobs: | |
| mirror: | |
| name: 'Sync Actions from Fork' | |
| runs-on: ubuntu-24.04 | |
| # Only act on fork PRs — same-repo PRs get CI directly from main.yml. | |
| if: github.event.pull_request.head.repo.full_name != github.repository | |
| steps: | |
| - name: 'Poll fork CI and mirror per-job results' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| HEAD_SHA: ${{ github.event.pull_request.head.sha }} | |
| HEAD_REF: ${{ github.event.pull_request.head.ref }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| FORK_REPO: ${{ github.event.pull_request.head.repo.full_name }} | |
| UPSTREAM_REPO: ${{ github.repository }} | |
| run: | | |
| # ── Phase 1: Wait for the fork workflow run to appear ─────────────── | |
| # The fork may not have triggered its CI yet immediately after push. | |
| MAX_WAIT=20 | |
| ATTEMPT=0 | |
| RUN_ID="" | |
| while [[ $ATTEMPT -lt $MAX_WAIT ]]; do | |
| ATTEMPT=$((ATTEMPT + 1)) | |
| echo "Waiting for workflow run on fork (attempt ${ATTEMPT}/${MAX_WAIT})..." | |
| RUN_ID=$(gh api \ | |
| "repos/${FORK_REPO}/actions/runs?head_sha=${HEAD_SHA}&per_page=10" \ | |
| --jq '.workflow_runs[] | select(.name == "SapMachine GHA Sanity Checks") | .id' \ | |
| 2>/dev/null | head -1) | |
| if [[ -n "$RUN_ID" && "$RUN_ID" != "null" ]]; then | |
| echo "Found workflow run on fork: ${RUN_ID}" | |
| break | |
| fi | |
| # Fallback for reopened PRs: no new run may exist for HEAD_SHA, | |
| # so locate the latest pull_request run for this PR number/branch. | |
| RUN_ID=$(gh api \ | |
| "repos/${FORK_REPO}/actions/runs?event=pull_request&branch=${HEAD_REF}&per_page=50" \ | |
| --jq '.workflow_runs[] | |
| | select(.name == "SapMachine GHA Sanity Checks") | |
| | select(any(.pull_requests[]?; .number == ('"${PR_NUMBER}"' | tonumber))) | |
| | .id' \ | |
| 2>/dev/null | head -1) | |
| if [[ -n "$RUN_ID" && "$RUN_ID" != "null" ]]; then | |
| echo "Found workflow run on fork via PR fallback: ${RUN_ID}" | |
| break | |
| fi | |
| sleep 60 | |
| done | |
| if [[ -z "$RUN_ID" || "$RUN_ID" == "null" ]]; then | |
| echo "No workflow run found on fork within ${MAX_WAIT} minutes — giving up." | |
| exit 1 | |
| fi | |
| # ── Phase 2: Mirror each fork job as an upstream Check Run ────────── | |
| # job name → upstream check run ID | |
| declare -A JOB_CHECK_RUN_IDS | |
| # job name → '1' once the check run has been finalized | |
| declare -A JOB_DONE | |
| # job name → fork job HTML URL | |
| declare -A JOB_URLS | |
| MAX_POLL=180 | |
| POLL=0 | |
| OVERALL_CONCLUSION="" | |
| while [[ $POLL -lt $MAX_POLL ]]; do | |
| POLL=$((POLL + 1)) | |
| echo "Poll ${POLL}/${MAX_POLL} — syncing fork job statuses..." | |
| JOBS_JSON=$(gh api \ | |
| "repos/${FORK_REPO}/actions/runs/${RUN_ID}/jobs?per_page=100" \ | |
| 2>/dev/null) | |
| if [[ -z "$JOBS_JSON" ]]; then | |
| sleep 60 | |
| continue | |
| fi | |
| JOB_COUNT=$(echo "$JOBS_JSON" | jq '.jobs | length') | |
| for i in $(seq 0 $((JOB_COUNT - 1))); do | |
| JOB_NAME=$(echo "$JOBS_JSON" | jq -r ".jobs[$i].name") | |
| JOB_STATUS=$(echo "$JOBS_JSON" | jq -r ".jobs[$i].status") | |
| JOB_CONCLUSION=$(echo "$JOBS_JSON" | jq -r ".jobs[$i].conclusion") | |
| JOB_URL=$(echo "$JOBS_JSON" | jq -r ".jobs[$i].html_url") | |
| # Create a Check Run for this job the first time we see it. | |
| JOB_URLS[$JOB_NAME]="$JOB_URL" | |
| if [[ -z "${JOB_CHECK_RUN_IDS[$JOB_NAME]}" ]]; then | |
| echo " Creating check run: ${JOB_NAME}" | |
| CR_ID=$(gh api \ | |
| -X POST \ | |
| "repos/${UPSTREAM_REPO}/check-runs" \ | |
| -f name="${JOB_NAME}" \ | |
| -f head_sha="${HEAD_SHA}" \ | |
| -f status="in_progress" \ | |
| -f output[title]="Waiting for fork job: ${JOB_NAME}" \ | |
| -f output[summary]="Polling fork repository for job '${JOB_NAME}' on commit ${HEAD_SHA}. [View job](${JOB_URL})" \ | |
| --jq '.id') | |
| JOB_CHECK_RUN_IDS[$JOB_NAME]=$CR_ID | |
| echo " → check run ID: ${CR_ID}" | |
| fi | |
| # Finalize any job that has completed since the last poll. | |
| if [[ "$JOB_STATUS" == "completed" && -z "${JOB_DONE[$JOB_NAME]}" ]]; then | |
| CR_ID="${JOB_CHECK_RUN_IDS[$JOB_NAME]}" | |
| # Guard against null conclusion (e.g. cancelled mid-queue). | |
| [[ -z "$JOB_CONCLUSION" || "$JOB_CONCLUSION" == "null" ]] && JOB_CONCLUSION="cancelled" | |
| if [[ "$JOB_CONCLUSION" == "success" ]]; then | |
| TITLE="Passed: ${JOB_NAME}" | |
| SUMMARY="Job **${JOB_NAME}** passed on the fork. [View job](${JOB_URL})" | |
| else | |
| TITLE="${JOB_CONCLUSION^}: ${JOB_NAME}" | |
| SUMMARY="Job **${JOB_NAME}** reported **${JOB_CONCLUSION}** on the fork. [View job](${JOB_URL})" | |
| fi | |
| gh api \ | |
| -X PATCH \ | |
| "repos/${UPSTREAM_REPO}/check-runs/${CR_ID}" \ | |
| -f status="completed" \ | |
| -f conclusion="${JOB_CONCLUSION}" \ | |
| -f output[title]="${TITLE}" \ | |
| -f output[summary]="${SUMMARY}" \ | |
| -f details_url="${JOB_URL}" | |
| JOB_DONE[$JOB_NAME]=1 | |
| echo " ✓ Finalized ${JOB_NAME}: ${JOB_CONCLUSION}" | |
| fi | |
| done | |
| # Check whether the overall run has finished. | |
| RUN_JSON=$(gh api \ | |
| "repos/${FORK_REPO}/actions/runs/${RUN_ID}" \ | |
| --jq '{status: .status, conclusion: .conclusion}' \ | |
| 2>/dev/null) | |
| RUN_STATUS=$(echo "$RUN_JSON" | jq -r '.status') | |
| OVERALL_CONCLUSION=$(echo "$RUN_JSON" | jq -r '.conclusion') | |
| if [[ "$RUN_STATUS" == "completed" ]]; then | |
| echo "Workflow run on fork completed with conclusion: ${OVERALL_CONCLUSION}" | |
| # Do one final job sync to catch any jobs that finished in this last window. | |
| JOBS_JSON=$(gh api \ | |
| "repos/${FORK_REPO}/actions/runs/${RUN_ID}/jobs?per_page=100" \ | |
| 2>/dev/null) | |
| JOB_COUNT=$(echo "$JOBS_JSON" | jq '.jobs | length') | |
| for i in $(seq 0 $((JOB_COUNT - 1))); do | |
| JOB_NAME=$(echo "$JOBS_JSON" | jq -r ".jobs[$i].name") | |
| JOB_STATUS=$(echo "$JOBS_JSON" | jq -r ".jobs[$i].status") | |
| JOB_CONCLUSION=$(echo "$JOBS_JSON" | jq -r ".jobs[$i].conclusion") | |
| JOB_URL=$(echo "$JOBS_JSON" | jq -r ".jobs[$i].html_url") | |
| if [[ -z "${JOB_CHECK_RUN_IDS[$JOB_NAME]}" ]]; then | |
| CR_ID=$(gh api \ | |
| -X POST \ | |
| "repos/${UPSTREAM_REPO}/check-runs" \ | |
| -f name="${JOB_NAME}" \ | |
| -f head_sha="${HEAD_SHA}" \ | |
| -f status="in_progress" \ | |
| -f output[title]="Waiting for fork job: ${JOB_NAME}" \ | |
| -f output[summary]="Polling fork repository for job '${JOB_NAME}' on commit ${HEAD_SHA}. [View job](${JOB_URL})" \ | |
| --jq '.id') | |
| JOB_CHECK_RUN_IDS[$JOB_NAME]=$CR_ID | |
| fi | |
| if [[ "$JOB_STATUS" == "completed" && -z "${JOB_DONE[$JOB_NAME]}" ]]; then | |
| CR_ID="${JOB_CHECK_RUN_IDS[$JOB_NAME]}" | |
| [[ -z "$JOB_CONCLUSION" || "$JOB_CONCLUSION" == "null" ]] && JOB_CONCLUSION="cancelled" | |
| if [[ "$JOB_CONCLUSION" == "success" ]]; then | |
| TITLE="Passed: ${JOB_NAME}" | |
| SUMMARY="Job **${JOB_NAME}** passed on the fork. [View job](${JOB_URL})" | |
| else | |
| TITLE="${JOB_CONCLUSION^}: ${JOB_NAME}" | |
| SUMMARY="Job **${JOB_NAME}** reported **${JOB_CONCLUSION}** on the fork. [View job](${JOB_URL})" | |
| fi | |
| gh api \ | |
| -X PATCH \ | |
| "repos/${UPSTREAM_REPO}/check-runs/${CR_ID}" \ | |
| -f status="completed" \ | |
| -f conclusion="${JOB_CONCLUSION}" \ | |
| -f output[title]="${TITLE}" \ | |
| -f output[summary]="${SUMMARY}" \ | |
| -f details_url="${JOB_URL}" | |
| JOB_DONE[$JOB_NAME]=1 | |
| echo " ✓ Finalized ${JOB_NAME}: ${JOB_CONCLUSION}" | |
| fi | |
| done | |
| break | |
| fi | |
| sleep 60 | |
| done | |
| # ── Phase 3: Handle timeout ───────────────────────────────────────── | |
| if [[ -z "$OVERALL_CONCLUSION" || "$OVERALL_CONCLUSION" == "null" ]]; then | |
| OVERALL_CONCLUSION="timed_out" | |
| echo "Timed out — marking remaining open check runs." | |
| for JOB_NAME in "${!JOB_CHECK_RUN_IDS[@]}"; do | |
| if [[ -z "${JOB_DONE[$JOB_NAME]}" ]]; then | |
| CR_ID="${JOB_CHECK_RUN_IDS[$JOB_NAME]}" | |
| gh api \ | |
| -X PATCH \ | |
| "repos/${UPSTREAM_REPO}/check-runs/${CR_ID}" \ | |
| -f status="completed" \ | |
| -f conclusion="timed_out" \ | |
| -f output[title]="Timed out: ${JOB_NAME}" \ | |
| -f output[summary]="The polling window expired before job '${JOB_NAME}' completed. [View job](${JOB_URLS[$JOB_NAME]})" | |
| fi | |
| done | |
| fi | |
| # Exit non-zero so the upstream PR shows a red check if CI did not pass. | |
| if [[ "$OVERALL_CONCLUSION" != "success" ]]; then | |
| exit 1 | |
| fi |