diff --git a/.github/workflows/scripts/safe-files.txt b/.github/workflows/scripts/safe-files.txt new file mode 100644 index 00000000..ca86499f --- /dev/null +++ b/.github/workflows/scripts/safe-files.txt @@ -0,0 +1,2 @@ +.env.example +app/.env.example diff --git a/.github/workflows/scripts/safe_list.sh b/.github/workflows/scripts/safe_list.sh new file mode 100755 index 00000000..8273bf85 --- /dev/null +++ b/.github/workflows/scripts/safe_list.sh @@ -0,0 +1,62 @@ +#!/bin/bash +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +RED='\033[1;31m' +GREEN='\033[1;32m' +YELLOW='\033[1;33m' +NC='\033[0m' +SAFE_LIST_FILE="${SCRIPT_DIR}/safe-files.txt" +PATTERNS=("*\.sql" "*\.dump*" "*\.env") +DANGEROUS_FILES=() + +is_in_safe_list() { + local file="$1" + while IFS= read -r safe_file; do # IFS -> read the name with spaces || for every line in the safe list + [[ -z "$safe_file" || "$safe_file" =~ ^# ]] && continue #ignore comments and empty lines + + if [[ "$safe_file" =~ /$ ]]; then # if the line describes a folder + # Vérifier si le fichier est dans ce dossier + if [[ "$file" == ${safe_file}* ]]; then + return 0 + fi + else + # Comparaison normale avec support des wildcards + if [[ "$file" == $safe_file ]]; then + return 0 + fi + fi + done < "$SAFE_LIST_FILE" + return 1 +} + +echo "" +echo -e "${YELLOW}Checking for sensitive files...${NC}" +echo "" + +for pattern in "${PATTERNS[@]}"; do # for all files detected by the pattern + while IFS= read -r file; do # read the safe list + [[ -z "$file" || -d "$file" ]] && continue #stop if it's a directory or an empty line + if ! is_in_safe_list "$file"; then # is the file in the safe list + DANGEROUS_FILES+=("$file") + fi + done < <(git ls-files | grep -E "${pattern//\*/.*}") +done + +if [ ${#DANGEROUS_FILES[@]} -eq 0 ]; then + echo -e "${GREEN}No dangerous files detected!${NC}" + echo "" + exit 0 # pipeline ok +else + # remove duplicates before displaying + IFS=$'\n' DANGEROUS_FILES=($(sort -u <<<"${DANGEROUS_FILES[*]}")) + unset IFS + + echo -e "${RED}(${#DANGEROUS_FILES[@]}) Dangerous files detected:${NC}" + for file in "${DANGEROUS_FILES[@]}"; do + echo -e "${RED}${NC}$file" + done + echo "" + echo -e "${RED} Pipeline blocked | to solve this issue, remove these items or add them to:${NC}" + echo -e " ${SAFE_LIST_FILE}" + echo "" + exit 1 # pipeline failed +fi diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bee747cb..b3bc9fef 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -3,7 +3,127 @@ name: CI on: [pull_request] jobs: + + safe-list: + runs-on: ubuntu-24.04 + + steps: + - uses: actions/checkout@v4 + + - name: Check for sensitive files + run: | + chmod +x .github/workflows/scripts/safe_list.sh + ./.github/workflows/scripts/safe_list.sh + + migration-check: + needs: safe-list + runs-on: ubuntu-24.04 + + services: + mariadb: + image: mariadb:10.11 + env: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: agentj + MYSQL_USER: agentj + MYSQL_PASSWORD: secret + options: >- + --health-cmd="healthcheck.sh --connect --innodb_initialized" + --health-interval=10s + --health-timeout=5s + --health-retries=3 + ports: + - 3306:3306 + + steps: + - uses: actions/checkout@v4 + + - uses: shivammathur/setup-php@v2 + with: + php-version: 8.2 + extensions: pdo_mysql + + - name: Setup env + run: | + cd ./app + cp .env.example .env + sed -i "s|\$AGENTJ_VERSION|dev|g" .env + sed -i "s|\$SF_APP_ENV|dev|g" .env + sed -i "s|\$SF_APP_SECRET|change-me|g" .env + sed -i "s|\$SF_TOKEN_ENCRYPTION_IV|change-me|g" .env + sed -i "s|\$SF_TOKEN_ENCRYPTION_SALT|change-me|g" .env + sed -i "s|\$SF_SENTRY_DSN||g" .env + sed -i "s|\$DB_NAME|agentj|g" .env + sed -i "s|\$DB_USER|agentj|g" .env + sed -i "s|\$DB_PASSWORD|secret|g" .env + sed -i "s|\$DB_HOST|127.0.0.1|g" .env + sed -i "s|\$DOMAIN|example.com|g" .env + sed -i "s|\$APP_URL|http://example.com|g" .env + sed -i "s|\$SMTP_FROM|example@example.com|g" .env + sed -i "s|\$ENABLE_AZURE_OAUTH||g" .env + sed -i "s|\$OAUTH_AZURE_CLIENT_ID||g" .env + sed -i "s|\$OAUTH_AZURE_CLIENT_SECRET||g" .env + sed -i "s|\$TRUSTED_PROXIES||g" .env + sed -i "s|\$TZ|Europe/Paris|g" .env + sed -i "s|\$DEFAULT_LOCALE|en|g" .env + + - name: Install dependencies + run: | + cd ./app + SYMFONY_ENV=dev composer install --no-interaction + env: + APP_ENV: dev + + - name: Wait for database + run: | + for i in {1..30}; do + if mysqladmin ping -h127.0.0.1 -uagentj -psecret --silent; then + echo "Database is ready!" + break + fi + echo "Waiting for database... ($i/30)" + sleep 2 + done + + - name: Run existing migrations + run: | + cd ./app + php bin/console doctrine:migrations:migrate --no-interaction --env=test + + - name: Check for missing migrations + run: | + cd ./app + + # Count migration files before + BEFORE=$(find migrations -name "Version*.php" 2>/dev/null | wc -l) + echo "Migrations before: $BEFORE" + + # Try to generate migration (force dev environment) + APP_ENV=dev php bin/console make:migration --no-interaction || true + + # Count migration files after + AFTER=$(find migrations -name "Version*.php" 2>/dev/null | wc -l) + echo "Migrations after: $AFTER" + + # Check if new file was created + if [ $AFTER -gt $BEFORE ]; then + echo "" + echo "❌ ERROR: A migration file was generated!" + echo "" + echo "This means your database schema is out of sync with your entities." + echo "" + echo "To fix this:" + echo " 1. Run locally: php bin/console make:migration" + echo " 2. Review the generated migration file" + echo " 3. Commit it with your entity changes" + echo "" + exit 1 + fi + + echo "✅ No missing migrations detected" + linters: + needs: safe-list env: NO_DOCKER: true diff --git a/app/config/packages/framework.yaml b/app/config/packages/framework.yaml index 991362bc..a44bfe62 100644 --- a/app/config/packages/framework.yaml +++ b/app/config/packages/framework.yaml @@ -29,4 +29,4 @@ when@test: framework: test: true session: - storage_id: session.storage.mock_file + storage_factory_id: session.storage.factory.mock_file