Skip to content

Bump the composer-minor-and-patch group across 1 directory with 7 updates #28

Bump the composer-minor-and-patch group across 1 directory with 7 updates

Bump the composer-minor-and-patch group across 1 directory with 7 updates #28

Workflow file for this run

name: Continuous Integration
on:
pull_request:
push:
branches:
- master
workflow_dispatch:
permissions:
contents: read
pull-requests: read
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
changes:
name: Change classification
uses: ./.github/workflows/change-classification.yml
php:
name: PHP quality and tests
runs-on: ubuntu-latest
needs:
- changes
- frontend
if: >-
github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.backend == 'true' ||
needs.changes.outputs.automation == 'true'
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.4"
tools: composer
extensions: intl, mbstring, pdo_sqlite, sqlite3
- name: Cache Composer dependencies
uses: actions/cache@v6
with:
path: ~/.cache/composer/files
key: ${{ runner.os }}-php-8.4-${{ hashFiles('composer.lock') }}
restore-keys: ${{ runner.os }}-php-8.4-
- name: Install PHP dependencies
run: composer install --no-interaction --no-progress --prefer-dist
- name: Download frontend assets
uses: actions/download-artifact@v8
with:
name: frontend-build
path: public/build
- name: Check PHP formatting
run: |
vendor/bin/pint
git diff --exit-code
- name: Run PHP tests
env:
APP_KEY: base64:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
run: php artisan test
frontend:
name: Frontend build
runs-on: ubuntu-latest
needs: changes
if: >-
github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.backend == 'true' ||
needs.changes.outputs.frontend == 'true' ||
needs.changes.outputs.automation == 'true'
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.4"
tools: composer
- name: Install PHP dependencies
run: composer install --no-interaction --no-progress --prefer-dist
- name: Set up Node.js
uses: actions/setup-node@v7
with:
node-version: "24"
cache: npm
- name: Install Node dependencies
run: npm ci --no-audit --fund=false
- name: Build frontend assets
run: npm run build
- name: Upload frontend assets
uses: actions/upload-artifact@v7
with:
name: frontend-build
path: public/build
mariadb:
name: MariaDB integration tests
runs-on: ubuntu-latest
needs:
- changes
- frontend
if: >-
github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.backend == 'true' ||
needs.changes.outputs.automation == 'true'
services:
db:
image: mariadb:11
env:
MARIADB_DATABASE: versiontracker
MARIADB_USER: versiontracker
MARIADB_PASSWORD: versiontracker
MARIADB_ROOT_PASSWORD: root
options: >-
--health-cmd="healthcheck.sh --connect --innodb_initialized"
--health-interval=10s
--health-timeout=5s
--health-retries=10
ports:
- 3306:3306
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.4"
tools: composer
extensions: intl, mbstring, pdo_mysql
- name: Install PHP dependencies
run: composer install --no-interaction --no-progress --prefer-dist
- name: Download frontend assets
uses: actions/download-artifact@v8
with:
name: frontend-build
path: public/build
- name: Run PHP tests with MariaDB
env:
APP_KEY: base64:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
DB_CONNECTION: mariadb
DB_HOST: 127.0.0.1
DB_PORT: 3306
DB_DATABASE: versiontracker
DB_USERNAME: versiontracker
DB_PASSWORD: versiontracker
run: php artisan test
container:
name: Container integration test
runs-on: ubuntu-latest
needs: changes
if: >-
github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.infrastructure == 'true' ||
needs.changes.outputs.automation == 'true'
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build application image
uses: docker/build-push-action@v6
with:
context: .
load: true
tags: ghcr.io/soerennb/version-tracker:test
cache-from: type=gha,scope=container
cache-to: type=gha,mode=max,scope=container
- name: Scan application image
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25
with:
image-ref: ghcr.io/soerennb/version-tracker:test
format: table
exit-code: "1"
ignore-unfixed: true
severity: CRITICAL,HIGH
vuln-type: os,library
- name: Prepare Compose environment
run: |
cp .env.docker.example .env.docker
sed -i 's/^VERSION=$/VERSION=test/' .env.docker
sed -i 's/^DEPLOYMENT_MODE=$/DEPLOYMENT_MODE=proxy/' .env.docker
sed -i 's/^APP_KEY=$/APP_KEY=base64:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=/' .env.docker
sed -i 's/^DB_PASSWORD=$/DB_PASSWORD=versiontracker/' .env.docker
sed -i 's/^DB_ROOT_PASSWORD=$/DB_ROOT_PASSWORD=root/' .env.docker
docker compose --env-file .env.docker -f compose.yml -f compose.proxy.yml config --quiet
- name: Initialize and check application
run: |
docker compose --env-file .env.docker -f compose.yml -f compose.proxy.yml up --detach db
docker compose --env-file .env.docker -f compose.yml -f compose.proxy.yml run --rm app php artisan migrate --force
docker compose --env-file .env.docker -f compose.yml -f compose.proxy.yml up --detach app
for attempt in {1..30}; do
if curl --fail --silent http://127.0.0.1:8080/up; then
exit 0
fi
sleep 2
done
docker compose --env-file .env.docker -f compose.yml -f compose.proxy.yml logs
exit 1
- name: Back up and restore application data
run: |
backup_directory="$(./install.sh backup)"
test -s "$backup_directory/database.sql"
test -s "$backup_directory/storage.tar.gz"
test "$(stat --format=%a "$backup_directory/environment.backup")" = 600
docker compose --env-file .env.docker -f compose.yml -f compose.proxy.yml down --volumes --remove-orphans
docker compose --env-file .env.docker -f compose.yml -f compose.proxy.yml up --detach db
for attempt in {1..30}; do
if docker compose --env-file .env.docker -f compose.yml -f compose.proxy.yml exec --no-TTY db healthcheck.sh --connect --innodb_initialized; then
break
fi
sleep 2
done
docker compose --env-file .env.docker -f compose.yml -f compose.proxy.yml exec --no-TTY db sh -c 'exec mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" "$MARIADB_DATABASE"' < "$backup_directory/database.sql"
docker compose --env-file .env.docker -f compose.yml -f compose.proxy.yml exec --no-TTY db sh -c 'mariadb -uroot -p"$MARIADB_ROOT_PASSWORD" "$MARIADB_DATABASE" --skip-column-names --execute="SELECT COUNT(*) FROM migrations"' | grep --extended-regexp '^[1-9][0-9]*$'
docker compose --env-file .env.docker -f compose.yml -f compose.proxy.yml run --rm app sh -c 'tar -xzf - -C /var/www/html' < "$backup_directory/storage.tar.gz"
docker compose --env-file .env.docker -f compose.yml -f compose.proxy.yml up --detach app
for attempt in {1..30}; do
if curl --fail --silent http://127.0.0.1:8080/up; then
exit 0
fi
sleep 2
done
docker compose --env-file .env.docker -f compose.yml -f compose.proxy.yml logs
exit 1
- name: Clean up containers
if: always()
run: |
if [[ -f .env.docker ]]; then
docker compose --env-file .env.docker -f compose.yml -f compose.proxy.yml down --volumes --remove-orphans
fi
compose:
name: Compose configuration
runs-on: ubuntu-latest
needs: changes
if: >-
github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.infrastructure == 'true' ||
needs.changes.outputs.automation == 'true'
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Validate deployment configurations
run: |
cp .env.docker.example .env.docker
sed -i 's/^VERSION=$/VERSION=v0.0.0/' .env.docker
docker compose --env-file .env.docker -f compose.yml -f compose.proxy.yml config --quiet
docker compose --env-file .env.docker -f compose.yml -f compose.caddy.yml config --quiet
- name: Validate Caddyfile
run: docker run --rm --env CADDY_DOMAIN=example.invalid --env CADDY_EMAIL=ci@example.invalid --volume "$GITHUB_WORKSPACE/Caddyfile:/etc/caddy/Caddyfile:ro" caddy:2.11.4 caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
shell:
name: Installer script
runs-on: ubuntu-latest
needs: changes
if: >-
github.event_name == 'workflow_dispatch' ||
needs.changes.outputs.infrastructure == 'true' ||
needs.changes.outputs.automation == 'true'
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Install ShellCheck
run: sudo apt-get update && sudo apt-get install --yes shellcheck
- name: Lint installer
run: |
test -x install.sh
shellcheck install.sh
gate:
name: CI gate
runs-on: ubuntu-latest
if: always()
needs:
- changes
- php
- frontend
- mariadb
- container
- compose
- shell
steps:
- name: Require successful executed checks
if: >-
contains(needs.*.result, 'failure') ||
contains(needs.*.result, 'cancelled')
run: exit 1