Files
ansible-lemp-wordpress/.github/workflows/ci-cd.yml
2025-06-18 19:48:09 +02:00

292 lines
8.5 KiB
YAML

name: CI/CD Pipeline
# Updated: Removed systemd, using SSH-based testing for better stability
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
lint:
name: Lint Ansible Playbooks
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install ansible ansible-lint yamllint
- name: Lint YAML files
run: |
yamllint .
continue-on-error: true
- name: Lint Ansible playbooks
run: |
ansible-lint playbooks/*.yml
continue-on-error: true
- name: Validate Ansible syntax
run: |
for playbook in playbooks/*.yml; do
ansible-playbook --syntax-check "$playbook"
done
test-ubuntu:
name: Test on Ubuntu
runs-on: ubuntu-latest
needs: lint
strategy:
matrix:
ubuntu_version: ['20.04', '22.04', '24.04']
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install Ansible
run: |
python -m pip install --upgrade pip
pip install ansible
- name: Set up Docker
uses: docker/setup-buildx-action@v3
- name: Create test inventory
run: |
mkdir -p test-inventory
cat > test-inventory/hosts <<EOF
[wordpress_servers]
test-server ansible_host=localhost ansible_port=2222 ansible_user=testuser ansible_ssh_private_key_file=~/.ssh/id_rsa ansible_ssh_common_args='-o StrictHostKeyChecking=no'
EOF
- name: Build test container
run: |
docker build -t test-ubuntu:${{ matrix.ubuntu_version }} -f- . <<EOF
FROM ubuntu:${{ matrix.ubuntu_version }}
RUN apt-get update && apt-get install -y \
python3 python3-pip sudo openssh-server curl \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN useradd -m -s /bin/bash testuser && \
echo 'testuser ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
# Start SSH service in foreground to keep container running
CMD ["/usr/sbin/sshd", "-D"]
EOF
- name: Run test container
run: |
# Configure SSH host keys
mkdir -p ~/.ssh
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N ""
docker run -d --name test-server \
-p 2222:22 \
test-ubuntu:${{ matrix.ubuntu_version }}
# Wait for container to be ready
sleep 5
# Configure SSH access
docker exec test-server mkdir -p /home/testuser/.ssh
docker cp ~/.ssh/id_rsa.pub test-server:/home/testuser/.ssh/authorized_keys
docker exec test-server chown -R testuser:testuser /home/testuser/.ssh
docker exec test-server chmod 700 /home/testuser/.ssh
docker exec test-server chmod 600 /home/testuser/.ssh/authorized_keys
docker exec test-server service ssh start
# Check if container is running
if ! docker ps | grep -q test-server; then
echo "Container failed to start, checking logs:"
docker logs test-server
exit 1
fi
- name: Test base LEMP installation
run: |
# Test just the syntax and basic functionality without full installation
ansible-playbook -i test-inventory/hosts \
playbooks/lemp-wordpress.yml \
--extra-vars "mysql_root_password=test123 wordpress_db_password=test123 wp_admin_password=test123" \
--check \
-v
- name: Test WordPress installation
run: |
# Test just the syntax check for WordPress installation
ansible-playbook -i test-inventory/hosts \
playbooks/install-wordpress-official.yml \
--extra-vars "wp_admin_password=test123" \
--check \
-v
- name: Verify basic connectivity
run: |
# Test basic SSH connectivity
echo "Testing SSH connectivity..."
ssh -o StrictHostKeyChecking=no -p 2222 testuser@localhost "echo 'SSH connection successful'"
# Test basic container functionality
echo "Testing container basics..."
docker exec test-server whoami
docker exec test-server uname -a
- name: Cleanup
if: always()
run: |
docker stop test-server || true
docker rm test-server || true
test-centos:
name: Test on CentOS Stream
runs-on: ubuntu-latest
needs: lint
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install Ansible
run: |
python -m pip install --upgrade pip
pip install ansible
- name: Set up Docker
uses: docker/setup-buildx-action@v3
- name: Create test inventory
run: |
mkdir -p test-inventory
cat > test-inventory/hosts <<EOF
[wordpress_servers]
test-centos ansible_connection=docker ansible_docker_extra_args="--user=root"
EOF
- name: Build CentOS test container
run: |
docker build -t test-centos:stream9 -f- . <<EOF
FROM quay.io/centos/centos:stream9
RUN dnf update -y && dnf install -y \
python3 python3-pip sudo openssh-server systemd \
&& dnf clean all
RUN useradd -m -s /bin/bash testuser && \
echo 'testuser ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
CMD ["/sbin/init"]
EOF
- name: Run CentOS test container
run: |
docker run -d --name test-centos \
--privileged \
--tmpfs /tmp \
--tmpfs /run \
--tmpfs /run/lock \
-v /sys/fs/cgroup:/sys/fs/cgroup:ro \
test-centos:stream9
# Wait for container to be ready
sleep 10
# Check if container is running
if ! docker ps | grep -q test-centos; then
echo "CentOS container failed to start, checking logs:"
docker logs test-centos
exit 1
fi
- name: Test LEMP installation on CentOS
run: |
# Just test syntax and basic functionality for CentOS
ansible-playbook -i test-inventory/hosts \
playbooks/lemp-wordpress-multios.yml \
--extra-vars "mysql_root_password=test123 wordpress_db_password=test123 wp_admin_password=test123" \
--check \
-v
continue-on-error: true
- name: Cleanup CentOS
if: always()
run: |
docker stop test-centos || true
docker rm test-centos || true
security-scan:
name: Security Scanning
runs-on: ubuntu-latest
needs: lint
permissions:
security-events: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3 # Updated to v3 to fix deprecated v2 warning
if: always()
with:
sarif_file: 'trivy-results.sarif'
release:
name: Create Release
runs-on: ubuntu-latest
needs: [test-ubuntu, test-centos, security-scan]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get latest tag
id: get_tag
run: |
latest_tag=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
echo "latest_tag=$latest_tag" >> $GITHUB_OUTPUT
- name: Generate changelog
run: |
echo "# Changelog" > CHANGELOG_RELEASE.md
echo "" >> CHANGELOG_RELEASE.md
git log ${{ steps.get_tag.outputs.latest_tag }}..HEAD --pretty=format:"- %s (%h)" >> CHANGELOG_RELEASE.md
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ github.run_number }}
name: Release v${{ github.run_number }}
body_path: CHANGELOG_RELEASE.md
draft: false
prerelease: false