Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
324 changes: 324 additions & 0 deletions .github/workflows/clk-rebase.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,324 @@
name: CLK Rebase
on:
workflow_dispatch:
repository_dispatch:
types:
- stable-branch-updated

permissions:
contents: write
pull-requests: write

jobs:
clk-rebase:
runs-on: kernel-build
container:
image: rockylinux:9
options: --cpus 8 --privileged
env:
# For repository_dispatch events, use the branch from the payload
# For workflow_dispatch, default to stable_6.18.y
STABLE_TRACKING_BRANCH: ${{ github.event.client_payload.branch || 'stable_6.18.y' }}
steps:
- name: Validate branch name
run: |
# Ensure branch name only contains allowed characters
if ! echo "$STABLE_TRACKING_BRANCH" | grep -qE '^stable_[0-9]+\.[0-9]+\.y$'; then
echo "ERROR: Invalid STABLE_TRACKING_BRANCH format: $STABLE_TRACKING_BRANCH"
echo "Expected format: stable_X.Y.y (e.g., stable_6.18.y)"
exit 1
fi
echo "Branch name validated: $STABLE_TRACKING_BRANCH"

- name: Generate GitHub App token
id: generate-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
repositories: |
kernel-src-tree
kernel-src-tree-tools

- name: Set version variables
run: |
set -e # Exit on any error
# Extract version from STABLE_TRACKING_BRANCH (e.g., stable_6.12.y -> 6.12.y)
STABLE_BASE_VERSION=$(echo "$STABLE_TRACKING_BRANCH" | sed 's/^stable_//')
echo "STABLE_BASE_VERSION=$STABLE_BASE_VERSION" >> $GITHUB_ENV

# Construct branch names from the base version
echo "CLK_BRANCH=ciq-$STABLE_BASE_VERSION" >> $GITHUB_ENV
echo "CLK_NEXT_BRANCH=ciq-${STABLE_BASE_VERSION}-next" >> $GITHUB_ENV
echo "TMP_CLK_NEXT_BRANCH={automation_tmp}_ciq-${STABLE_BASE_VERSION}-next" >> $GITHUB_ENV
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TMP_CLK_NEXT_BRANCH variable has a typo in the prefix. It uses "{automation_tmp}" with curly braces instead of a proper variable expansion or prefix format. This should likely be "automation_tmp_ciq-${STABLE_BASE_VERSION}-next" without the curly braces.

Suggested change
echo "TMP_CLK_NEXT_BRANCH={automation_tmp}_ciq-${STABLE_BASE_VERSION}-next" >> $GITHUB_ENV
echo "TMP_CLK_NEXT_BRANCH=automation_tmp_ciq-${STABLE_BASE_VERSION}-next" >> $GITHUB_ENV

Copilot uses AI. Check for mistakes.

- name: Install system dependencies
run: |
dnf install epel-release -y
dnf groupinstall 'Development Tools' -y
dnf install --enablerepo=crb bc dwarves elfutils-libelf-devel grubby grub2-tools iproute jq kernel-devel openssl-devel qemu-kvm sudo virtme-ng -y

# kernel_kselftest.sh calls sudo even when running as root
# Allow sudo to work without warnings in these cases
echo "root ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers

# Install GitHub CLI
dnf install 'dnf-command(config-manager)' -y
dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo
dnf install gh -y

# the vm has curl-minimal installed. kernel_kselftest will balk when
# it tries to install full curl later. Install the full version now
# with --allowerasing
dnf install curl --allowerasing -y

# work around install issue with iputils under vng
dnf install -y --setopt=tsflags=nocaps iputils

- name: Checkout kernel-src-tree
uses: actions/checkout@v4
with:
repository: ctrliq/kernel-src-tree
token: ${{ steps.generate-token.outputs.token }}
path: kernel-src-tree
fetch-depth: 0
persist-credentials: true

- name: Checkout kernel-src-tree-tools
uses: actions/checkout@v4
with:
repository: ctrliq/kernel-src-tree-tools
token: ${{ steps.generate-token.outputs.token }}
path: kernel-src-tree-tools
persist-credentials: true

- name: Configure git
run: |
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"

- name: Perform rebase
run: |
set -e # Exit on any error
cd kernel-src-tree

git checkout $STABLE_TRACKING_BRANCH
git checkout $CLK_BRANCH

# Run rebase script and verify it succeeded
if ! ../kernel-src-tree-tools/lt_rebase.sh $STABLE_TRACKING_BRANCH; then
echo "ERROR: Rebase failed"
exit 1
fi

