Skip to content

deps: update safety requirement to >=3.7.0 #112

deps: update safety requirement to >=3.7.0

deps: update safety requirement to >=3.7.0 #112

name: Dependency Testing Pipeline
on:
pull_request:
paths:
- '.github/dependabot.yml'
- 'requirements*.txt'
- 'molecule/*/molecule.yml'
- 'galaxy.yml'
- '.github/workflows/**'
- 'meta/runtime.yml'
schedule:
# Run dependency tests weekly on Fridays at 10:00 UTC
- cron: '0 10 * * 5'
workflow_dispatch:
inputs:
test_scope:
description: 'Test scope'
required: false
default: 'full'
type: choice
options:
- 'full'
- 'python-only'
- 'ansible-only'
- 'docker-only'
enable_epel_gpg:
description: 'Enable GPG verification for EPEL repositories'
required: false
default: false
type: boolean
concurrency:
group: dependency-testing-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
env:
PYTHON_VERSION: "3.11"
ANSIBLE_CORE_VERSION: "2.17"
MOLECULE_VERSION: "6.0.3"
jobs:
security-scan:
name: Enhanced Dependency Security Scan
runs-on: self-hosted
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v5
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: '1.21'
- name: Install security scanning tools
run: |
# Install safety for Python dependencies
pip install --upgrade safety bandit semgrep
# Install docker-bench-security if not present
if ! command -v docker-bench-security &> /dev/null; then
curl -sSL https://raw.githubusercontent.com/docker/docker-bench-security/master/docker-bench-security.sh > /tmp/docker-bench-security.sh
chmod +x /tmp/docker-bench-security.sh
fi
- name: Run Ansible collection security check
run: |
# Use focused security check for Ansible collections
./scripts/ansible-collection-security-check.sh
- name: Upload security scan results
uses: actions/upload-artifact@v5
if: always()
with:
name: security-scan-results
path: security-reports/
retention-days: 30
- name: Check for critical vulnerabilities
run: |
if [[ -f "security-reports/summary.json" ]]; then
CRITICAL_COUNT=$(jq '.summary.critical // 0' security-reports/summary.json)
HIGH_COUNT=$(jq '.summary.high // 0' security-reports/summary.json)
echo "Critical vulnerabilities: $CRITICAL_COUNT"
echo "High vulnerabilities: $HIGH_COUNT"
if [[ $CRITICAL_COUNT -gt 0 ]]; then
echo "::error::Critical vulnerabilities found! Build failed."
exit 1
elif [[ $HIGH_COUNT -gt 5 ]]; then
echo "::warning::High number of high-severity vulnerabilities found ($HIGH_COUNT)"
fi
fi
dependency-matrix:
name: Generate Dependency Test Matrix
runs-on: self-hosted
needs: security-scan
outputs:
python-matrix: ${{ steps.generate.outputs.python-matrix }}
ansible-matrix: ${{ steps.generate.outputs.ansible-matrix }}
docker-matrix: ${{ steps.generate.outputs.docker-matrix }}
test-scope: ${{ steps.generate.outputs.test-scope }}
steps:
- uses: actions/checkout@v5
- name: Generate test matrix
id: generate
run: |
# Determine test scope
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
TEST_SCOPE="${{ github.event.inputs.test_scope }}"
elif [[ "${{ github.event_name }}" == "schedule" ]]; then
TEST_SCOPE="full"
else
# For PRs, determine scope based on changed files
if git diff --name-only origin/main HEAD | grep -E "(requirements|galaxy\.yml|meta/runtime\.yml)"; then
TEST_SCOPE="full"
elif git diff --name-only origin/main HEAD | grep -E "molecule.*\.yml"; then
TEST_SCOPE="docker-only"
else
TEST_SCOPE="python-only"
fi
fi
echo "test-scope=${TEST_SCOPE}" >> $GITHUB_OUTPUT
# Python dependency matrix
PYTHON_MATRIX='{"include":[{"python-version":"3.11","name":"current"},{"python-version":"3.12","name":"next"}]}'
echo "python-matrix=${PYTHON_MATRIX}" >> $GITHUB_OUTPUT
# Ansible dependency matrix
ANSIBLE_MATRIX='{"include":[{"ansible-core":"2.17","name":"current"},{"ansible-core":"2.18","name":"next"}]}'
echo "ansible-matrix=${ANSIBLE_MATRIX}" >> $GITHUB_OUTPUT
# Docker image matrix for Molecule (simplified since we now test all images in one job)
DOCKER_MATRIX='{"include":[{"name":"comprehensive"}]}'
echo "docker-matrix=${DOCKER_MATRIX}" >> $GITHUB_OUTPUT
python-dependency-test:
name: Python Dependencies (${{ matrix.name }})
runs-on: self-hosted
needs: dependency-matrix
if: needs.dependency-matrix.outputs.test-scope == 'full' || needs.dependency-matrix.outputs.test-scope == 'python-only'
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.dependency-matrix.outputs.python-matrix) }}
steps:
- uses: actions/checkout@v5
- name: Setup Python ${{ matrix.python-version }}
run: |
# Detect OS and use appropriate package manager (following ansible-test.yml pattern)
if [ -f /etc/os-release ]; then
. /etc/os-release
echo "Detected OS: $NAME ($ID)"
fi
# Determine package manager
if command -v dnf &> /dev/null; then
PKG_MGR="dnf"
elif command -v yum &> /dev/null; then
PKG_MGR="yum"
else
echo "Error: No suitable package manager found"
exit 1
fi
echo "Using package manager: $PKG_MGR"
# Skip EPEL configuration in dependency testing pipeline due to GPG verification failures
# Dependencies will be installed via pip instead of system packages where possible
if [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]]; then
echo "Skipping EPEL configuration for Rocky/Alma Linux in dependency testing pipeline"
echo "Using pip-based installations to avoid EPEL GPG verification issues"
# Clean any existing EPEL metadata that might cause issues
sudo rm -rf /var/cache/dnf/epel* /var/cache/yum/epel* 2>/dev/null || true
# Remove any existing EPEL repositories to prevent conflicts
sudo $PKG_MGR remove -y epel-release 2>/dev/null || true
echo "EPEL cleanup completed - using pip for Python dependencies"
fi
# Check if Python version is already installed (following ansible-test.yml pattern)
if command -v python${{ matrix.python-version }} &> /dev/null; then
echo "Python ${{ matrix.python-version }} is already installed: $(python${{ matrix.python-version }} --version)"
PYTHON_INSTALLED=true
else
echo "Python ${{ matrix.python-version }} not found, will install"
PYTHON_INSTALLED=false
fi
# Install Python and development packages only if needed
if [[ "$PYTHON_INSTALLED" == "false" ]]; then
echo "Installing Python ${{ matrix.python-version }} and development packages..."
if [[ "$ID" == "rocky" ]]; then
echo "Using --nogpgcheck for Rocky Linux package installation"
sudo $PKG_MGR install -y --nogpgcheck python${{ matrix.python-version }} python${{ matrix.python-version }}-devel python${{ matrix.python-version }}-pip
sudo $PKG_MGR install -y --nogpgcheck python3-libselinux libselinux-devel
else
sudo $PKG_MGR install -y python${{ matrix.python-version }} python${{ matrix.python-version }}-devel python${{ matrix.python-version }}-pip
sudo $PKG_MGR install -y python3-libselinux libselinux-devel
fi
else
echo "Python ${{ matrix.python-version }} already installed, skipping installation"
# Still install SELinux packages if needed
if [[ "$ID" == "rocky" ]]; then
sudo $PKG_MGR install -y --nogpgcheck python3-libselinux libselinux-devel 2>/dev/null || true
else
sudo $PKG_MGR install -y python3-libselinux libselinux-devel 2>/dev/null || true
fi
fi
# Setup Python environment
python${{ matrix.python-version }} -m pip install --upgrade pip
python${{ matrix.python-version }} -m pip install virtualenv
# Create virtual environment with system site packages for SELinux
python${{ matrix.python-version }} -m virtualenv --system-site-packages venv-${{ matrix.name }}
source venv-${{ matrix.name }}/bin/activate
- name: Install core dependencies
run: |
source venv-${{ matrix.name }}/bin/activate
pip install --upgrade pip setuptools wheel
- name: Verify SELinux bindings
run: |
source venv-${{ matrix.name }}/bin/activate
# Test that SELinux bindings are available
python -c "import selinux; print('SELinux bindings available')" || {
echo "SELinux bindings not available, attempting to fix..."
# Try to install SELinux bindings in venv
pip install selinux || echo "Failed to install SELinux via pip"
# Set environment variable to disable SELinux for Ansible if needed
export ANSIBLE_SELINUX_SPECIAL_FS=""
echo "ANSIBLE_SELINUX_SPECIAL_FS=" >> $GITHUB_ENV
}
- name: Test Ansible installation
run: |
source venv-${{ matrix.name }}/bin/activate
pip install ansible-core==${{ env.ANSIBLE_CORE_VERSION }}.*
# Test that ansible-config works (this is what was failing)
ansible-config dump --only-changed || echo "ansible-config dump failed"
ansible --version
ansible-galaxy --version
- name: Install system dependencies for container testing
run: |
# Detect OS and use appropriate package manager
if [ -f /etc/os-release ]; then
. /etc/os-release
echo "Detected OS: $NAME ($ID)"
fi
# Determine package manager
if command -v dnf &> /dev/null; then
PKG_MGR="dnf"
elif command -v yum &> /dev/null; then
PKG_MGR="yum"
else
echo "Error: No suitable package manager found"
exit 1
fi
# Install podman if not already available (following ansible-test.yml pattern)
if ! command -v podman &> /dev/null; then
echo "Installing podman container runtime..."
if [[ "$ID" == "rocky" ]]; then
sudo $PKG_MGR install -y --nogpgcheck podman
else
sudo $PKG_MGR install -y podman
fi
else
echo "Podman already installed: $(podman --version)"
fi
- name: Test Molecule installation
run: |
source venv-${{ matrix.name }}/bin/activate
# Install molecule and podman driver separately (following ansible-test.yml pattern)
pip install "molecule>=${{ env.MOLECULE_VERSION }}" molecule-podman
molecule --version
# Verify podman driver is available
echo "Checking molecule drivers:"
molecule drivers || echo "Failed to list drivers"
- name: Test additional dependencies
run: |
source venv-${{ matrix.name }}/bin/activate
# Test Ansible collections installation
ansible-galaxy collection install community.general
ansible-galaxy collection install containers.podman
# Test linting tools
pip install ansible-lint yamllint
ansible-lint --version
yamllint --version
- name: Run dependency compatibility test
run: |
source venv-${{ matrix.name }}/bin/activate
# Test that molecule can load configuration without errors (following ansible-test.yml pattern)
echo "🔍 Molecule configuration debugging..."
echo "Available scenarios:"
molecule list
echo ""
# Test molecule check on default scenario (syntax and dependency validation)
if [[ -d "molecule/default" ]]; then
echo "🔍 Testing molecule check on default scenario..."
echo "Default scenario configuration:"
cat molecule/default/molecule.yml
echo ""
if molecule check --scenario-name default; then
echo "✅ Molecule check passed for default scenario"
else
echo "⚠️ Molecule check failed for default scenario - may indicate dependency issues"
fi
else
echo "ℹ️ No default molecule scenario found, skipping molecule check"
fi
- name: Generate dependency report
if: always()
run: |
source venv-${{ matrix.name }}/bin/activate
pip freeze > dependency-report-python-${{ matrix.name }}.txt
echo "## Python ${{ matrix.python-version }} Dependency Report" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
cat dependency-report-python-${{ matrix.name }}.txt >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
- name: Upload dependency report
if: always()
uses: actions/upload-artifact@v5
with:
name: dependency-report-python-${{ matrix.name }}
path: dependency-report-python-${{ matrix.name }}.txt
ansible-dependency-test:
name: Ansible Dependencies (${{ matrix.name }})
runs-on: self-hosted
needs: dependency-matrix
if: needs.dependency-matrix.outputs.test-scope == 'full' || needs.dependency-matrix.outputs.test-scope == 'ansible-only'
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.dependency-matrix.outputs.ansible-matrix) }}
steps:
- uses: actions/checkout@v5
- name: Setup Python ${{ env.PYTHON_VERSION }}
run: |
# Detect OS and use appropriate package manager (following ansible-test.yml pattern)
if [ -f /etc/os-release ]; then
. /etc/os-release
echo "Detected OS: $NAME ($ID)"
fi
# Determine package manager
if command -v dnf &> /dev/null; then
PKG_MGR="dnf"
elif command -v yum &> /dev/null; then
PKG_MGR="yum"
else
echo "Error: No suitable package manager found"
exit 1
fi
echo "Using package manager: $PKG_MGR"
# Skip EPEL configuration in dependency testing pipeline due to GPG verification failures
# Dependencies will be installed via pip instead of system packages where possible
if [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]]; then
echo "Skipping EPEL configuration for Rocky/Alma Linux in dependency testing pipeline"
echo "Using pip-based installations to avoid EPEL GPG verification issues"
# Clean any existing EPEL metadata that might cause issues
sudo rm -rf /var/cache/dnf/epel* /var/cache/yum/epel* 2>/dev/null || true
# Remove any existing EPEL repositories to prevent conflicts
sudo $PKG_MGR remove -y epel-release 2>/dev/null || true
echo "EPEL cleanup completed - using pip for Python dependencies"
fi
# Check if Python version is already installed (following ansible-test.yml pattern)
if command -v python${{ env.PYTHON_VERSION }} &> /dev/null; then
echo "Python ${{ env.PYTHON_VERSION }} is already installed: $(python${{ env.PYTHON_VERSION }} --version)"
PYTHON_INSTALLED=true
else
echo "Python ${{ env.PYTHON_VERSION }} not found, will install"
PYTHON_INSTALLED=false
fi
# Install Python and development packages only if needed
if [[ "$PYTHON_INSTALLED" == "false" ]]; then
echo "Installing Python ${{ env.PYTHON_VERSION }} and development packages..."
if [[ "$ID" == "rocky" ]]; then
echo "Using --nogpgcheck for Rocky Linux package installation"
sudo $PKG_MGR install -y --nogpgcheck python${{ env.PYTHON_VERSION }} python${{ env.PYTHON_VERSION }}-devel python${{ env.PYTHON_VERSION }}-pip
sudo $PKG_MGR install -y --nogpgcheck python3-libselinux libselinux-devel
else
sudo $PKG_MGR install -y python${{ env.PYTHON_VERSION }} python${{ env.PYTHON_VERSION }}-devel python${{ env.PYTHON_VERSION }}-pip
sudo $PKG_MGR install -y python3-libselinux libselinux-devel
fi
else
echo "Python ${{ env.PYTHON_VERSION }} already installed, skipping installation"
# Still install SELinux packages if needed
if [[ "$ID" == "rocky" ]]; then
sudo $PKG_MGR install -y --nogpgcheck python3-libselinux libselinux-devel 2>/dev/null || true
else
sudo $PKG_MGR install -y python3-libselinux libselinux-devel 2>/dev/null || true
fi
fi
# Setup Python environment
python${{ env.PYTHON_VERSION }} -m pip install --upgrade pip
python${{ env.PYTHON_VERSION }} -m pip install virtualenv
# Create virtual environment with system site packages for SELinux
python${{ env.PYTHON_VERSION }} -m virtualenv --system-site-packages venv-ansible-${{ matrix.name }}
source venv-ansible-${{ matrix.name }}/bin/activate
- name: Install Ansible Core ${{ matrix.ansible-core }}
run: |
source venv-ansible-${{ matrix.name }}/bin/activate
pip install ansible-core==${{ matrix.ansible-core }}.*
ansible --version
- name: Test requirements.yml dependencies
run: |
source venv-ansible-${{ matrix.name }}/bin/activate
# Test that all dependencies in requirements.yml can be installed
if [[ -f requirements.yml ]]; then
echo "Installing collections and roles from requirements.yml..."
ansible-galaxy install -r requirements.yml
echo "✅ Successfully installed dependencies from requirements.yml"
echo "📋 Installed collections:"
ansible-galaxy collection list
echo "📋 Installed roles:"
ansible-galaxy role list
else
echo "❌ requirements.yml not found, skipping dependency installation"
fi
- name: Test role dependencies
run: |
source venv-ansible-${{ matrix.name }}/bin/activate
# Test each role can be loaded
for role in roles/*/; do
role_name=$(basename "$role")
echo "Testing role: $role_name"
ansible-playbook --syntax-check --list-tasks test.yml \
-e "target_role=$role_name" || echo "Warning: $role_name syntax check failed"
done
- name: Test collection build
run: |
source venv-ansible-${{ matrix.name }}/bin/activate
# Test that collection can be built
ansible-galaxy collection build --force
ls -la *.tar.gz
- name: Generate Ansible dependency report
if: always()
run: |
source venv-ansible-${{ matrix.name }}/bin/activate
echo "## Ansible Core ${{ matrix.ansible-core }} Dependency Report" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
ansible --version >> $GITHUB_STEP_SUMMARY
echo '' >> $GITHUB_STEP_SUMMARY
ansible-galaxy collection list >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
docker-dependency-test:
name: Container Dependencies Test
runs-on: self-hosted
needs: dependency-matrix
if: needs.dependency-matrix.outputs.test-scope == 'full' || needs.dependency-matrix.outputs.test-scope == 'docker-only'
steps:
- uses: actions/checkout@v5
- name: Setup Python ${{ env.PYTHON_VERSION }}
run: |
# Detect OS and use appropriate package manager (following ansible-test.yml pattern)
if [ -f /etc/os-release ]; then
. /etc/os-release
echo "Detected OS: $NAME ($ID)"
fi
# Determine package manager
if command -v dnf &> /dev/null; then
PKG_MGR="dnf"
elif command -v yum &> /dev/null; then
PKG_MGR="yum"
else
echo "Error: No suitable package manager found"
exit 1
fi
echo "Using package manager: $PKG_MGR"
# Skip EPEL configuration in dependency testing pipeline due to GPG verification failures
# Dependencies will be installed via pip instead of system packages where possible
if [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]]; then
echo "Skipping EPEL configuration for Rocky/Alma Linux in dependency testing pipeline"
echo "Using pip-based installations to avoid EPEL GPG verification issues"
# Clean any existing EPEL metadata that might cause issues
sudo rm -rf /var/cache/dnf/epel* /var/cache/yum/epel* 2>/dev/null || true
# Remove any existing EPEL repositories to prevent conflicts
sudo $PKG_MGR remove -y epel-release 2>/dev/null || true
echo "EPEL cleanup completed - using pip for Python dependencies"
fi
# Check if Python version is already installed (following ansible-test.yml pattern)
if command -v python${{ env.PYTHON_VERSION }} &> /dev/null; then
echo "Python ${{ env.PYTHON_VERSION }} is already installed: $(python${{ env.PYTHON_VERSION }} --version)"
PYTHON_INSTALLED=true
else
echo "Python ${{ env.PYTHON_VERSION }} not found, will install"
PYTHON_INSTALLED=false
fi
# Install Python and development packages only if needed
if [[ "$PYTHON_INSTALLED" == "false" ]]; then
echo "Installing Python ${{ env.PYTHON_VERSION }} and development packages..."
if [[ "$ID" == "rocky" ]]; then
echo "Using --nogpgcheck for Rocky Linux package installation"
sudo $PKG_MGR install -y --nogpgcheck python${{ env.PYTHON_VERSION }} python${{ env.PYTHON_VERSION }}-devel python${{ env.PYTHON_VERSION }}-pip
sudo $PKG_MGR install -y --nogpgcheck python3-libselinux libselinux-devel
else
sudo $PKG_MGR install -y python${{ env.PYTHON_VERSION }} python${{ env.PYTHON_VERSION }}-devel python${{ env.PYTHON_VERSION }}-pip
sudo $PKG_MGR install -y python3-libselinux libselinux-devel
fi
else
echo "Python ${{ env.PYTHON_VERSION }} already installed, skipping installation"
# Still install SELinux packages if needed
if [[ "$ID" == "rocky" ]]; then
sudo $PKG_MGR install -y --nogpgcheck python3-libselinux libselinux-devel 2>/dev/null || true
else
sudo $PKG_MGR install -y python3-libselinux libselinux-devel 2>/dev/null || true
fi
fi
# Install system dependencies for container testing
if ! command -v podman &> /dev/null; then
echo "Installing podman container runtime..."
if [[ "$ID" == "rocky" ]]; then
sudo $PKG_MGR install -y --nogpgcheck podman
else
sudo $PKG_MGR install -y podman
fi
else
echo "Podman already installed: $(podman --version)"
fi
# Setup Python environment
python${{ env.PYTHON_VERSION }} -m pip install --upgrade pip
python${{ env.PYTHON_VERSION }} -m pip install virtualenv
# Create virtual environment with system site packages for SELinux
python${{ env.PYTHON_VERSION }} -m virtualenv --system-site-packages venv-docker
source venv-docker/bin/activate
# Install molecule and podman driver separately (following ansible-test.yml pattern)
pip install "molecule>=${{ env.MOLECULE_VERSION }}" molecule-podman
echo "Container test environment setup completed:"
echo "Python version: $(python --version)"
echo "Molecule version: $(molecule --version)"
echo "Podman version: $(podman --version)"
- name: Setup container registries and pre-pull images
env:
REDHAT_REGISTRY_USERNAME: ${{ secrets.REDHAT_REGISTRY_USERNAME }}
REDHAT_REGISTRY_TOKEN: ${{ secrets.REDHAT_REGISTRY_TOKEN }}
run: |
echo "🐳 Setting up container registries and pre-pulling images..."
# Initialize registry access flags
RED_HAT_ACCESS=false
# Test Red Hat registry access if credentials are available
if [[ -n "$REDHAT_REGISTRY_USERNAME" && -n "$REDHAT_REGISTRY_TOKEN" ]]; then
echo "🔐 Testing Red Hat registry authentication..."
if echo "$REDHAT_REGISTRY_TOKEN" | podman login registry.redhat.io --username "$REDHAT_REGISTRY_USERNAME" --password-stdin; then
echo "✅ Red Hat registry authentication successful"
# Test access with a minimal pull
if podman pull registry.redhat.io/ubi9-minimal:latest 2>/dev/null; then
echo "✅ Red Hat registry access confirmed"
RED_HAT_ACCESS=true
podman rmi registry.redhat.io/ubi9-minimal:latest 2>/dev/null || true
else
echo "⚠️ Red Hat registry authenticated but image pull failed"
fi
else
echo "⚠️ Red Hat registry authentication failed"
fi
else
echo "ℹ️ Red Hat registry credentials not available - using public images only"
fi
# Define image sets based on registry access (following ansible-test.yml pattern)
if [[ "$RED_HAT_ACCESS" == "true" ]]; then
IMAGES=(
"docker.io/rockylinux/rockylinux:9-ubi-init"
"docker.io/almalinux/9-init:9.6-20250712"
"registry.redhat.io/ubi9-init:9.6-1751962289"
"registry.redhat.io/ubi10-init:10.0-1751895590"
)
else
IMAGES=(
"docker.io/rockylinux/rockylinux:9-ubi-init"
"docker.io/almalinux/9-init:9.6-20250712"
)
fi
# Pre-pull all container images to avoid timeout during tests
echo "🐳 Pre-pulling container images to avoid timeout during tests..."
PULL_SUCCESS=0
PULL_TOTAL=${#IMAGES[@]}
# Temporarily disable exit on error for container pulls (following scripts/emergency-cleanup-containers.sh pattern)
set +e
for image in "${IMAGES[@]}"; do
echo "Pulling $image..."
if podman pull "$image" 2>/dev/null; then
echo "✅ Successfully pulled $image"
((PULL_SUCCESS++))
else
echo "⚠️ Failed to pull $image - may cause test failures"
# Continue without exiting (following existing pattern)
fi
done
# Re-enable exit on error
set -e
echo "🎯 Container registry setup complete!"
echo "Successfully pulled: $PULL_SUCCESS/$PULL_TOTAL images"
# Store results for later steps
echo "RED_HAT_ACCESS=$RED_HAT_ACCESS" >> $GITHUB_ENV
echo "PULL_SUCCESS=$PULL_SUCCESS" >> $GITHUB_ENV
echo "PULL_TOTAL=$PULL_TOTAL" >> $GITHUB_ENV
- name: Validate molecule configurations for security compliance
run: |
source venv-docker/bin/activate
echo "🔒 Validating molecule configurations for security compliance..."
privileged_usage_found=false
# Check all molecule scenarios for privileged containers (ADR-0012 compliance)
for molecule_dir in molecule/*/; do
if [[ -f "$molecule_dir/molecule.yml" ]]; then
scenario_name=$(basename "$molecule_dir")
molecule_file="$molecule_dir/molecule.yml"
echo "📋 Checking scenario: $scenario_name"
# Check for privileged containers (security violation)
if grep -q "privileged.*true" "$molecule_file"; then
echo " ❌ Privileged container found - security violation"
echo " 🚫 Violates ADR-0012: Security-Enhanced Container Testing"
privileged_usage_found=true
else
echo " ✅ No privileged containers detected"
fi
# Validate molecule configuration syntax
echo " 📝 Validating molecule configuration syntax..."
if molecule syntax --scenario-name "$scenario_name" >/dev/null 2>&1; then
echo " ✅ Molecule configuration syntax is valid"
else
echo " ⚠️ Molecule configuration syntax issues detected"
fi
fi
done
# Fail if privileged containers are found
if [[ "$privileged_usage_found" == "true" ]]; then
echo ""
echo "❌ SECURITY VIOLATION: Privileged containers detected!"
echo " This violates ADR-0012: Security-Enhanced Container Testing"
echo " Please remove 'privileged: true' from molecule configurations"
exit 1
else
echo ""
echo "✅ Security validation passed - no privileged containers found"
fi
- name: Test basic molecule functionality
run: |
source venv-docker/bin/activate
echo "🧪 Testing basic molecule functionality..."
# Verify container runtime (following ansible-test.yml pattern)
echo "🔍 Container runtime verification:"
podman version
podman info | grep -E "(graphDriverName|runRoot|imageStore)" || echo "Podman info check completed"
echo ""
# Verify molecule drivers
echo "🔍 Molecule driver verification:"
molecule drivers
echo ""
# Test molecule list command
echo "📋 Available molecule scenarios:"
molecule list
# Test molecule check on default scenario (syntax and dependency validation)
if [[ -d "molecule/default" ]]; then
echo "🔍 Testing molecule check on default scenario..."
cd molecule/default
if molecule check --scenario-name default; then
echo "✅ Molecule check passed for default scenario"
else
echo "⚠️ Molecule check failed for default scenario - may indicate dependency issues"
fi
else
echo "ℹ️ No default molecule scenario found, skipping molecule check"
fi
- name: Generate container dependency report
if: always()
run: |
echo "## Container Dependencies Test Report" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "Red Hat Registry Access: $RED_HAT_ACCESS" >> $GITHUB_STEP_SUMMARY
echo "Images Successfully Pulled: $PULL_SUCCESS/$PULL_TOTAL" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Available Container Images:" >> $GITHUB_STEP_SUMMARY
podman images --format "table {{.Repository}}:{{.Tag}} {{.Size}} {{.Created}}" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
dependency-security-scan:
name: Dependency Security Scan
runs-on: self-hosted
needs: [python-dependency-test, ansible-dependency-test]
if: always() && (needs.python-dependency-test.result == 'success' || needs.ansible-dependency-test.result == 'success')
steps:
- uses: actions/checkout@v5
- name: Setup Python ${{ env.PYTHON_VERSION }}
run: |
# Detect OS and use appropriate package manager (following ansible-test.yml pattern)
if [ -f /etc/os-release ]; then
. /etc/os-release
echo "Detected OS: $NAME ($ID)"
fi
# Determine package manager
if command -v dnf &> /dev/null; then
PKG_MGR="dnf"
elif command -v yum &> /dev/null; then
PKG_MGR="yum"
else
echo "Error: No suitable package manager found"
exit 1
fi
echo "Using package manager: $PKG_MGR"
# Skip EPEL configuration in dependency testing pipeline due to GPG verification failures
# Dependencies will be installed via pip instead of system packages where possible
if [[ "$ID" == "rocky" ]] || [[ "$ID" == "almalinux" ]]; then
echo "Skipping EPEL configuration for Rocky/Alma Linux in dependency testing pipeline"
echo "Using pip-based installations to avoid EPEL GPG verification issues"
# Clean any existing EPEL metadata that might cause issues
sudo rm -rf /var/cache/dnf/epel* /var/cache/yum/epel* 2>/dev/null || true
# Remove any existing EPEL repositories to prevent conflicts
sudo $PKG_MGR remove -y epel-release 2>/dev/null || true
echo "EPEL cleanup completed - using pip for Python dependencies"
fi
# Check if Python version is already installed (following ansible-test.yml pattern)
if command -v python${{ env.PYTHON_VERSION }} &> /dev/null; then
echo "Python ${{ env.PYTHON_VERSION }} is already installed: $(python${{ env.PYTHON_VERSION }} --version)"
PYTHON_INSTALLED=true
else
echo "Python ${{ env.PYTHON_VERSION }} not found, will install"
PYTHON_INSTALLED=false
fi
# Install Python and development packages only if needed
if [[ "$PYTHON_INSTALLED" == "false" ]]; then
echo "Installing Python ${{ env.PYTHON_VERSION }} and development packages..."
if [[ "$ID" == "rocky" ]]; then
echo "Using --nogpgcheck for Rocky Linux package installation"
sudo $PKG_MGR install -y --nogpgcheck python${{ env.PYTHON_VERSION }} python${{ env.PYTHON_VERSION }}-devel python${{ env.PYTHON_VERSION }}-pip
sudo $PKG_MGR install -y --nogpgcheck python3-libselinux libselinux-devel
else
sudo $PKG_MGR install -y python${{ env.PYTHON_VERSION }} python${{ env.PYTHON_VERSION }}-devel python${{ env.PYTHON_VERSION }}-pip
sudo $PKG_MGR install -y python3-libselinux libselinux-devel
fi
else
echo "Python ${{ env.PYTHON_VERSION }} already installed, skipping installation"
# Still install SELinux packages if needed
if [[ "$ID" == "rocky" ]]; then
sudo $PKG_MGR install -y --nogpgcheck python3-libselinux libselinux-devel 2>/dev/null || true
else
sudo $PKG_MGR install -y python3-libselinux libselinux-devel 2>/dev/null || true
fi
fi
# Setup Python environment
python${{ env.PYTHON_VERSION }} -m pip install --upgrade pip
python${{ env.PYTHON_VERSION }} -m pip install virtualenv
# Create virtual environment with system site packages for SELinux
python${{ env.PYTHON_VERSION }} -m virtualenv --system-site-packages venv-security
source venv-security/bin/activate
- name: Install security scanning tools
run: |
source venv-security/bin/activate
pip install safety bandit
- name: Run dependency vulnerability scan
run: |
source venv-security/bin/activate
# Create a requirements file from our dependencies
cat > temp-requirements.txt << EOF
ansible-core==${{ env.ANSIBLE_CORE_VERSION }}.*
molecule[podman]==${{ env.MOLECULE_VERSION }}.*
ansible-lint
yamllint
EOF
# Run safety check
safety check -r temp-requirements.txt || echo "Security vulnerabilities found"
- name: Run static code analysis
run: |
source venv-security/bin/activate
# Run bandit on any Python files
find . -name "*.py" -exec bandit {} \; || echo "Security issues found in Python code"
dependency-test-summary:
name: Dependency Test Summary
runs-on: self-hosted
needs: [python-dependency-test, ansible-dependency-test, docker-dependency-test, dependency-security-scan]
if: always()
steps:
- name: Generate final summary
run: |
echo "# Dependency Testing Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Python tests summary
if [[ "${{ needs.python-dependency-test.result }}" == "success" ]]; then
echo "✅ Python dependency tests: PASSED" >> $GITHUB_STEP_SUMMARY
else
echo "❌ Python dependency tests: FAILED" >> $GITHUB_STEP_SUMMARY
fi
# Ansible tests summary
if [[ "${{ needs.ansible-dependency-test.result }}" == "success" ]]; then
echo "✅ Ansible dependency tests: PASSED" >> $GITHUB_STEP_SUMMARY
else
echo "❌ Ansible dependency tests: FAILED" >> $GITHUB_STEP_SUMMARY
fi
# Docker tests summary
if [[ "${{ needs.docker-dependency-test.result }}" == "success" ]]; then
echo "✅ Container dependency tests: PASSED" >> $GITHUB_STEP_SUMMARY
else
echo "❌ Container dependency tests: FAILED" >> $GITHUB_STEP_SUMMARY
fi
# Security scan summary
if [[ "${{ needs.dependency-security-scan.result }}" == "success" ]]; then
echo "✅ Security dependency scan: PASSED" >> $GITHUB_STEP_SUMMARY
else
echo "⚠️ Security dependency scan: ISSUES FOUND" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "Generated: $(date)" >> $GITHUB_STEP_SUMMARY
- name: Check overall status
run: |
# Fail if critical tests failed
if [[ "${{ needs.python-dependency-test.result }}" == "failure" ]] || \
[[ "${{ needs.ansible-dependency-test.result }}" == "failure" ]]; then
echo "Critical dependency tests failed!"
exit 1
fi
echo "Dependency testing completed successfully!"