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
147 changes: 133 additions & 14 deletions .github/workflows/pr-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,62 @@ 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:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0

- 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<<EOF" >> $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)
Expand Down Expand Up @@ -74,13 +128,16 @@ jobs:
echo "Script completed successfully for PR #${PR_NUMBER}"
fi

- name: Fetch base branch
run: git fetch origin ${{ github.base_ref }} --depth=1

- 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)

Expand Down Expand Up @@ -115,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
Expand Down Expand Up @@ -151,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:
Expand All @@ -174,15 +292,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:
Expand Down Expand Up @@ -244,7 +363,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:
Expand Down Expand Up @@ -306,7 +425,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:
Expand Down Expand Up @@ -369,7 +488,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:
Expand Down Expand Up @@ -430,7 +549,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:
Expand Down Expand Up @@ -492,7 +611,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:
Expand Down Expand Up @@ -555,7 +674,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:
Expand Down
154 changes: 154 additions & 0 deletions gha-script/execute_changed_scripts.py
Original file line number Diff line number Diff line change
@@ -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())

# Made with Bob
Loading