Skip to content

fix(ci): rely on fallback runner in auto-label.yaml #68

fix(ci): rely on fallback runner in auto-label.yaml

fix(ci): rely on fallback runner in auto-label.yaml #68

name: Trigger PR Sync
on:
push:
branches:
- main
workflow_dispatch:
inputs:
pr_number:
description: "PR Number"
required: true
type: number
permissions: {}
jobs:
pr-sync:
name: Trigger PR Sync
environment: pr-sync
runs-on:
# Ubuntu 24.04 generic (6.11.0-29) [x86_64]
- graas_ami-03dbff05cae3a30d0_${{ github.event.number || 0 }}${{ github.run_attempt }}-${{ github.run_id }}
- EXECUTION_TYPE=SHORT
- INSTANCE_TYPE=MICRO
permissions:
contents: read # sparse checkout for ci-helpers.sh
issues: write # gh label create
pull-requests: write # gh pr list, comment, edit labels
container:
image: alpine:3.23.3@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659
steps:
- name: Install tools
run: apk add --no-cache github-cli
shell: sh
- name: Determine PR Number
id: pr-number
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
EVENT_NAME: ${{ github.event_name }}
INPUT_PR_NUMBER: ${{ github.event.inputs.pr_number }}
COMMIT_SHA: ${{ github.sha }}
GH_REPO: ${{ github.repository }}
shell: sh
run: |
set -eu
if [ "${EVENT_NAME}" = "workflow_dispatch" ]; then
num="${INPUT_PR_NUMBER}"
else
max_attempts=5
sleep_time=3
attempts=0
echo "Searching for merged PR for commit: ${COMMIT_SHA}"
while [ "${attempts}" -lt "${max_attempts}" ]; do
num=$(
gh pr list \
--repo "${GH_REPO}" \
--state merged \
--search "${COMMIT_SHA}" \
--json number \
--jq 'first(.[] | .number) // empty'
) || true
if [ -n "${num}" ] && [ "${num}" != "null" ]; then
break
fi
attempts=$((attempts + 1))
if [ "${attempts}" -lt "${max_attempts}" ]; then
sleep "${sleep_time}"
echo "Attempt ${attempts} failed, retrying..."
fi
done
if [ -z "${num}" ]; then
echo "ERROR: No merged PR found after ${max_attempts} attempts." >&2
exit 1
fi
fi
echo "Found PR number: ${num}"
echo "pr_number=${num}" >> "${GITHUB_OUTPUT}"
- name: Check if PR already synced
id: check-synced
if: steps.pr-number.outcome == 'success'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
PR_NUMBER: ${{ steps.pr-number.outputs.pr_number }}
shell: sh
run: |
set -eu
readonly LABEL_SYNCED="pr-synced"
already_synced=$(
gh pr view "${PR_NUMBER}" \
--repo "${GH_REPO}" \
--json labels \
--jq "any(.labels[]; .name == \"${LABEL_SYNCED}\")"
)
case "${already_synced}" in
true)
echo "PR #${PR_NUMBER} already has label ${LABEL_SYNCED}; skipping sync."
echo "already_synced=true" >> "${GITHUB_OUTPUT}"
;;
*)
echo "already_synced=false" >> "${GITHUB_OUTPUT}"
;;
esac
- name: Validate pr-sync configuration
if: >-
steps.pr-number.outcome == 'success' &&
steps.check-synced.outputs.already_synced != 'true'
env:
TRACEE_PRIVATE_REPO_OWNER: ${{ secrets.TRACEE_PRIVATE_REPO_OWNER }}
TRACEE_PRIVATE_REPO: ${{ secrets.TRACEE_PRIVATE_REPO }}
TRACEE_PRIVATE_SYNC_WORKFLOW: ${{ secrets.TRACEE_PRIVATE_SYNC_WORKFLOW }}
GH_APP_CLIENT_ID: ${{ secrets.ACTIONS_TRACEE_WRITE_GH_APP_CLIENT_ID }}
GH_APP_PRIVATE_KEY: ${{ secrets.ACTIONS_TRACEE_WRITE_GH_APP_PRIVATE_KEY }}
shell: sh
run: |
set -eu
for v in "${TRACEE_PRIVATE_REPO_OWNER}" \
"${TRACEE_PRIVATE_REPO}" \
"${TRACEE_PRIVATE_SYNC_WORKFLOW}" \
"${GH_APP_CLIENT_ID}" \
"${GH_APP_PRIVATE_KEY}"; do
if [ -z "${v}" ]; then
echo "ERROR: One or more required pr-sync secrets are not configured." >&2
echo "Set them under Environments -> pr-sync -> Environment secrets." >&2
exit 1
fi
done
case "${TRACEE_PRIVATE_REPO}" in
*/*)
echo "ERROR: TRACEE_PRIVATE_REPO must be the repository name only (no owner/ prefix)." >&2
exit 1
;;
esac
- name: Create GitHub App token
id: app-token
if: >-
steps.pr-number.outcome == 'success' &&
steps.check-synced.outputs.already_synced != 'true'
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
with:
client-id: ${{ secrets.ACTIONS_TRACEE_WRITE_GH_APP_CLIENT_ID }}
private-key: ${{ secrets.ACTIONS_TRACEE_WRITE_GH_APP_PRIVATE_KEY }}
owner: ${{ secrets.TRACEE_PRIVATE_REPO_OWNER }}
repositories: ${{ secrets.TRACEE_PRIVATE_REPO }}
permission-actions: write
- name: Trigger pr sync workflow
id: sync
if: >-
steps.pr-number.outcome == 'success' &&
steps.check-synced.outputs.already_synced != 'true'
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
TRACEE_PRIVATE_REPO_OWNER: ${{ secrets.TRACEE_PRIVATE_REPO_OWNER }}
TRACEE_PRIVATE_REPO: ${{ secrets.TRACEE_PRIVATE_REPO }}
TRACEE_PRIVATE_SYNC_WORKFLOW: ${{ secrets.TRACEE_PRIVATE_SYNC_WORKFLOW }}
PR_NUMBER: ${{ steps.pr-number.outputs.pr_number }}
shell: sh
run: |
set -eu
gh_repo="${TRACEE_PRIVATE_REPO_OWNER}/${TRACEE_PRIVATE_REPO}"
gh_err_file=$(mktemp)
trap 'rm -f "${gh_err_file}"' EXIT
max_attempts=5
attempts=0
succeeded=false
while [ "${attempts}" -lt "${max_attempts}" ]; do
attempts=$((attempts + 1))
: > "${gh_err_file}"
if gh workflow run "${TRACEE_PRIVATE_SYNC_WORKFLOW}" \
--repo "${gh_repo}" \
--ref main \
-f "oss_pr_number=${PR_NUMBER}" \
2> "${gh_err_file}"; then
succeeded=true
break
fi
echo "Attempt ${attempts}/${max_attempts} failed to dispatch pr sync workflow." >&2
if [ -s "${gh_err_file}" ]; then
echo "gh error output:" >&2
cat "${gh_err_file}" >&2
fi
if [ "${attempts}" -lt "${max_attempts}" ]; then
sleep 1
fi
done
if [ "${succeeded}" != true ]; then
echo "ERROR: Failed to dispatch pr sync workflow after ${max_attempts} attempts." >&2
{
echo ""
echo "### Workflow dispatch failure"
echo ""
echo "Could not trigger the pr sync workflow for OSS PR #${PR_NUMBER}."
if [ -s "${gh_err_file}" ]; then
echo ""
echo "<details><summary>Last gh error output</summary>"
echo ""
echo '```'
cat "${gh_err_file}"
echo '```'
echo ""
echo "</details>"
fi
} >> "${GITHUB_STEP_SUMMARY}"
exit 1
fi
- name: Checkout helpers
if: >-
always() &&
steps.pr-number.outcome == 'success' &&
steps.check-synced.outputs.already_synced != 'true'
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
sparse-checkout: |
.github/scripts
sparse-checkout-cone-mode: false
- name: Update PR sync labels
if: >-
always() &&
steps.pr-number.outcome == 'success' &&
steps.check-synced.outputs.already_synced != 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
PR_NUMBER: ${{ steps.pr-number.outputs.pr_number }}
SYNC_RESULT: ${{ steps.sync.outcome }}
shell: sh
run: |
set -eu
. .github/scripts/ci-helpers.sh
readonly LABEL_SYNCED="pr-synced"
readonly LABEL_NOT_SYNCED="pr-non-synced"
ensure_label "${LABEL_SYNCED}" "1d76db" \
"PR sync dispatch succeeded"
ensure_label "${LABEL_NOT_SYNCED}" "d73a4a" \
"PR sync dispatch failed"
case "${SYNC_RESULT}" in
success)
add_label "${PR_NUMBER}" "${LABEL_SYNCED}"
remove_label "${PR_NUMBER}" "${LABEL_NOT_SYNCED}"
;;
*)
add_label "${PR_NUMBER}" "${LABEL_NOT_SYNCED}"
remove_label "${PR_NUMBER}" "${LABEL_SYNCED}"
;;
esac
- name: Comment on original PR
if: always() && steps.pr-number.outcome == 'success'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
PR_NUMBER: ${{ steps.pr-number.outputs.pr_number }}
ALREADY_SYNCED: ${{ steps.check-synced.outputs.already_synced }}
SYNC_RESULT: ${{ steps.sync.outcome }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
shell: sh
run: |
set -eu
if [ "${ALREADY_SYNCED}" = "true" ]; then
body="PR sync was already completed for this PR (label \`pr-synced\`). Skipping sync dispatch."
else
case "${SYNC_RESULT}" in
success)
body="PR sync was triggered successfully."
;;
failure)
body="PR sync could not be triggered. See [workflow run](${RUN_URL}) for details."
;;
skipped|cancelled)
body="PR sync was not run (an earlier step failed or was skipped). See [workflow run](${RUN_URL})."
;;
*)
body="PR sync status is unknown. See [workflow run](${RUN_URL})."
;;
esac
fi
gh pr comment "${PR_NUMBER}" \
--repo "${GH_REPO}" \
--body "${body}"
- name: Summary
if: always()
env:
PR_NUMBER: ${{ steps.pr-number.outputs.pr_number }}
PR_NUMBER_OUTCOME: ${{ steps.pr-number.outcome }}
ALREADY_SYNCED: ${{ steps.check-synced.outputs.already_synced }}
SYNC_RESULT: ${{ steps.sync.outcome }}
shell: sh
run: |
{
echo "## PR Sync"
echo ""
if [ "${PR_NUMBER_OUTCOME}" != "success" ]; then
echo "Did not run: merged PR number could not be determined."
elif [ "${ALREADY_SYNCED}" = "true" ]; then
echo "Skipped: OSS PR **#${PR_NUMBER}** already has the \`pr-synced\` label."
elif [ "${SYNC_RESULT}" = "success" ]; then
echo "Triggered the pr sync workflow for OSS PR **#${PR_NUMBER}**."
elif [ "${SYNC_RESULT}" = "skipped" ]; then
echo "Did not run: a step before sync failed or was skipped."
else
echo "Failed to trigger the pr sync workflow for OSS PR **#${PR_NUMBER}**."
fi
} >> "${GITHUB_STEP_SUMMARY}"