echo "Rebase completed successfully"

- name: Build kernel
run: |
set -e # Exit on any error
cd kernel-src-tree

# need some config tweaks for vng
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_VSOCKETS
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_VIRTIO_VSOCKETS
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_VIRTIO_VSOCKETS_COMMON
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_NET_9P
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_NET_9P_FD
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_NET_9P_VIRTIO
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_FAILOVER
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_BLK_DEV_SD
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_SCSI_VIRTIO
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_VIRTIO_NET
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_NET_FAILOVER
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_VIRTIO_CONSOLE
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_I6300ESB_WDT
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_VIRTIO_BALLOON
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_VIRTIO_MMIO
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_FUSE_FS
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_VIRTIO_FS
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_OVERLAY_FS
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_NETFS_SUPPORT
./scripts/config --file ./ciq/configs/kernel-x86_64.config --enable CONFIG_9P_FS

../kernel-src-tree-tools/kernel_build.sh --skip-kabi --no-reboot | tee ../build.log

- name: Run selftests
run: |
set -e # Exit on any error
cd kernel-src-tree

vng --qemu /usr/libexec/qemu-kvm --force-initramfs --disable-microvm --rw --network user --verbose --memory 16G -- ../kernel-src-tree-tools/kernel_kselftest.sh

- name: Generate fresh token for push and PR
id: generate-push-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
repositories: |
kernel-src-tree

- name: Extract results and push branches
env:
PUSH_TOKEN: ${{ steps.generate-push-token.outputs.token }}
run: |
set -e # Exit on any error
cd kernel-src-tree

echo "Selftests passed:"
OK_TESTS=$(grep -a ^ok ../kselftest-logs/selftest* 2>/dev/null | wc -l || echo "0")
echo $OK_TESTS

# Extract the stable version we rebased onto
STABLE_VERSION=$(git log -1 --format=%s $STABLE_TRACKING_BRANCH | grep -oP 'Linux \K[0-9]+\.[0-9]+\.[0-9]+' || echo "unknown")
echo "Rebased to stable version: $STABLE_VERSION"

# Clear any cached credentials
git config --unset-all http.https://github.com/.extraheader || true

# Configure git to use the token via URL insteadOf (GitHub Actions recommended method)
git config --global url."https://x-access-token:${PUSH_TOKEN}@github.com/".insteadOf "https://github.com/"

# Push the branches
git push origin $CLK_NEXT_BRANCH
git push origin $TMP_CLK_NEXT_BRANCH
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow pushes both CLK_NEXT_BRANCH and TMP_CLK_NEXT_BRANCH at lines 183-184, but there's no check to verify whether these branches already exist or if the push will be a fast-forward. If TMP_CLK_NEXT_BRANCH already exists from a previous failed run, the push might fail. Consider using git push --force for the temporary branch or checking/deleting it before pushing.

Suggested change
git push origin $TMP_CLK_NEXT_BRANCH
git push --force origin $TMP_CLK_NEXT_BRANCH

Copilot uses AI. Check for mistakes.

# Check for config changes
# Look for a commit at HEAD with message like "[CIQ] v6.12.29 - rebased configs"
# that matches the stable version we're rebasing onto
HEAD_COMMIT_MSG=$(git log -1 --format=%s HEAD)
if echo "$HEAD_COMMIT_MSG" | grep -qF "[CIQ] v${STABLE_VERSION} - rebased configs"; then
echo "Config change commit detected for v${STABLE_VERSION}"
# Extract the config changes from the commit
git show HEAD --stat > ../config_changes.txt
else
echo "No config change commit detected for v${STABLE_VERSION}"
echo "None" > ../config_changes.txt
fi

# Save data for PR creation
echo "$STABLE_VERSION" > ../stable_version.txt
echo "$OK_TESTS" > ../ok_tests.txt

- name: Upload selftest logs
if: always()
uses: actions/upload-artifact@v4
with:
name: kselftest-logs
path: kselftest-logs/selftest*
if-no-files-found: warn

- name: Upload build log
if: always()
uses: actions/upload-artifact@v4
with:
name: build-log
path: build.log
if-no-files-found: warn

- name: Fetch previous PR kselftest results
if: success()
env:
GH_TOKEN: ${{ steps.generate-push-token.outputs.token }}
run: |
set -e # Exit on any error
cd kernel-src-tree

