diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 118baed..934d086 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -122,4 +122,3 @@ jobs: build-args: | PHP_IMG=${{ matrix.base_container }} COMPOSER_VERSION=${{ env.COMPOSER_VERSION }} - diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..1ab6cc3 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,59 @@ +name: Build Docker image + +permissions: + contents: read + +on: + push: + branches: + - "develop" + +jobs: + build_push_develop: + runs-on: ubuntu-latest + steps: + ## GitHub Action validation testing before starting workflow ## + - name: Ensure Docker token is present + env: + DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + if: ${{ env.DOCKERHUB_TOKEN == '' }} + run: | + echo "Dockerhub token is not defined in GitHub secrets, exiting run" + exit 1 + + - name: Ensure Docker username is present + env: + DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }} + if: ${{ env.DOCKERHUB_USERNAME == '' }} + run: | + echo "Dockerhub username is not defined in GitHub secrets, exiting run" + exit 1 + + ## Begin workflow ## + + # https://github.com/marketplace/actions/docker-setup-qemu + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + # https://github.com/marketplace/actions/docker-setup-buildx + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + # https://github.com/marketplace/actions/docker-login + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and Push 8.4 Test + uses: docker/build-push-action@v6 + if: ${{ github.ref == 'refs/heads/develop' }} + with: + push: true + no-cache: true + tags: 10up/wordpress-ci:php-8.4-develop + build-args: | + PHP_IMG=php:8.4-bookworm + COMPOSER_VERSION=${{ env.COMPOSER_VERSION }} + diff --git a/Dockerfile b/Dockerfile index 973f118..7485aa0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,7 @@ RUN apt-get update && \ build-essential \ ca-certificates \ clamav \ + clamav-daemon \ clamav-freshclam \ curl \ fonts-liberation \ @@ -191,6 +192,7 @@ RUN curl -sSL https://raw.githubusercontent.com/upciti/wakemeops/main/assets/ins ## CI pipeline scripts and auth ## COPY scripts/* /custom-scripts/ +COPY config/clamd.conf /custom-scripts/clamd.conf RUN chmod +x /custom-scripts/* ENV PATH="/custom-scripts:${PATH}" @@ -207,4 +209,3 @@ COPY ./entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] - diff --git a/clam.pid b/clam.pid new file mode 100644 index 0000000..dd6dbb8 --- /dev/null +++ b/clam.pid @@ -0,0 +1 @@ +37842 diff --git a/clamd.conf b/clamd.conf new file mode 100644 index 0000000..3250202 --- /dev/null +++ b/clamd.conf @@ -0,0 +1 @@ +LocalSocket clamd.sock diff --git a/config/clamd.conf b/config/clamd.conf new file mode 100644 index 0000000..3250202 --- /dev/null +++ b/config/clamd.conf @@ -0,0 +1 @@ +LocalSocket clamd.sock diff --git a/scripts/virus-scan b/scripts/virus-scan index 0d38666..713acbc 100644 --- a/scripts/virus-scan +++ b/scripts/virus-scan @@ -1,42 +1,72 @@ #!/bin/bash +set -Eeuo pipefail +set -x -# Use ClamAV to do a virus scan of the repo. Only display files where a virus is found +SOCKET=/tmp/clamd.sock +DB_DIR="${CLAMAV_DB_DIR:-/var/lib/clamav}" +CLAMD_CONF=/tmp/clamd-$$.conf +CLAMD_LOG=/tmp/clamd-$$.log +CLAMD_PID="" +WAITED=0 -# Colors -# shellcheck disable=SC1117 end="\033[0m" red="\033[0;31m" green="\033[0;32m" +red() { echo -e "${red}${1}${end}"; } +green() { echo -e "${green}${1}${end}"; } -function red { - echo -e "${red}${1}${end}" -} - -function green { - echo -e "${green}${1}${end}" +cleanup() { + [ -n "$CLAMD_PID" ] && kill "$CLAMD_PID" 2>/dev/null || true + [ -n "$CLAMD_PID" ] && wait "$CLAMD_PID" 2>/dev/null || true + rm -f "${SOCKET}" "${CLAMD_CONF}" "${CLAMD_LOG}" } +trap cleanup EXIT green "#### Starting Virus Scan ####" -clamscan --exclude-dir ./.composer-cache --exclude-dir ./node_modules_cache -riz . +for bin in clamd clamdscan; do + command -v "$bin" > /dev/null 2>&1 || { echo "ERROR: $bin not found" >&2; exit 1; } +done + +[ -d "${DB_DIR}" ] || { echo "ERROR: virus DB directory not found: ${DB_DIR}" >&2; exit 1; } + +cat > "${CLAMD_CONF}" <&2 + exit 1 +fi -virus_status=$? +clamdscan \ + --config-file="${CLAMD_CONF}" \ + --multiscan \ + --fdpass \ + --exclude='./.composer-cache' \ + --exclude='./node_modules_cache' \ + -ri . -echo "-------" -echo "" +SCAN_EXIT=$? -if [ $virus_status -eq 0 ] -then - green "Clean - no viruses found" - echo "" - exit 0 -elif [ $virus_status -eq 1 ] -then - red "**** INFECTED FILE FOUND!!! **** PLEASE SEE REPORT ABOVE ****" - echo "" - exit 1 +if [ "$SCAN_EXIT" -eq 0 ]; then + green "Clean: no viruses found" +elif [ "$SCAN_EXIT" -eq 1 ]; then + red "**** INFECTED FILE FOUND — see report above ****" + exit 1 else - red "Virus scanner internal error." - echo "" - exit 0 # don't block a deploy because the virus scan program is broken + echo "ERROR: clamdscan exited with code ${SCAN_EXIT} — scan did not complete cleanly" >&2 + exit "$SCAN_EXIT" fi