mirror of
https://github.com/netdata/libbpf.git
synced 2026-11-06 01:40:15 +08:00
Run the sync monthly, and on demand. If it goes through without needing a human, push the libbpf-sync-* branch and open a pull request. Otherwise fail the run without opening one. The sync job runs code from the kernel trees (bpf_doc.py), so it only gets a read-only token. A separate publish job pushes the verified sync bundle and opens the pull request. Skip the run while any sync pull request is open. Manual runs default to dry runs, which only upload the sync results as an artifact. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Ihor Solodrai <ihor.solodrai@linux.dev>
159 lines
5.4 KiB
YAML
159 lines
5.4 KiB
YAML
name: libbpf-sync
|
|
|
|
on:
|
|
schedule:
|
|
# Monthly, on the 1st
|
|
- cron: '17 13 1 * *'
|
|
workflow_dispatch:
|
|
inputs:
|
|
dry_run:
|
|
description: Run the sync without pushing a branch or opening a pull request
|
|
required: true
|
|
default: true
|
|
type: boolean
|
|
|
|
permissions: {}
|
|
|
|
concurrency:
|
|
group: libbpf-sync
|
|
cancel-in-progress: false
|
|
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
|
|
jobs:
|
|
# Runs code from the kernel trees (bpf_doc.py), so it gets a read-only token
|
|
# and hands the result over to the publish job as an artifact.
|
|
sync:
|
|
# Forks may only dry-run
|
|
if: github.repository == 'libbpf/libbpf' || (github.event_name == 'workflow_dispatch' && inputs.dry_run)
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 120
|
|
permissions:
|
|
contents: read
|
|
pull-requests: read
|
|
outputs:
|
|
branch: ${{ steps.sync.outputs.branch }}
|
|
head_sha: ${{ steps.sync.outputs.head_sha }}
|
|
env:
|
|
DRY_RUN: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run || false }}
|
|
steps:
|
|
- name: Check for open sync pull requests
|
|
id: gate
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
REF: ${{ github.ref }}
|
|
run: |
|
|
if [ "${DRY_RUN}" != true ] && [ "${REF}" != refs/heads/master ]; then
|
|
echo "::error::Only dry runs are allowed from ${REF}"
|
|
exit 1
|
|
fi
|
|
open=$(gh pr list --repo "${GITHUB_REPOSITORY}" --base master --state open --limit 1000 \
|
|
--json headRefName,url \
|
|
--jq '[.[] | select(.headRefName | startswith("libbpf-sync-")) | .url] | join(" ")')
|
|
if [ -z "${open}" ]; then
|
|
exit 0
|
|
fi
|
|
if [ "${DRY_RUN}" = true ]; then
|
|
echo "::warning::Sync pull request already open, dry-running anyway: ${open}"
|
|
else
|
|
echo "::notice::Sync pull request already open, skipping: ${open}"
|
|
echo "skip=true" >> "${GITHUB_OUTPUT}"
|
|
fi
|
|
|
|
- name: Checkout libbpf
|
|
if: steps.gate.outputs.skip != 'true'
|
|
uses: actions/checkout@v7
|
|
with:
|
|
fetch-depth: 0
|
|
persist-credentials: false
|
|
|
|
- name: Set up git
|
|
if: steps.gate.outputs.skip != 'true'
|
|
run: |
|
|
git config --global user.name 'libbpf-bot'
|
|
git config --global user.email 'bot+libbpf@kernel.org'
|
|
git config --global checkout.workers 0
|
|
git --version
|
|
if ! git filter-branch -h > /dev/null 2>&1; then
|
|
echo "::error::git filter-branch is not available"
|
|
exit 1
|
|
fi
|
|
command -v patch python3
|
|
|
|
- name: Fetch bpf-next and bpf trees
|
|
if: steps.gate.outputs.skip != 'true'
|
|
run: .github/scripts/sync-fetch-kernel.sh "${GITHUB_WORKSPACE}" "${RUNNER_TEMP}/linux"
|
|
|
|
- name: Sync
|
|
id: sync
|
|
if: steps.gate.outputs.skip != 'true'
|
|
run: .github/scripts/sync-run.sh "${GITHUB_WORKSPACE}" "${RUNNER_TEMP}/linux" "${RUNNER_TEMP}/out"
|
|
|
|
- name: Upload sync results
|
|
if: ${{ !cancelled() && steps.gate.outputs.skip != 'true' }}
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: libbpf-sync-${{ github.run_id }}
|
|
path: ${{ runner.temp }}/out
|
|
if-no-files-found: ignore
|
|
overwrite: true
|
|
|
|
publish:
|
|
needs: sync
|
|
if: needs.sync.outputs.branch != '' && !(github.event_name == 'workflow_dispatch' && inputs.dry_run)
|
|
runs-on: ubuntu-24.04
|
|
timeout-minutes: 15
|
|
permissions:
|
|
contents: write
|
|
pull-requests: write
|
|
env:
|
|
BRANCH: ${{ needs.sync.outputs.branch }}
|
|
HEAD_SHA: ${{ needs.sync.outputs.head_sha }}
|
|
GH_TOKEN: ${{ github.token }}
|
|
steps:
|
|
- name: Checkout libbpf
|
|
uses: actions/checkout@v7
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Download sync results
|
|
uses: actions/download-artifact@v7
|
|
with:
|
|
name: libbpf-sync-${{ github.run_id }}
|
|
path: ${{ runner.temp }}/out
|
|
|
|
- name: Push sync branch and open pull request
|
|
run: |
|
|
out="${RUNNER_TEMP}/out"
|
|
if [[ "${BRANCH}" != libbpf-sync-* ]]; then
|
|
echo "::error::Unexpected sync branch name '${BRANCH}'"
|
|
exit 1
|
|
fi
|
|
|
|
git bundle verify -q "${out}/sync.bundle"
|
|
git fetch -q "${out}/sync.bundle" "refs/heads/${BRANCH}:refs/heads/${BRANCH}"
|
|
if [ "$(git rev-parse "refs/heads/${BRANCH}")" != "${HEAD_SHA}" ]; then
|
|
echo "::error::Sync bundle doesn't match ${HEAD_SHA}"
|
|
exit 1
|
|
fi
|
|
|
|
# A sync pull request could have been opened while the sync was running
|
|
open=$(gh pr list --base master --state open --limit 1000 \
|
|
--json headRefName,url \
|
|
--jq '[.[] | select(.headRefName | startswith("libbpf-sync-")) | .url] | join(" ")')
|
|
if [ -n "${open}" ]; then
|
|
echo "::notice::Sync pull request already open, not publishing: ${open}"
|
|
exit 0
|
|
fi
|
|
|
|
git push origin "refs/heads/${BRANCH}:refs/heads/${BRANCH}"
|
|
title="Libbpf sync $(TZ=UTC git log -n1 --format=%cd --date=format-local:%Y-%m-%dT%H:%M:%SZ "refs/heads/${BRANCH}")"
|
|
if ! gh pr create --base master --head "${BRANCH}" --title "${title}" \
|
|
--body-file "${out}/pr-body.md"; then
|
|
echo "::error::Failed to open a pull request, deleting ${BRANCH}"
|
|
git push origin --delete "${BRANCH}"
|
|
exit 1
|
|
fi
|