# Extract the major.minor version for matching (e.g., "6.12" from "6.12.y")
CLK_VERSION=$(echo "$STABLE_BASE_VERSION" | grep -oP '^\d+\.\d+')
echo "Looking for previous [CIQ ${CLK_VERSION}] PR..."

# Find the most recent merged PR to the same base branch with matching CIQ version
if PREVIOUS_PR=$(gh pr list \
--repo ${{ github.repository }} \
--base ${CLK_NEXT_BRANCH} \
--state merged \
--limit 10 \
--json number,title,body,mergedAt \
--jq "map(select(.title | contains(\"[CIQ ${CLK_VERSION}]\"))) | sort_by(.mergedAt) | reverse | .[0]" 2>&1); then

if [ -n "$PREVIOUS_PR" ] && [ "$PREVIOUS_PR" != "null" ]; then
# Extract the test count from the previous PR body
PREVIOUS_PR_BODY=$(echo "$PREVIOUS_PR" | jq -r '.body')
PREVIOUS_OK_TESTS=$(echo "$PREVIOUS_PR_BODY" | grep -oP 'Selftests passed:\s+\*\*\K[0-9]+' || echo "unknown")
PREVIOUS_PR_NUMBER=$(echo "$PREVIOUS_PR" | jq -r '.number')

echo "Found previous PR #${PREVIOUS_PR_NUMBER} with ${PREVIOUS_OK_TESTS} passing tests"
echo "$PREVIOUS_OK_TESTS" > ../previous_ok_tests.txt
echo "$PREVIOUS_PR_NUMBER" > ../previous_pr_number.txt
else
echo "No previous [CIQ ${CLK_VERSION}] PR found"
echo "unknown" > ../previous_ok_tests.txt
echo "N/A" > ../previous_pr_number.txt
fi
else
echo "WARNING: Failed to fetch previous PR information: $PREVIOUS_PR"
echo "unknown" > ../previous_ok_tests.txt
echo "N/A" > ../previous_pr_number.txt
fi

- name: Create Pull Request
if: success()
env:
GH_TOKEN: ${{ steps.generate-push-token.outputs.token }}
run: |
set -e # Exit on any error
cd kernel-src-tree

STABLE_VERSION=$(cat ../stable_version.txt)
OK_TESTS=$(cat ../ok_tests.txt)
CONFIG_CHANGES=$(cat ../config_changes.txt)
PREVIOUS_OK_TESTS=$(cat ../previous_ok_tests.txt)
PREVIOUS_PR_NUMBER=$(cat ../previous_pr_number.txt)

# Extract the major.minor version for the PR title (e.g., "6.12" from "6.12.y")
CLK_VERSION=$(echo "$STABLE_BASE_VERSION" | grep -oP '^\d+\.\d+')

# Extract abbreviated build log (first 20 and last 20 lines)
BUILD_LOG_SUMMARY=$(egrep -B 5 -A 5 "\[TIMER\]|^Starting Build" ../build.log)
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The egrep command uses "[TIMER]|^Starting Build" pattern but doesn't handle the case where neither pattern matches, which would result in an empty BUILD_LOG_SUMMARY. This could lead to an empty code block in the PR. Consider adding error handling or a fallback message if the patterns don't match.

Suggested change
BUILD_LOG_SUMMARY=$(egrep -B 5 -A 5 "\[TIMER\]|^Starting Build" ../build.log)
if egrep -B 5 -A 5 "\[TIMER\]|^Starting Build" ../build.log > /tmp/build_log_summary.txt; then
BUILD_LOG_SUMMARY=$(cat /tmp/build_log_summary.txt)
else
BUILD_LOG_SUMMARY="No matching build log markers found in build.log; please refer to the full build log artifact for details."
fi

Copilot uses AI. Check for mistakes.

# Get artifact URLs (will be available after workflow completes)
RUN_ID="${{ github.run_id }}"
REPO="${{ github.repository }}"
SELFTEST_ARTIFACT_URL="https://github.com/${REPO}/actions/runs/${RUN_ID}"
BUILD_LOG_ARTIFACT_URL="https://github.com/${REPO}/actions/runs/${RUN_ID}"

# Build previous test results line if available
if [ "$PREVIOUS_OK_TESTS" != "unknown" ] && [ "$PREVIOUS_PR_NUMBER" != "N/A" ]; then
PREVIOUS_TEST_LINE="Previous: ${PREVIOUS_OK_TESTS} tests ([PR #${PREVIOUS_PR_NUMBER}](https://github.com/${{ github.repository }}/pull/${PREVIOUS_PR_NUMBER}))"
else
PREVIOUS_TEST_LINE=""
fi

