From 64adeac729d05874c27f497e631d960942cd8e42 Mon Sep 17 00:00:00 2001 From: Stuti Ravikiran Wali Date: Mon, 11 May 2026 00:00:57 +0530 Subject: [PATCH 1/3] Add job to check for relevant file changes Added a new job to check for relevant file changes before the build process. This job determines whether to proceed with the build based on changes to specific files like build_info.json, .sh scripts, or Dockerfile. --- .github/workflows/pr-build.yaml | 159 +++++++++++++++++++++++++++++--- 1 file changed, 146 insertions(+), 13 deletions(-) diff --git a/.github/workflows/pr-build.yaml b/.github/workflows/pr-build.yaml index b23699f2bb..7859a2f741 100644 --- a/.github/workflows/pr-build.yaml +++ b/.github/workflows/pr-build.yaml @@ -28,16 +28,69 @@ run-name: > jobs: + check_changes: + runs-on: ubuntu-latest + outputs: + should_build: ${{ steps.filter.outputs.should_build }} + changed_files: ${{ steps.filter.outputs.changed_files }} + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + + - name: Check for relevant file changes + id: filter + run: | + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + echo "should_build=true" >> $GITHUB_OUTPUT + echo "Workflow dispatch - proceeding with build" + exit 0 + fi + + # Fetch base branch with full history + git fetch origin ${{ github.base_ref }} + CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD) + + echo "Changed files:" + echo "$CHANGED_FILES" + + # Store changed files for reuse in later jobs + echo "changed_files<> $GITHUB_OUTPUT + echo "$CHANGED_FILES" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + # Check for build_info.json, .sh scripts (excluding specific directories), or Dockerfile + RELEVANT_CHANGES=$(echo "$CHANGED_FILES" | grep -E '(build_info\.json|\.sh$|Dockerfile)' | grep -vE '^(gha-script|process_bom|script|templates|travis-currency-ymls|travis-ymls)/' || true) + + if [ -n "$RELEVANT_CHANGES" ]; then + echo "should_build=true" >> $GITHUB_OUTPUT + echo "✅ Found relevant changes:" + echo "$RELEVANT_CHANGES" + else + echo "should_build=false" >> $GITHUB_OUTPUT + echo "⏭️ Skipping PR build CI check - no changes related to build_info.json, build scripts (.sh), or Dockerfile" + fi + build_info: + needs: check_changes + if: needs.check_changes.outputs.should_build == 'true' runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-24.04-ppc64le-p10' || inputs.large-runner }} + outputs: + wheel_build_enabled: ${{ steps.set_flags.outputs.wheel_build_enabled }} + has_sh_changes: ${{ steps.set_flags.outputs.has_sh_changes }} + has_dockerfile_changes: ${{ steps.set_flags.outputs.has_dockerfile_changes }} + docker_build_enabled: ${{ steps.set_flags.outputs.docker_build_enabled }} + build_package_enabled: ${{ steps.set_flags.outputs.build_package_enabled }} steps: - name: Checkout code (Pull Request) if: github.event_name == 'pull_request' uses: actions/checkout@v6 with: - fetch-depth: 0 - ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} - name: Checkout code (Workflow Dispatch) if: github.event_name == 'workflow_dispatch' @@ -77,8 +130,14 @@ jobs: - name: Locate and parse build_info.json run: | - - CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD) + # Reuse changed files from check_changes job + CHANGED_FILES="${{ needs.check_changes.outputs.changed_files }}" + + # If workflow_dispatch, fetch and compute changed files + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + git fetch origin ${{ github.base_ref }} --depth=1 + CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD) + fi BUILD_INFO_FILE=$(echo "$CHANGED_FILES" | grep 'build_info.json' | head -n 1) @@ -113,6 +172,66 @@ jobs: chmod +x ./gha-script/read_buildinfo.sh bash ./gha-script/read_buildinfo.sh + - name: Set job control flags + id: set_flags + run: | + PACKAGE_DIR=$(jq -r '.package_dir // ""' $BUILD_INFO_FILE) + WHEEL_BUILD=$(jq -r '.wheel_build // "false"' $BUILD_INFO_FILE) + + # Robust docker_build extraction + if jq -e '.docker_build == true or .docker_build == "true"' "$BUILD_INFO_FILE" > /dev/null; then + DOCKER_BUILD="true" + else + DOCKER_BUILD="false" + fi + + # Check if .sh scripts changed in this package + SH_SCRIPT_CHANGED=$(echo "$CHANGED_FILES" | grep -E "^$PACKAGE_DIR/.*\.sh$" || true) + + # Check if Dockerfile changed + DOCKERFILE_CHANGED=$(echo "$CHANGED_FILES" | grep -i 'Dockerfile' || true) + + # Set outputs for wheel builds + if [ "$WHEEL_BUILD" == "true" ] && [ -n "$SH_SCRIPT_CHANGED" ]; then + echo "wheel_build_enabled=true" >> $GITHUB_OUTPUT + echo "✅ Wheel builds will run (WHEEL_BUILD=true and .sh scripts changed)" + else + echo "wheel_build_enabled=false" >> $GITHUB_OUTPUT + echo "⏭️ Wheel builds will be skipped (WHEEL_BUILD=$WHEEL_BUILD, .sh changes: ${SH_SCRIPT_CHANGED:-none})" + fi + + # Set output for sh changes + if [ -n "$SH_SCRIPT_CHANGED" ]; then + echo "has_sh_changes=true" >> $GITHUB_OUTPUT + else + echo "has_sh_changes=false" >> $GITHUB_OUTPUT + fi + + # Set outputs for docker build + if [ "$DOCKER_BUILD" == "true" ] && [ -n "$DOCKERFILE_CHANGED" ]; then + echo "docker_build_enabled=true" >> $GITHUB_OUTPUT + echo "has_dockerfile_changes=true" >> $GITHUB_OUTPUT + echo "✅ Docker build will run (BUILD_DOCKER=true and Dockerfile changed)" + else + echo "docker_build_enabled=false" >> $GITHUB_OUTPUT + if [ -n "$DOCKERFILE_CHANGED" ]; then + echo "has_dockerfile_changes=true" >> $GITHUB_OUTPUT + else + echo "has_dockerfile_changes=false" >> $GITHUB_OUTPUT + fi + echo "⏭️ Docker build will be skipped (BUILD_DOCKER=$DOCKER_BUILD, Dockerfile changes: ${DOCKERFILE_CHANGED:-none})" + fi + + # Set output for build job (runs when build_info.json or .sh scripts change) + BUILD_INFO_CHANGED=$(echo "$CHANGED_FILES" | grep 'build_info\.json' || true) + if [ -n "$BUILD_INFO_CHANGED" ] || [ -n "$SH_SCRIPT_CHANGED" ]; then + echo "build_package_enabled=true" >> $GITHUB_OUTPUT + echo "✅ Build package job will run (build_info.json or .sh scripts changed)" + else + echo "build_package_enabled=false" >> $GITHUB_OUTPUT + echo "⏭️ Build package job will be skipped (no build_info.json or .sh script changes)" + fi + - name: Create scanner-env.sh run: | mkdir -p package-cache @@ -149,6 +268,7 @@ jobs: build: needs: build_info + if: needs.build_info.outputs.build_package_enabled == 'true' runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-24.04-ppc64le-p10' || inputs.large-runner }} steps: @@ -174,15 +294,16 @@ jobs: echo "------------------- scanner-env.sh -----------------------------" cat package-cache/scanner-env.sh - chmod +x ./gha-script/build_package.sh - bash ./gha-script/build_package.sh + echo "------------------- Executing changed scripts -----------------------------" + chmod +x ./gha-script/execute_changed_scripts.py + python3 ./gha-script/execute_changed_scripts.py # ===================== WHEEL JOBS ===================== wheel_build_py39: needs: build_info - if: ${{ success() }} + if: needs.build_info.outputs.wheel_build_enabled == 'true' runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-24.04-ppc64le-p10' || inputs.large-runner }} continue-on-error: true env: @@ -245,7 +366,7 @@ jobs: wheel_build_py310: needs: build_info - if: ${{ success() }} + if: needs.build_info.outputs.wheel_build_enabled == 'true' runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-24.04-ppc64le-p10' || inputs.large-runner }} continue-on-error: false env: @@ -308,7 +429,7 @@ jobs: wheel_build_py311: needs: build_info - if: ${{ success() }} + if: needs.build_info.outputs.wheel_build_enabled == 'true' runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-24.04-ppc64le-p10' || inputs.large-runner }} continue-on-error: false env: @@ -372,7 +493,7 @@ jobs: wheel_build_py312: needs: build_info - if: ${{ success() }} + if: needs.build_info.outputs.wheel_build_enabled == 'true' runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-24.04-ppc64le-p10' || inputs.large-runner }} continue-on-error: false env: @@ -434,7 +555,7 @@ jobs: wheel_build_py313: needs: build_info - if: ${{ success() }} + if: needs.build_info.outputs.wheel_build_enabled == 'true' runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-24.04-ppc64le-p10' || inputs.large-runner }} continue-on-error: true env: @@ -497,7 +618,7 @@ jobs: wheel_build_py314: needs: build_info - if: ${{ success() }} + if: needs.build_info.outputs.wheel_build_enabled == 'true' runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-24.04-ppc64le-p10' || inputs.large-runner }} continue-on-error: true env: @@ -561,7 +682,7 @@ jobs: build_docker: needs: build_info - if: ${{ success() }} + if: needs.build_info.outputs.docker_build_enabled == 'true' runs-on: ${{ github.event_name == 'pull_request' && 'ubuntu-24.04-ppc64le-p10' || inputs.large-runner }} steps: @@ -614,3 +735,15 @@ jobs: docker save -o package-cache/image.tar "$IMAGE_NAME" ls -lh package-cache/image.tar + + + + + + + + + + + + From 87e9394ca2d37f01b288e035cf65577a70087a97 Mon Sep 17 00:00:00 2001 From: Stuti Ravikiran Wali Date: Mon, 11 May 2026 00:03:43 +0530 Subject: [PATCH 2/3] Add script to execute changed build scripts --- gha-script/execute_changed_scripts.py | 154 ++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 gha-script/execute_changed_scripts.py diff --git a/gha-script/execute_changed_scripts.py b/gha-script/execute_changed_scripts.py new file mode 100644 index 0000000000..c2a5725a44 --- /dev/null +++ b/gha-script/execute_changed_scripts.py @@ -0,0 +1,154 @@ +#!/usr/bin/env python3 + +import os +import sys +import re + +def extract_script_metadata(script_path): + """ + Extract metadata from script header comments. + Returns dict with package_version, tested_on, ci_check, etc. + """ + metadata = { + 'package_version': None, + 'tested_on': 'UBI:9.3', # default + 'ci_check': 'true', # default + 'package_name': None, + 'use_non_root_user': 'false' # default + } + + key_mapping = { + '# Package': 'package_name', + '# Version': 'package_version', + '# Tested on': 'tested_on', + '# Ci-Check': 'ci_check', + '# Use Non-Root User': 'use_non_root_user' + } + + try: + with open(script_path, 'r') as f: + for line in f: + line = line.strip() + for key, field in key_mapping.items(): + if line.startswith(key): + value = line.split(':', 1)[-1].strip() + metadata[field] = value + break + except Exception as e: + print(f"Error reading script {script_path}: {e}") + return None + + return metadata + +def get_changed_scripts(): + """ + Get list of changed .sh scripts from CHANGED_FILES environment variable. + """ + changed_files = os.environ.get('CHANGED_FILES', '') + if not changed_files: + print("No CHANGED_FILES environment variable found") + return [] + + scripts = [] + for line in changed_files.split('\n'): + line = line.strip() + if line.endswith('.sh') and 'dockerfile' not in line.lower(): + scripts.append(line) + + return scripts + +def main(): + print("=" * 80) + print("EXECUTING CHANGED BUILD SCRIPTS") + print("=" * 80) + + # Get changed scripts + changed_scripts = get_changed_scripts() + + if not changed_scripts: + print("No .sh scripts found in changed files") + print("Skipping script execution") + return 0 + + print(f"\nFound {len(changed_scripts)} changed script(s):") + for script in changed_scripts: + print(f" - {script}") + print() + + # Process each script + executed_count = 0 + skipped_count = 0 + + for script_path in changed_scripts: + print("=" * 80) + print(f"Processing: {script_path}") + print("=" * 80) + + # Check if script exists + if not os.path.exists(script_path): + print(f"⚠️ Script not found: {script_path}") + continue + + # Extract metadata from script header + metadata = extract_script_metadata(script_path) + if not metadata: + print(f"❌ Failed to extract metadata from {script_path}") + continue + + version = metadata['package_version'] + ci_check = metadata['ci_check'].lower() + tested_on = metadata['tested_on'] + use_non_root = metadata['use_non_root_user'].lower() + + print(f"📋 Metadata extracted:") + print(f" Package: {metadata['package_name']}") + print(f" Version: {version}") + print(f" Tested on: {tested_on}") + print(f" CI-Check: {ci_check}") + print(f" Use Non-Root: {use_non_root}") + + # Check CI-Check flag + if ci_check != "true": + print(f"⏭️ Skipping {script_path} - CI-Check flag is set to {ci_check}") + skipped_count += 1 + continue + + if not version: + print(f"⚠️ No version found in script header, skipping {script_path}") + skipped_count += 1 + continue + + # Set environment variables for build_package.sh + os.environ['PKG_DIR_PATH'] = os.path.dirname(script_path) + '/' + os.environ['BUILD_SCRIPT'] = os.path.basename(script_path) + os.environ['VERSION'] = version + os.environ['TESTED_ON'] = tested_on + os.environ['NON_ROOT_BUILD'] = use_non_root + + print(f"\n🚀 Executing: {script_path} with version {version}") + print(f" Command: bash gha-script/build_package.sh") + + # Execute build_package.sh which will run the script + exit_code = os.system('bash gha-script/build_package.sh') + + if exit_code != 0: + print(f"\n❌ Script execution failed for {script_path} with exit code {exit_code}") + return exit_code + else: + print(f"\n✅ Script execution completed successfully for {script_path}") + executed_count += 1 + + print("\n" + "=" * 80) + print("EXECUTION SUMMARY") + print("=" * 80) + print(f"✅ Executed: {executed_count}") + print(f"⏭️ Skipped: {skipped_count}") + print(f"📊 Total: {len(changed_scripts)}") + print("=" * 80) + + return 0 + +if __name__ == "__main__": + sys.exit(main()) + + From 74cf4c58a8eb9d3983633e49ec0746bb0a243571 Mon Sep 17 00:00:00 2001 From: Stuti Ravikiran Wali Date: Mon, 11 May 2026 00:04:27 +0530 Subject: [PATCH 3/3] Comment out CI-check logic in validate_builds.py Commented out the CI-check logic for script validation and added notes about script execution in the build job. --- gha-script/validate_builds.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/gha-script/validate_builds.py b/gha-script/validate_builds.py index 54094dcce1..84df61e3ee 100644 --- a/gha-script/validate_builds.py +++ b/gha-script/validate_builds.py @@ -315,14 +315,20 @@ def trigger_build_validation_ci(pr_number): # perform basic validation check trigger_basic_validation_checks(file_name) - #check ci-check from package header + #check ci-check from package header ci_check=package_data['ci_check'].lower() - if ci_check=="true": - - # Build/test script files - trigger_script_validation_checks(file_name) - else: - print("Skipping Build script validation for {} as CI-Check flag is set to False".format(file_name)) + + # COMMENTED OUT: Script execution moved to build job via execute_changed_scripts.py + # This avoids duplicate execution - validation happens here, actual build happens in build job + # if ci_check=="true": + # # Build/test script files + # trigger_script_validation_checks(file_name) + # else: + # print("Skipping Build script validation for {} as CI-Check flag is set to False".format(file_name)) + + print("✅ Basic validation passed for {} (headers, license, line endings)".format(file_name)) + print(" Script execution will happen in build job with proper version parameter") + # Keep track of validated files. validated_file_list.append(file_name) elif file_name.lower().endswith('build_info.json') and status != "removed":