Skip to content

Continuous Integration #4088

Continuous Integration

Continuous Integration #4088

Workflow file for this run

name: Continuous Integration
env:
DOCKER_IMAGE: wyrihaximusnet/php
DOCKER_BUILDKIT: 1
DOCKER_IMAGE_REGISTRIES_SECRET_MAPPING: '{"ghcr.io":"GHCR_TOKEN","docker.io":"HUB_PASSCODE"}'
DOCKER_CLI_EXPERIMENTAL: enabled
on:
push:
branches:
- master
pull_request:
schedule:
- cron: '13 4 * * *'
jobs:
supported-alpine-versions:
name: Supported Alpine versions
runs-on: ubuntu-latest
outputs:
alpine: ${{ steps.supported-alpine-versions.outputs.versions }}
steps:
- id: supported-alpine-versions
name: Generate Alpine
uses: wyrihaximus/github-action-supported-alpine-linux-versions@v1
with:
maxVersions: 2
supported-debian-versions:
name: Supported Debian versions
runs-on: ubuntu-latest
outputs:
debian: ${{ steps.supported-debian-versions.outputs.versions }}
steps:
- id: supported-debian-versions
name: Generate Debian
uses: wyrihaximus/github-action-supported-debian-linux-versions@v1
supported-php-versions:
name: Supported PHP versions
runs-on: ubuntu-latest
outputs:
php: ${{ steps.supported-php-versions.outputs.versions }}
steps:
- id: supported-php-versions
name: Generate PHP
uses: wyrihaximus/github-action-supported-php-versions@v1
with:
upcomingReleases: true
supported-arch-matrix:
name: Supported processor architectures
runs-on: ubuntu-latest
outputs:
arch: ${{ steps.supported-arch-matrix.outputs.arch }}
steps:
- uses: actions/checkout@v3
- id: supported-arch-matrix
name: Generate Arch
run: |
echo "arch=[\"amd64\",\"arm64\"]" >> $GITHUB_OUTPUT
image-type-matrix:
name: Create Image Type Matrix
runs-on: ubuntu-latest
outputs:
type: ${{ steps.image-type-matrix.outputs.type }}
steps:
- uses: actions/checkout@v1
- id: image-type-matrix
name: Generate Type
run: |
ls Dockerfile-* | jq -csR '. | rtrimstr("\n") | split("\n")' | php -r "echo str_replace('Dockerfile-', '', stream_get_contents(STDIN));" > types.list
cat types.list
echo "type=$(cat types.list)" >> $GITHUB_OUTPUT
exclude-matrix:
name: Create Exclude Matrix
runs-on: ubuntu-latest
outputs:
exclude: ${{ steps.exclude-matrix.outputs.exclude }}
exclude-push: ${{ steps.exclude-matrix.outputs.exclude-push }}
steps:
- uses: actions/checkout@v1
- id: exclude-matrix
name: Generate Exclude
run: |
php utils/exclude-list.php
image-matrix:
name: Create Image Matrix
runs-on: ubuntu-latest
needs:
- supported-alpine-versions
- supported-debian-versions
- supported-php-versions
outputs:
image: ${{ steps.image-matrix.outputs.image }}
steps:
- uses: actions/checkout@v1
- id: image-matrix
name: Generate Combined Image Matrix
run: |
echo "Generate full image list"
php utils/all-images.php
if [ "${{ github.event_name }}" == "schedule" ] ; then
echo "This is a scheduled run, scanning for CVE's"
php utils/all-image-tags.php | xargs -I % sh -c 'docker run -v /tmp/trivy:/var/lib/trivy -v /var/run/docker.sock:/var/run/docker.sock -t aquasec/trivy:latest --cache-dir /var/lib/trivy image --exit-code 1 --no-progress $(php -r "echo explode(\"#\", \"%\")[0];") > /dev/null || echo "%|"' >> images_with.cves
if [ -s "images_with.cves" ]
then
echo "Found images with CVE's in them"
cat images_with.cves | xargs -I % php -r 'echo implode(PHP_EOL, explode("|", "%")), PHP_EOL;' | xargs -I % php -r 'echo explode("#", "%")[1], PHP_EOL;' >> images-that-need-updating.list
fi
echo "Looking for newer upstream images"
php utils/newer-upstream-images.php >> images-that-need-updating.list
printf "image=%s" $(php utils/deduplicate-list.php) >> $GITHUB_OUTPUT
exit 0
fi
echo "Not in a scheduled run, building all images"
printf "image=%s" $(cat all-images.list) >> $GITHUB_OUTPUT
exit 0
env:
ALPINE: ${{ needs.supported-alpine-versions.outputs.alpine }}
DEBIAN: ${{ needs.supported-debian-versions.outputs.debian }}
PHP: ${{ needs.supported-php-versions.outputs.php }}
lint:
name: Linting Dockerfile-${{ matrix.type }}
runs-on: ubuntu-latest
needs:
- image-type-matrix
strategy:
fail-fast: false
matrix:
type: ${{ fromJson(needs.image-type-matrix.outputs.type) }}
steps:
- uses: actions/checkout@v2
- name: Lint Dockerfile-${{ matrix.type }}
uses: docker://hadolint/hadolint:latest-debian
with:
entrypoint: hadolint
args: Dockerfile-${{ matrix.type }}
build:
name: Building "${{ matrix.image }}" on ${{ matrix.arch }}
needs:
- lint
- image-matrix
- supported-arch-matrix
- exclude-matrix
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
image: ${{ fromJson(needs.image-matrix.outputs.image) }}
arch: ${{ fromJson(needs.supported-arch-matrix.outputs.arch) }}
exclude: ${{ fromJson(needs.exclude-matrix.outputs.exclude) }}
steps:
- uses: actions/checkout@v2
- uses: dbhi/qus/action@main
- run: mkdir ./docker-image/
- uses: nick-invision/retry@v2
with:
timeout_minutes: 120
retry_wait_seconds: 30
max_attempts: 5
command: ./build-php.sh $(echo "${{ matrix.image }}" | tr '-' ' ') ${{ matrix.arch }}
- run: cat ./docker-image/image.tags | xargs -I % docker inspect --format='%={{.Id}}:{{index .Config.Env 7}}' %
- run: docker save "${DOCKER_IMAGE}" | gzip -9 > ./docker-image/image.tar
- run: docker images
- name: Upload Images
uses: actions/upload-artifact@v2
with:
name: docker-image-${{ matrix.image }}-${{ matrix.arch }}
path: ./docker-image
scan-vulnerability:
name: Scanning "${{ matrix.image }}" for vulnerabilities on ${{ matrix.arch }}
needs:
- build
- image-matrix
- supported-arch-matrix
- exclude-matrix
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
image: ${{ fromJson(needs.image-matrix.outputs.image) }}
arch: ${{ fromJson(needs.supported-arch-matrix.outputs.arch) }}
exclude: ${{ fromJson(needs.exclude-matrix.outputs.exclude) }}
steps:
- uses: actions/checkout@v2
if: contains(matrix.image, 'alpine')
- uses: dbhi/qus/action@main
if: contains(matrix.image, 'alpine')
- name: Download Images
if: contains(matrix.image, 'alpine')
uses: actions/download-artifact@v2
with:
name: docker-image-${{ matrix.image }}-${{ matrix.arch }}
path: ./docker-image
- run: docker load --input ./docker-image/image.tar
if: contains(matrix.image, 'alpine')
- run: mkdir -p "./clair/${DOCKER_IMAGE}"
if: contains(matrix.image, 'alpine')
- run: make ci-scan-vulnerability
if: contains(matrix.image, 'alpine')
test:
name: Testing "${{ matrix.image }}" on ${{ matrix.arch }}
needs:
- build
- image-matrix
- supported-arch-matrix
- exclude-matrix
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
image: ${{ fromJson(needs.image-matrix.outputs.image) }}
arch: ${{ fromJson(needs.supported-arch-matrix.outputs.arch) }}
exclude: ${{ fromJson(needs.exclude-matrix.outputs.exclude) }}
steps:
- uses: actions/checkout@v2
- uses: dbhi/qus/action@main
- name: Download Images
uses: actions/download-artifact@v2
with:
name: docker-image-${{ matrix.image }}-${{ matrix.arch }}
path: ./docker-image
- run: ls -lasth ./docker-image
- run: docker load --input ./docker-image/image.tar
- run: IMAGE_BASE_VERSION=$(php -r 'echo explode("-", "${{ matrix.image }}")[2];') make $(php -r 'echo "test-", explode("-", str_replace(["zts-zts", "cli-nts"], ["zts", "nts"], "${{ matrix.image }}"))[0];')
env:
IMAGE_ARCH: ${{ matrix.arch }}
- run: rm -Rf ./docker-image/
check-mark:
name: ✔️
needs:
- lint
- build
- scan-vulnerability
- test
runs-on: ubuntu-latest
steps:
- run: echo "✔️"
push:
name: Pushing "${{ matrix.image }}" for ${{ matrix.arch }}
if: (github.event_name == 'push' || github.event_name == 'schedule') && github.ref == 'refs/heads/master'
needs:
- check-mark
- image-matrix
- supported-arch-matrix
- exclude-matrix
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
image: ${{ fromJson(needs.image-matrix.outputs.image) }}
arch: ${{ fromJson(needs.supported-arch-matrix.outputs.arch) }}
exclude: ${{ fromJson(needs.exclude-matrix.outputs.exclude) }}
steps:
- uses: actions/checkout@v2
- uses: dbhi/qus/action@main
- name: Download Images
uses: actions/download-artifact@v2
with:
name: docker-image-${{ matrix.image }}-${{ matrix.arch }}
path: ./docker-image
- run: docker load --input ./docker-image/image.tar
- name: Login to container registries
uses: nick-invision/retry@v2
with:
timeout_minutes: 120
retry_wait_seconds: 30
max_attempts: 5
command: |
(jq -r 'to_entries | map("echo \"$" + .value + "\" | docker login " + .key + " --username \"${{ env.DOCKER_USER }}\" --password-stdin") | .[]' <<<"$DOCKER_IMAGE_REGISTRIES_SECRET_MAPPING") | sh
env:
DOCKER_USER: ${{ secrets.HUB_USERNAME }}
GHCR_TOKEN: ${{ secrets.GHCR_TOKEN }}
HUB_PASSCODE: ${{ secrets.HUB_PASSCODE }}
- name: Retag
uses: nick-invision/retry@v2
with:
timeout_minutes: 120
retry_wait_seconds: 30
max_attempts: 5
command: |
(jq -r 'to_entries | map("cat ./docker-image/image.tags | xargs -I % docker tag % " + .key + "/%") | .[]' <<<"$DOCKER_IMAGE_REGISTRIES_SECRET_MAPPING") | sh
- name: Push tags
uses: nick-invision/retry@v2
with:
timeout_minutes: 120
retry_wait_seconds: 30
max_attempts: 5
command: |
(jq -r 'to_entries | map("cat ./docker-image/image.tags | xargs -I % docker push " + .key + "/%") | .[]' <<<"$DOCKER_IMAGE_REGISTRIES_SECRET_MAPPING") | sh
push-manifest:
name: Push ${{ matrix.image }} manifest
if: (github.event_name == 'push' || github.event_name == 'schedule') && github.ref == 'refs/heads/master'
strategy:
fail-fast: false
matrix:
image: ${{ fromJson(needs.image-matrix.outputs.image) }}
needs:
- push
- image-matrix
- supported-arch-matrix
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: dbhi/qus/action@main
- name: Download Images
uses: actions/download-artifact@v2
with:
name: docker-image-${{ matrix.image }}-amd64
path: ./docker-image
- name: Login to container registries
uses: nick-invision/retry@v2
with:
timeout_minutes: 120
retry_wait_seconds: 30
max_attempts: 5
command: |
(jq -r 'to_entries | map("echo \"$" + .value + "\" | docker login " + .key + " --username \"${{ env.DOCKER_USER }}\" --password-stdin") | .[]' <<<"$DOCKER_IMAGE_REGISTRIES_SECRET_MAPPING") | sh
env:
DOCKER_USER: ${{ secrets.HUB_USERNAME }}
GHCR_TOKEN: ${{ secrets.GHCR_TOKEN }}
HUB_PASSCODE: ${{ secrets.HUB_PASSCODE }}
- name: Docker info
run: docker info
- name: Push manifest to registries
uses: nick-invision/retry@v2
with:
timeout_minutes: 120
retry_wait_seconds: 30
max_attempts: 5
command: |
touch command.sh
(jq -r 'to_entries | map("cat ./docker-image/image.tags | xargs -I % php utils/create-manifest-command.php " + .key + " %") | .[]' <<<"$DOCKER_IMAGE_REGISTRIES_SECRET_MAPPING") | sh
chmod +x command.sh
./command.sh
env:
TARGET_ARCHS: ${{ needs.supported-arch-matrix.outputs.arch }}