Skip to content

Commit

Permalink
actions: Force rebuilding toolchain bundles
Browse files Browse the repository at this point in the history
This prevents race condition issue when new toolchain bundle has to be
built after PR is merged

Signed-off-by: Jan Gałda <[email protected]>
  • Loading branch information
jangalda-nsc committed Nov 29, 2024
1 parent 0e1aa07 commit 17e1597
Showing 1 changed file with 121 additions and 0 deletions.
121 changes: 121 additions & 0 deletions .github/workflows/enforce-toolchain-synchronization.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Enforce rebasing Pull Requests if Toolchain was modified on target branch
#
# If new commits, which modifies toolchain files was pushed to given branch, find all PRs targeting
# this branch, which also change toolchain files. Then, enforce rebasing them by changing
# CI/Jenkins/toolchain check to FAILURE.
# This prevents race condition issue when new toolchain bundle has to be built after PR is merged.
#
# Toolchain files:
# * scripts/requirements-fixed.txt
# * scripts/tools-versions-darwin.yml
# * scripts/tools-versions-win10.yml
# * scripts/tools-versions-linux.yml

name: Enforce rebasing Pull Requests if Toolchain was modified on target branch

on:
push:
branches:
- '**' # Triggers on pushes to any branch

jobs:
check-prs:
runs-on: ubuntu-latest

steps:
- name: Define list of files to check
id: define_files
run: |
echo "TOOLCHAIN_FILES=scripts/requirements-fixed.txt,scripts/tools-versions-linux.yml,scripts/tools-versions-darwin.yml,scripts/tools-versions-win10.yml" >> $GITHUB_ENV
- name: Checkout the repository
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false

- name: Get files modified by recent commits
id: get_files
run: |
echo "Modified files in this commit:"
git diff --name-only ${{ github.event.before }} ${{ github.sha }} > modified_files.txt
cat modified_files.txt
- name: Check if any watched files are modified
id: check_files
run: |
modified_files=$(cat modified_files.txt)
IFS=',' read -r -a watched_files <<< "${{ env.TOOLCHAIN_FILES }}"
modified=false
for file in "${watched_files[@]}"; do
if echo "$modified_files" | grep -q "$file"; then
echo "$file was modified."
modified=true
fi
done
echo "modified=$modified" >> $GITHUB_ENV
# App token is required to update Check Status
- name: Get jenkins-ncs App token
if: env.modified == 'true'
uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ vars.JENKINS_NCS_APP_ID }}
private-key: ${{ secrets.JENKINS_NCS_APP_PRIVATE_KEY }}

- name: Find open pull requests targeting this branch and modyfing Toolchain files
if: env.modified == 'true'
id: find_prs
run: |
PRs=$(gh pr list --base ${{ github.ref_name }} --state open --json url,headRefName,files --jq '[.[] | select(.files[]? | .path as $file | [$file] | inside([env.TOOLCHAIN_FILES]))]')
echo "Found PRs: $PRs"
echo "prs=$PRs" >> $GITHUB_ENV
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}

- name: Set CI/Jenkins/toolchain status check to failure
if: env.modified == 'true' && steps.find_prs.outputs.prs != '[]'
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
for pr in $(echo "$prs" | jq -r '.[].url'); do
pr_url=$(echo $pr | sed 's|https://github.com/||')
pr_owner=$(echo $pr_url | cut -d'/' -f1)
pr_repo=$(echo $pr_url | cut -d'/' -f2)
pr_number=$(echo $pr_url | cut -d'/' -f4)
echo "Setting CI/Jenkins/toolchain status to failure for PR: $pr"
# Get the SHA of the last commit in the PR branch
commit_sha=$(gh pr view $pr_number --json headRefOid --jq '.headRefOid')
# Get the Check Run ID by listing the check runs for the PR's head commit
check_run_id=$(gh api \
-H "Accept: application/vnd.github.v3+json" \
/repos/$pr_owner/$pr_repo/commits/$commit_sha/check-runs \
--jq '.check_runs[] | select(.name == "CI/Jenkins/toolchain") | .id')
# If no check run exists, create a new one; otherwise, update the existing one
if [ -z "$check_run_id" ]; then
echo "Creating new check run for PR: $pr"
gh api \
-H "Accept: application/vnd.github.v3+json" \
--method POST /repos/$pr_owner/$pr_repo/check-runs \
-f name="CI/Jenkins/toolchain" \
-f head_sha="$commit_sha" \
-f status="completed" \
-f conclusion="failure" \
-f output[title]="Rebase needed - Toolchain changed on '${{ github.ref_name }}' branch" \
-f output[summary]="Toolchain was modified on '${{ github.ref_name }}' and this PR has to be rebased"
else
echo "Updating existing check run with ID $check_run_id"
gh api \
-H "Accept: application/vnd.github.v3+json" \
--method PATCH /repos/$pr_owner/$pr_repo/check-runs/$check_run_id \
-f conclusion="failure" \
-f status="completed" \
-f output[title]="Rebase needed - Toolchain changed on '${{ github.ref_name }}' branch" \
-f output[summary]="Toolchain was modified on '${{ github.ref_name }}' and this PR has to be rebased"
fi
done

0 comments on commit 17e1597

Please sign in to comment.