Skip to content

Commit da6f619

Browse files
committed
github actions: Add automated CLK rebase workflow
Add a new GitHub Actions workflow to automate the process of rebasing CLK kernel branches against upstream stable releases. The workflow: - Triggers on workflow_dispatch or repository_dispatch - Performs rebase using lt_rebase.sh from kernel-src-tree-tools - Builds the kernel (with virtme-ng compatible configuration tweaks) - Runs kernel selftests in a virtme-ng vm - Creates a pull request with build logs, test results, and config changes - Tracks test pass rates across rebase iterations Also modifies sync.yml to trigger the rebase workflow via repository_dispatch when stable branches receive updates, creating an end-to-end automation pipeline for keeping CLK branches synchronized with upstream stable releases.
1 parent bb8ee80 commit da6f619

2 files changed

Lines changed: 348 additions & 1 deletion

File tree

.github/workflows/clk-rebase.yml

Lines changed: 324 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,324 @@
1+
name: CLK Rebase
2+
on:
3+
workflow_dispatch:
4+
repository_dispatch:
5+
types:
6+
- stable-branch-updated
7+
8+
permissions:
9+
contents: write
10+
pull-requests: write
11+
12+
jobs:
13+
clk-rebase:
14+
runs-on: kernel-build
15+
container:
16+
image: rockylinux:9
17+
options: --cpus 8 --privileged
18+
env:
19+
# For repository_dispatch events, use the branch from the payload
20+
# For workflow_dispatch, default to stable_6.18.y
21+
STABLE_TRACKING_BRANCH: ${{ github.event.client_payload.branch || 'stable_6.18.y' }}
22+
steps:
23+
- name: Validate branch name
24+
run: |
25+
# Ensure branch name only contains allowed characters
26+
if ! echo "$STABLE_TRACKING_BRANCH" | grep -qE '^stable_[0-9]+\.[0-9]+\.y$'; then
27+
echo "ERROR: Invalid STABLE_TRACKING_BRANCH format: $STABLE_TRACKING_BRANCH"
28+
echo "Expected format: stable_X.Y.y (e.g., stable_6.18.y)"
29+
exit 1
30+
fi
31+
echo "Branch name validated: $STABLE_TRACKING_BRANCH"
32+
33+
- name: Generate GitHub App token
34+
id: generate-token
35+
uses: actions/create-github-app-token@v1
36+
with:
37+
app-id: ${{ secrets.APP_ID }}
38+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
39+
repositories: |
40+
kernel-src-tree
41+
kernel-src-tree-tools
42+
43+
- name: Set version variables
44+
run: |
45+
set -e # Exit on any error
46+
# Extract version from STABLE_TRACKING_BRANCH (e.g., stable_6.12.y -> 6.12.y)
47+
STABLE_BASE_VERSION=$(echo "$STABLE_TRACKING_BRANCH" | sed 's/^stable_//')
48+
echo "STABLE_BASE_VERSION=$STABLE_BASE_VERSION" >> $GITHUB_ENV
49+
50+
# Construct branch names from the base version
51+
echo "CLK_BRANCH=ciq-$STABLE_BASE_VERSION" >> $GITHUB_ENV
52+
echo "CLK_NEXT_BRANCH=ciq-${STABLE_BASE_VERSION}-next" >> $GITHUB_ENV
53+
echo "TMP_CLK_NEXT_BRANCH={automation_tmp}_ciq-${STABLE_BASE_VERSION}-next" >> $GITHUB_ENV
54+
55+
- name: Install system dependencies
56+
run: |
57+
dnf install epel-release -y
58+
dnf groupinstall 'Development Tools' -y
59+
dnf install --enablerepo=crb bc dwarves elfutils-libelf-devel grubby grub2-tools iproute jq kernel-devel openssl-devel qemu-kvm sudo virtme-ng -y
60+
61+
# kernel_kselftest.sh calls sudo even when running as root
62+
# Allow sudo to work without warnings in these cases
63+
echo "root ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers
64+
65+
# Install GitHub CLI
66+
dnf install 'dnf-command(config-manager)' -y
67+
dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo
68+
dnf install gh -y
69+
70+
# the vm has curl-minimal installed. kernel_kselftest will balk when
71+
# it tries to install full curl later. Install the full version now
72+
# with --allowerasing
73+
dnf install curl --allowerasing -y
74+
75+
# work around install issue with iputils under vng
76+
dnf install -y --setopt=tsflags=nocaps iputils
77+
78+
- name: Checkout kernel-src-tree
79+
uses: actions/checkout@v4
80+
with:
81+
repository: ctrliq/kernel-src-tree
82+
token: ${{ steps.generate-token.outputs.token }}
83+
path: kernel-src-tree
84+
fetch-depth: 0
85+
persist-credentials: true
86+
87+
- name: Checkout kernel-src-tree-tools
88+
uses: actions/checkout@v4
89+
with:
90+
repository: ctrliq/kernel-src-tree-tools
91+
token: ${{ steps.generate-token.outputs.token }}
92+
path: kernel-src-tree-tools
93+
persist-credentials: true
94+
95+
- name: Configure git
96+
run: |
97+
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
98+
git config --global user.name "github-actions[bot]"
99+
100+
- name: Perform rebase
101+
run: |
102+
set -e # Exit on any error
103+
cd kernel-src-tree
104+
105+
git checkout $STABLE_TRACKING_BRANCH
106+
git checkout $CLK_BRANCH
107+
108+
# Run rebase script and verify it succeeded
109+
if ! ../kernel-src-tree-tools/lt_rebase.sh $STABLE_TRACKING_BRANCH; then
110+
echo "ERROR: Rebase failed"
111+
exit 1
112+
fi
113+
114+
echo "Rebase completed successfully"
115+
116+
- name: Build kernel
117+
run: |
118+
set -e # Exit on any error
119+
cd kernel-src-tree
120+
121+
# need some config tweaks for vng
122+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_VSOCKETS
123+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_VIRTIO_VSOCKETS
124+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_VIRTIO_VSOCKETS_COMMON
125+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_NET_9P
126+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_NET_9P_FD
127+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_NET_9P_VIRTIO
128+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_FAILOVER
129+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_BLK_DEV_SD
130+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_SCSI_VIRTIO
131+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_VIRTIO_NET
132+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_NET_FAILOVER
133+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_VIRTIO_CONSOLE
134+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_I6300ESB_WDT
135+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_VIRTIO_BALLOON
136+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_VIRTIO_MMIO
137+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_FUSE_FS
138+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_VIRTIO_FS
139+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_OVERLAY_FS
140+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_NETFS_SUPPORT
141+
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_9P_FS
142+
143+
../kernel-src-tree-tools/kernel_build.sh --skip-kabi --no-reboot | tee ../build.log
144+
145+
- name: Run selftests
146+
run: |
147+
set -e # Exit on any error
148+
cd kernel-src-tree
149+
150+
vng --qemu /usr/libexec/qemu-kvm --force-initramfs --disable-microvm --rw --network user --verbose --memory 16G -- ../kernel-src-tree-tools/kernel_kselftest.sh
151+
152+
- name: Generate fresh token for push and PR
153+
id: generate-push-token
154+
uses: actions/create-github-app-token@v1
155+
with:
156+
app-id: ${{ secrets.APP_ID }}
157+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
158+
repositories: |
159+
kernel-src-tree
160+
161+
- name: Extract results and push branches
162+
env:
163+
PUSH_TOKEN: ${{ steps.generate-push-token.outputs.token }}
164+
run: |
165+
set -e # Exit on any error
166+
cd kernel-src-tree
167+
168+
echo "Selftests passed:"
169+
OK_TESTS=$(grep -a ^ok ../kselftest-logs/selftest* 2>/dev/null | wc -l || echo "0")
170+
echo $OK_TESTS
171+
172+
# Extract the stable version we rebased onto
173+
STABLE_VERSION=$(git log -1 --format=%s $STABLE_TRACKING_BRANCH | grep -oP 'Linux \K[0-9]+\.[0-9]+\.[0-9]+' || echo "unknown")
174+
echo "Rebased to stable version: $STABLE_VERSION"
175+
176+
# Clear any cached credentials
177+
git config --unset-all http.https://github.com/.extraheader || true
178+
179+
# Configure git to use the token via URL insteadOf (GitHub Actions recommended method)
180+
git config --global url."https://x-access-token:${PUSH_TOKEN}@github.com/".insteadOf "https://github.com/"
181+
182+
# Push the branches
183+
git push origin $CLK_NEXT_BRANCH
184+
git push origin $TMP_CLK_NEXT_BRANCH
185+
186+
# Check for config changes
187+
# Look for a commit at HEAD with message like "[CIQ] v6.12.29 - rebased configs"
188+
# that matches the stable version we're rebasing onto
189+
HEAD_COMMIT_MSG=$(git log -1 --format=%s HEAD)
190+
if echo "$HEAD_COMMIT_MSG" | grep -qF "[CIQ] v${STABLE_VERSION} - rebased configs"; then
191+
echo "Config change commit detected for v${STABLE_VERSION}"
192+
# Extract the config changes from the commit
193+
git show HEAD --stat > ../config_changes.txt
194+
else
195+
echo "No config change commit detected for v${STABLE_VERSION}"
196+
echo "None" > ../config_changes.txt
197+
fi
198+
199+
# Save data for PR creation
200+
echo "$STABLE_VERSION" > ../stable_version.txt
201+
echo "$OK_TESTS" > ../ok_tests.txt
202+
203+
- name: Upload selftest logs
204+
if: always()
205+
uses: actions/upload-artifact@v4
206+
with:
207+
name: kselftest-logs
208+
path: kselftest-logs/selftest*
209+
if-no-files-found: warn
210+
211+
- name: Upload build log
212+
if: always()
213+
uses: actions/upload-artifact@v4
214+
with:
215+
name: build-log
216+
path: build.log
217+
if-no-files-found: warn
218+
219+
- name: Fetch previous PR kselftest results
220+
if: success()
221+
env:
222+
GH_TOKEN: ${{ steps.generate-push-token.outputs.token }}
223+
run: |
224+
set -e # Exit on any error
225+
cd kernel-src-tree
226+
227+
# Extract the major.minor version for matching (e.g., "6.12" from "6.12.y")
228+
CLK_VERSION=$(echo "$STABLE_BASE_VERSION" | grep -oP '^\d+\.\d+')
229+
echo "Looking for previous [CIQ ${CLK_VERSION}] PR..."
230+
231+
# Find the most recent merged PR to the same base branch with matching CIQ version
232+
if PREVIOUS_PR=$(gh pr list \
233+
--repo ${{ github.repository }} \
234+
--base ${CLK_NEXT_BRANCH} \
235+
--state merged \
236+
--limit 10 \
237+
--json number,title,body,mergedAt \
238+
--jq "map(select(.title | contains(\"[CIQ ${CLK_VERSION}]\"))) | sort_by(.mergedAt) | reverse | .[0]" 2>&1); then
239+
240+
if [ -n "$PREVIOUS_PR" ] && [ "$PREVIOUS_PR" != "null" ]; then
241+
# Extract the test count from the previous PR body
242+
PREVIOUS_PR_BODY=$(echo "$PREVIOUS_PR" | jq -r '.body')
243+
PREVIOUS_OK_TESTS=$(echo "$PREVIOUS_PR_BODY" | grep -oP 'Selftests passed:\s+\*\*\K[0-9]+' || echo "unknown")
244+
PREVIOUS_PR_NUMBER=$(echo "$PREVIOUS_PR" | jq -r '.number')
245+
246+
echo "Found previous PR #${PREVIOUS_PR_NUMBER} with ${PREVIOUS_OK_TESTS} passing tests"
247+
echo "$PREVIOUS_OK_TESTS" > ../previous_ok_tests.txt
248+
echo "$PREVIOUS_PR_NUMBER" > ../previous_pr_number.txt
249+
else
250+
echo "No previous [CIQ ${CLK_VERSION}] PR found"
251+
echo "unknown" > ../previous_ok_tests.txt
252+
echo "N/A" > ../previous_pr_number.txt
253+
fi
254+
else
255+
echo "WARNING: Failed to fetch previous PR information: $PREVIOUS_PR"
256+
echo "unknown" > ../previous_ok_tests.txt
257+
echo "N/A" > ../previous_pr_number.txt
258+
fi
259+
260+
- name: Create Pull Request
261+
if: success()
262+
env:
263+
GH_TOKEN: ${{ steps.generate-push-token.outputs.token }}
264+
run: |
265+
set -e # Exit on any error
266+
cd kernel-src-tree
267+
268+
STABLE_VERSION=$(cat ../stable_version.txt)
269+
OK_TESTS=$(cat ../ok_tests.txt)
270+
CONFIG_CHANGES=$(cat ../config_changes.txt)
271+
PREVIOUS_OK_TESTS=$(cat ../previous_ok_tests.txt)
272+
PREVIOUS_PR_NUMBER=$(cat ../previous_pr_number.txt)
273+
274+
# Extract the major.minor version for the PR title (e.g., "6.12" from "6.12.y")
275+
CLK_VERSION=$(echo "$STABLE_BASE_VERSION" | grep -oP '^\d+\.\d+')
276+
277+
# Extract abbreviated build log (first 20 and last 20 lines)
278+
BUILD_LOG_SUMMARY=$(egrep -B 5 -A 5 "\[TIMER\]|^Starting Build" ../build.log)
279+
280+
# Get artifact URLs (will be available after workflow completes)
281+
RUN_ID="${{ github.run_id }}"
282+
REPO="${{ github.repository }}"
283+
SELFTEST_ARTIFACT_URL="https://github.com/${REPO}/actions/runs/${RUN_ID}"
284+
BUILD_LOG_ARTIFACT_URL="https://github.com/${REPO}/actions/runs/${RUN_ID}"
285+
286+
# Build previous test results line if available
287+
if [ "$PREVIOUS_OK_TESTS" != "unknown" ] && [ "$PREVIOUS_PR_NUMBER" != "N/A" ]; then
288+
PREVIOUS_TEST_LINE="Previous: ${PREVIOUS_OK_TESTS} tests ([PR #${PREVIOUS_PR_NUMBER}](https://github.com/${{ github.repository }}/pull/${PREVIOUS_PR_NUMBER}))"
289+
else
290+
PREVIOUS_TEST_LINE=""
291+
fi
292+
293+
# Create PR body
294+
cat > /tmp/pr_body.md <<EOF
295+
## Automated Rebase to v${STABLE_VERSION}
296+
297+
### Config Changes
298+
\`\`\`
299+
${CONFIG_CHANGES}
300+
\`\`\`
301+
302+
### Build Log
303+
\`\`\`
304+
${BUILD_LOG_SUMMARY}
305+
\`\`\`
306+
307+
### Testing
308+
Selftests passed: **${OK_TESTS}** tests
309+
${PREVIOUS_TEST_LINE}
310+
311+
### Artifacts
312+
- [Build Log](${BUILD_LOG_ARTIFACT_URL})
313+
- [Selftest Logs](${SELFTEST_ARTIFACT_URL})
314+
315+
EOF
316+
317+
# Create the PR
318+
gh pr create \
319+
--title "[CIQ ${CLK_VERSION}] Rebase to v${STABLE_VERSION}" \
320+
--body-file /tmp/pr_body.md \
321+
--base ${CLK_NEXT_BRANCH} \
322+
--head ${TMP_CLK_NEXT_BRANCH} \
323+
--reviewer bmastbergen
324+

.github/workflows/sync.yml

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,30 @@ jobs:
5757
5858
git remote add upstream ${REMOTE}
5959
git fetch upstream --tags --quiet
60+
61+
# Check if rebase will make changes
62+
BEFORE_SHA=$(git rev-parse HEAD)
6063
git rebase upstream/${REMOTE_BRANCH}
61-
git push origin --follow-tags
64+
AFTER_SHA=$(git rev-parse HEAD)
65+
66+
if [ "$BEFORE_SHA" != "$AFTER_SHA" ]; then
67+
echo "Changes detected, pushing..."
68+
git push origin --follow-tags
69+
echo "CHANGES_PUSHED=true" >> $GITHUB_ENV
70+
else
71+
echo "No changes to push"
72+
echo "CHANGES_PUSHED=false" >> $GITHUB_ENV
73+
fi
74+
75+
- name: Trigger CLK rebase workflow
76+
if: env.CHANGES_PUSHED == 'true' && startsWith(matrix.branch, 'stable_')
77+
run: |
78+
curl -L \
79+
-X POST \
80+
-H "Accept: application/vnd.github+json" \
81+
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
82+
-H "X-GitHub-Api-Version: 2022-11-28" \
83+
https://api.github.com/repos/${{ github.repository }}/dispatches \
84+
-d "{\"event_type\":\"stable-branch-updated\",\"client_payload\":{\"branch\":\"${{ matrix.branch }}\"}}"
6285
6386

0 commit comments

Comments
 (0)