-
Notifications
You must be signed in to change notification settings - Fork 10
Add reusable validate kernel commits workflow #649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
bmastbergen
merged 10 commits into
main
from
bmastbergen_main-add-reusable-validate-kernel-commits
Nov 5, 2025
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
a34b16f
github actions: Add reusable workflow for validating kernel commits
bmastbergen 60c0269
github actions: validate-kernel-commits: Add --check-cves
bmastbergen c161fd1
github actions: validate-kernel-commits: Add interdiff
bmastbergen 49f5ed2
github actions: validate-kernel-commits: Clone kernel-src-tree-tools
bmastbergen ac3c8b2
github actions: Add JIRA PR Check
bmastbergen 40d2d45
github actions: Give ckc results a unique name
bmastbergen 82dc114
github actions: Convert github-script usage to gh
bmastbergen 853f587
github actions: Wrap long command lines for readability
bmastbergen 2f0a577
github actions: Add 120 minute timeout
bmastbergen 6acca96
github actions: Get the correct return code
bmastbergen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,238 @@ | ||
| name: Validate Kernel Commits | ||
|
|
||
| on: | ||
| workflow_call: | ||
| # No inputs needed - uses github context from caller | ||
|
|
||
| permissions: | ||
| contents: read | ||
| pull-requests: write | ||
|
|
||
| jobs: | ||
| validate-kernel-commits: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 120 | ||
|
|
||
| steps: | ||
| - name: Checkout PR branch | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
| ref: ${{ github.head_ref }} | ||
|
|
||
| - name: Checkout base branch | ||
| run: | | ||
| git fetch origin ${{ github.base_ref }}:${{ github.base_ref }} | ||
|
|
||
| - name: Checkout kernel-src-tree-tools | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: ctrliq/kernel-src-tree-tools | ||
| ref: 'mainline' | ||
| path: kernel-src-tree-tools | ||
|
|
||
| - name: Set up Python | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: '3.x' | ||
|
|
||
| - name: Run upstream fixes check | ||
| id: check-kernel-commits | ||
| working-directory: kernel-src-tree-tools | ||
| run: | | ||
| set +e # Don't exit on error, we want to capture the output | ||
| set -o pipefail # Capture exit code from python script, not tee | ||
| python3 check_kernel_commits.py \ | ||
| --repo .. \ | ||
| --pr_branch "${{ github.head_ref }}" \ | ||
| --base_branch "${{ github.base_ref }}" \ | ||
| --markdown \ | ||
| --check-cves | tee ../ckc_result.txt | ||
| EXIT_CODE=$? | ||
kerneltoast marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # Check if the script failed | ||
| if [ $EXIT_CODE -ne 0 ]; then | ||
| echo "❌ Kernel commits check failed with exit code $EXIT_CODE" | ||
| exit $EXIT_CODE | ||
| fi | ||
|
|
||
| # Check for findings: | ||
| # 1. Verify the success message exists | ||
| # 2. If it exists, check if there are any OTHER lines (which would indicate issues) | ||
| # 3. If success message doesn't exist, that's also a finding | ||
| if grep -q "All referenced commits exist upstream and have no Fixes: tags." ../ckc_result.txt; then | ||
| # Success message found, check if there are any other lines | ||
| LINE_COUNT=$(wc -l < ../ckc_result.txt) | ||
| if [ "$LINE_COUNT" -gt 1 ]; then | ||
| echo "has_findings=true" >> $GITHUB_OUTPUT | ||
| else | ||
| echo "has_findings=false" >> $GITHUB_OUTPUT | ||
| fi | ||
| else | ||
| # Success message not found, there must be findings | ||
| echo "has_findings=true" >> $GITHUB_OUTPUT | ||
| fi | ||
|
|
||
| set -e # Re-enable exit on error | ||
|
|
||
| - name: Comment on PR if issues found | ||
| if: steps.check-kernel-commits.outputs.has_findings == 'true' | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| run: | | ||
| if ! gh pr comment ${{ github.event.pull_request.number }} \ | ||
| --body-file ckc_result.txt \ | ||
| --repo ${{ github.repository }}; then | ||
| echo "❌ Failed to post check-kernel-commits comment to PR" | ||
| exit 1 | ||
| fi | ||
|
|
||
| - name: Install build dependencies for patchutils | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y build-essential autoconf automake libtool gnulib | ||
|
|
||
| - name: Clone and build custom patchutils | ||
| run: | | ||
| git clone https://github.com/kerneltoast/patchutils.git --depth=1 --revision=32e5f1df96920f1d24beb910346f01acab8b0bd8 | ||
| cd patchutils | ||
| ./bootstrap | ||
| ./configure | ||
| make -j$(nproc) | ||
|
|
||
| - name: Run interdiff check | ||
| id: interdiff | ||
| working-directory: kernel-src-tree-tools | ||
| run: | | ||
| set +e # Don't exit on error, we want to capture the output | ||
| set -o pipefail # Capture exit code from python script, not tee | ||
| python3 run_interdiff.py \ | ||
| --repo .. \ | ||
| --pr_branch "${{ github.head_ref }}" \ | ||
| --base_branch "${{ github.base_ref }}" \ | ||
| --markdown \ | ||
| --interdiff ../patchutils/src/interdiff | tee ../interdiff_result.txt | ||
| EXIT_CODE=$? | ||
kerneltoast marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| # Check if the script failed | ||
| if [ $EXIT_CODE -ne 0 ]; then | ||
| echo "❌ Interdiff check failed with exit code $EXIT_CODE" | ||
| exit $EXIT_CODE | ||
| fi | ||
|
|
||
| # Check for differences: | ||
| # 1. Verify the success message exists | ||
| # 2. If it exists, check if there are any OTHER lines (which would indicate differences) | ||
| # 3. If success message doesn't exist, that's also a difference | ||
| if grep -q "All backported commits match their upstream counterparts." ../interdiff_result.txt; then | ||
| # Success message found, check if there are any other lines | ||
| LINE_COUNT=$(wc -l < ../interdiff_result.txt) | ||
| if [ "$LINE_COUNT" -gt 1 ]; then | ||
| echo "has_differences=true" >> $GITHUB_OUTPUT | ||
| else | ||
| echo "has_differences=false" >> $GITHUB_OUTPUT | ||
| fi | ||
| else | ||
| # Success message not found, there must be differences | ||
| echo "has_differences=true" >> $GITHUB_OUTPUT | ||
| fi | ||
|
|
||
| set -e # Re-enable exit on error | ||
|
|
||
| - name: Comment on PR if interdiff differences found | ||
| if: steps.interdiff.outputs.has_differences == 'true' | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| run: | | ||
| if ! gh pr comment ${{ github.event.pull_request.number }} \ | ||
| --body-file interdiff_result.txt \ | ||
| --repo ${{ github.repository }}; then | ||
| echo "❌ Failed to post interdiff comment to PR" | ||
| exit 1 | ||
| fi | ||
|
|
||
| - name: Install JIRA PR Check dependencies | ||
| run: | | ||
| python -m pip install --upgrade pip | ||
| pip install jira | ||
|
|
||
| - name: Mask JIRA credentials | ||
| run: | | ||
| echo "::add-mask::${{ secrets.JIRA_API_TOKEN }}" | ||
kerneltoast marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| echo "::add-mask::${{ secrets.JIRA_API_USER }}" | ||
| echo "::add-mask::${{ secrets.JIRA_URL }}" | ||
|
|
||
| - name: Run JIRA PR Check | ||
| id: jira_check | ||
| continue-on-error: true # Allow PR comments to be posted before failing workflow | ||
| env: | ||
| JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} | ||
| JIRA_API_USER: ${{ secrets.JIRA_API_USER }} | ||
| JIRA_URL: ${{ secrets.JIRA_URL }} | ||
| working-directory: kernel-src-tree-tools | ||
| run: | | ||
| # Run script and capture output, ensuring credentials are never echoed | ||
| set +x # Disable command echo to prevent credential exposure | ||
| set +e # Don't exit on error, we want to capture the output | ||
| OUTPUT=$(python3 jira_pr_check.py \ | ||
| --kernel-src-tree .. \ | ||
| --merge-target ${{ github.base_ref }} \ | ||
| --pr-branch ${{ github.head_ref }} 2>&1) | ||
| EXIT_CODE=$? | ||
|
|
||
| # Filter out any potential credential leaks from output | ||
| FILTERED_OUTPUT=$(echo "$OUTPUT" | grep -v "jira-user\|jira-key\|basic_auth\|Authorization\|$JIRA_API_TOKEN") | ||
|
|
||
| echo "$FILTERED_OUTPUT" | ||
| echo "output<<'EOF'" >> $GITHUB_OUTPUT | ||
| echo "$FILTERED_OUTPUT" >> $GITHUB_OUTPUT | ||
| echo "EOF" >> $GITHUB_OUTPUT | ||
|
|
||
| # Check if there are any issues based on output patterns | ||
| if echo "$FILTERED_OUTPUT" | grep -q "❌ Errors:"; then | ||
| echo "has_issues=true" >> $GITHUB_OUTPUT | ||
|
|
||
| # Check specifically for LTS mismatch errors | ||
| if echo "$FILTERED_OUTPUT" | grep -q "expects branch"; then | ||
| echo "has_lts_mismatch=true" >> $GITHUB_OUTPUT | ||
| else | ||
| echo "has_lts_mismatch=false" >> $GITHUB_OUTPUT | ||
| fi | ||
| elif echo "$FILTERED_OUTPUT" | grep -q "⚠️ Warnings:"; then | ||
| echo "has_issues=true" >> $GITHUB_OUTPUT | ||
| echo "has_lts_mismatch=false" >> $GITHUB_OUTPUT | ||
| else | ||
| echo "has_issues=false" >> $GITHUB_OUTPUT | ||
| echo "has_lts_mismatch=false" >> $GITHUB_OUTPUT | ||
| fi | ||
|
|
||
| # Exit with the script's exit code | ||
| exit $EXIT_CODE | ||
|
|
||
| - name: Comment PR with JIRA issues | ||
| if: steps.jira_check.outputs.has_issues == 'true' | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| run: | | ||
| if ! gh pr comment ${{ github.event.pull_request.number }} \ | ||
| --body "${{ steps.jira_check.outputs.output }}" \ | ||
| --repo ${{ github.repository }}; then | ||
| echo "❌ Failed to post JIRA check comment to PR" | ||
| exit 1 | ||
| fi | ||
|
|
||
| - name: Request changes if LTS mismatch | ||
| if: steps.jira_check.outputs.has_lts_mismatch == 'true' | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| run: | | ||
| gh pr review ${{ github.event.pull_request.number }} \ | ||
| --request-changes \ | ||
| --body "⚠️ This PR contains VULN tickets that do not match the target LTS product. Please review the JIRA ticket assignments and ensure they match the merge target branch." \ | ||
| --repo ${{ github.repository }} | ||
|
|
||
| - name: Fail workflow if JIRA errors found | ||
| if: steps.jira_check.outcome == 'failure' | ||
| run: | | ||
| echo "❌ JIRA PR check failed - errors were found in one or more commits" | ||
| exit 1 | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.