# Create PR body
cat > /tmp/pr_body.md <<EOF
## Automated Rebase to v${STABLE_VERSION}

### Config Changes
\`\`\`
${CONFIG_CHANGES}
\`\`\`

### Build Log
\`\`\`
${BUILD_LOG_SUMMARY}
\`\`\`

### Testing
Selftests passed: **${OK_TESTS}** tests
${PREVIOUS_TEST_LINE}

### Artifacts
- [Build Log](${BUILD_LOG_ARTIFACT_URL})
- [Selftest Logs](${SELFTEST_ARTIFACT_URL})

EOF

# Create the PR
gh pr create \
--title "[CIQ ${CLK_VERSION}] Rebase to v${STABLE_VERSION}" \
--body-file /tmp/pr_body.md \
--base ${CLK_NEXT_BRANCH} \
--head ${TMP_CLK_NEXT_BRANCH} \
--reviewer bmastbergen

Comment on lines +317 to +324
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The gh pr create command doesn't handle the case where a PR from TMP_CLK_NEXT_BRANCH to CLK_NEXT_BRANCH already exists. If the workflow runs multiple times before a PR is merged, subsequent runs will fail at this step with an error about a PR already existing. Consider adding logic to check for existing PRs and either update them or skip PR creation with a message.

Suggested change
# Create the PR
gh pr create \
--title "[CIQ ${CLK_VERSION}] Rebase to v${STABLE_VERSION}" \
--body-file /tmp/pr_body.md \
--base ${CLK_NEXT_BRANCH} \
--head ${TMP_CLK_NEXT_BRANCH} \
--reviewer bmastbergen
# Check for an existing open PR from TMP_CLK_NEXT_BRANCH to CLK_NEXT_BRANCH
EXISTING_PR_NUMBER=$(gh pr list \
--base "${CLK_NEXT_BRANCH}" \
--head "${TMP_CLK_NEXT_BRANCH}" \
--state open \
--json number \
--jq '.[0].number' || true)
if [ -n "${EXISTING_PR_NUMBER}" ]; then
echo "Found existing PR #${EXISTING_PR_NUMBER} from ${TMP_CLK_NEXT_BRANCH} to ${CLK_NEXT_BRANCH}; updating title and body."
gh pr edit "${EXISTING_PR_NUMBER}" \
--title "[CIQ ${CLK_VERSION}] Rebase to v${STABLE_VERSION}" \
--body-file /tmp/pr_body.md
else
echo "No existing PR from ${TMP_CLK_NEXT_BRANCH} to ${CLK_NEXT_BRANCH}; creating a new one."
gh pr create \
--title "[CIQ ${CLK_VERSION}] Rebase to v${STABLE_VERSION}" \
--body-file /tmp/pr_body.md \
--base ${CLK_NEXT_BRANCH} \
--head ${TMP_CLK_NEXT_BRANCH} \
--reviewer bmastbergen
fi

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't a terrible idea

25 changes: 24 additions & 1 deletion .github/workflows/sync.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,30 @@ jobs:

git remote add upstream ${REMOTE}
git fetch upstream --tags --quiet

# Check if rebase will make changes
BEFORE_SHA=$(git rev-parse HEAD)
git rebase upstream/${REMOTE_BRANCH}
git push origin --follow-tags
AFTER_SHA=$(git rev-parse HEAD)

if [ "$BEFORE_SHA" != "$AFTER_SHA" ]; then
echo "Changes detected, pushing..."
git push origin --follow-tags
echo "CHANGES_PUSHED=true" >> $GITHUB_ENV
else
echo "No changes to push"
echo "CHANGES_PUSHED=false" >> $GITHUB_ENV
fi

- name: Trigger CLK rebase workflow
if: env.CHANGES_PUSHED == 'true' && startsWith(matrix.branch, 'stable_')
run: |
curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/${{ github.repository }}/dispatches \
-d "{\"event_type\":\"stable-branch-updated\",\"client_payload\":{\"branch\":\"${{ matrix.branch }}\"}}"
Comment on lines +78 to +84
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The repository_dispatch API call doesn't check for errors. If the curl command fails (e.g., network issues, authentication problems), the workflow will continue silently without triggering the rebase workflow. Consider adding error handling to check the HTTP response status or use the -f flag with curl to fail on HTTP errors, combined with proper error checking.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't a terrible idea