From 2a0c0e67f1b2c472b60ac28406f4eceaea35b7ad Mon Sep 17 00:00:00 2001 From: Alexis Legros Date: Mon, 17 Nov 2025 14:30:09 +0100 Subject: [PATCH 01/11] feat(ci) : #257 added safe list check --- .github/workflows/scripts/safe-files.txt | 2 + .github/workflows/scripts/safe_list.sh | 62 ++++++++++++++++++++++++ .github/workflows/tests.yml | 11 +++++ 3 files changed, 75 insertions(+) create mode 100644 .github/workflows/scripts/safe-files.txt create mode 100755 .github/workflows/scripts/safe_list.sh diff --git a/.github/workflows/scripts/safe-files.txt b/.github/workflows/scripts/safe-files.txt new file mode 100644 index 00000000..4e280267 --- /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..09b1ee8a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -3,6 +3,17 @@ 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 + linters: env: NO_DOCKER: true From 67f262ef96d799c43ad2aad14c6b34dcaf0d9030 Mon Sep 17 00:00:00 2001 From: Alexis Legros Date: Mon, 17 Nov 2025 14:36:49 +0100 Subject: [PATCH 02/11] fix failed pipeline --- .github/workflows/scripts/safe-files.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scripts/safe-files.txt b/.github/workflows/scripts/safe-files.txt index 4e280267..ca86499f 100644 --- a/.github/workflows/scripts/safe-files.txt +++ b/.github/workflows/scripts/safe-files.txt @@ -1,2 +1,2 @@ .env.example - app/.env.example +app/.env.example From f27a8abd2bc3ecc37288d205f7c45d910ad41476 Mon Sep 17 00:00:00 2001 From: Alexis Legros Date: Mon, 17 Nov 2025 14:55:36 +0100 Subject: [PATCH 03/11] migration check --- .github/workflows/tests.yml | 107 ++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 09b1ee8a..7708e436 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -3,6 +3,7 @@ name: CI on: [pull_request] jobs: + safe-list: runs-on: ubuntu-24.04 @@ -14,7 +15,113 @@ jobs: 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|test|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 + composer install --no-interaction + + - 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 + 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 From 4b805303b36d4a6c0adbeda887e614dd1789c311 Mon Sep 17 00:00:00 2001 From: Alexis Legros Date: Mon, 17 Nov 2025 15:01:04 +0100 Subject: [PATCH 04/11] fix failed pipeline --- app/config/packages/framework.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From ddf499921b9055244f1bb55206f279d4bf4de3eb Mon Sep 17 00:00:00 2001 From: Alexis Legros Date: Mon, 17 Nov 2025 15:06:46 +0100 Subject: [PATCH 05/11] test pipeline --- app/src/Entity/User.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/Entity/User.php b/app/src/Entity/User.php index 02ec7b5b..e55ea329 100644 --- a/app/src/Entity/User.php +++ b/app/src/Entity/User.php @@ -50,6 +50,9 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface #[ORM\Column(name: 'emailRecovery', type: 'string', length: 255, nullable: true)] private ?string $emailRecovery = null; + #[ORM\Column(name: 'test_field', type: 'string', length: 20, nullable: true)] + private ?string $test_field = null; + #[ORM\Column(name: 'imapLogin', type: 'string', length: 255, nullable: true)] private ?string $imapLogin = null; From f4b10f9aafb143144c2d811c7f57e901427d1d72 Mon Sep 17 00:00:00 2001 From: Alexis Legros Date: Mon, 17 Nov 2025 15:27:42 +0100 Subject: [PATCH 06/11] test pipeline --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7708e436..fae8afe1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -97,7 +97,7 @@ jobs: echo "Migrations before: $BEFORE" # Try to generate migration - php bin/console make:migration --no-interaction || true + make:migration --no-interaction || true # Count migration files after AFTER=$(find migrations -name "Version*.php" 2>/dev/null | wc -l) From 7b13cf956051d46225c5090231b103e5810a7abc Mon Sep 17 00:00:00 2001 From: Alexis Legros Date: Mon, 17 Nov 2025 15:42:10 +0100 Subject: [PATCH 07/11] test pipeline --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index fae8afe1..7708e436 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -97,7 +97,7 @@ jobs: echo "Migrations before: $BEFORE" # Try to generate migration - make:migration --no-interaction || true + php bin/console make:migration --no-interaction || true # Count migration files after AFTER=$(find migrations -name "Version*.php" 2>/dev/null | wc -l) From 13dcf20fed184c039fc3041b431d0beb39620f48 Mon Sep 17 00:00:00 2001 From: Alexis Legros Date: Mon, 17 Nov 2025 15:50:28 +0100 Subject: [PATCH 08/11] test pipeline --- .github/workflows/tests.yml | 2 +- app/src/Entity/User.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7708e436..0a068954 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -70,7 +70,7 @@ jobs: - name: Install dependencies run: | cd ./app - composer install --no-interaction + composer install --no-interaction --dev - name: Wait for database run: | diff --git a/app/src/Entity/User.php b/app/src/Entity/User.php index e55ea329..f1644708 100644 --- a/app/src/Entity/User.php +++ b/app/src/Entity/User.php @@ -50,8 +50,8 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface #[ORM\Column(name: 'emailRecovery', type: 'string', length: 255, nullable: true)] private ?string $emailRecovery = null; - #[ORM\Column(name: 'test_field', type: 'string', length: 20, nullable: true)] - private ?string $test_field = null; + #[ORM\Column(name: 'aaaaatest', type: 'string', length: 20, nullable: true)] + private ?string $aaaaatest = null; #[ORM\Column(name: 'imapLogin', type: 'string', length: 255, nullable: true)] private ?string $imapLogin = null; From 66bd2553788480523a87916885d7c282c1e00163 Mon Sep 17 00:00:00 2001 From: Alexis Legros Date: Mon, 17 Nov 2025 15:54:20 +0100 Subject: [PATCH 09/11] test pipeline --- .github/workflows/tests.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0a068954..882bc02b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -48,7 +48,7 @@ jobs: cd ./app cp .env.example .env sed -i "s|\$AGENTJ_VERSION|dev|g" .env - sed -i "s|\$SF_APP_ENV|test|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 @@ -70,7 +70,9 @@ jobs: - name: Install dependencies run: | cd ./app - composer install --no-interaction --dev + SYMFONY_ENV=dev composer install --no-interaction + env: + APP_ENV: dev - name: Wait for database run: | From 6c0a5b4d41355b7f5d946ce53a6ed1ff5ac84128 Mon Sep 17 00:00:00 2001 From: Alexis Legros Date: Mon, 17 Nov 2025 15:54:49 +0100 Subject: [PATCH 10/11] test pipeline --- .github/workflows/tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 882bc02b..b3bc9fef 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -98,8 +98,8 @@ jobs: BEFORE=$(find migrations -name "Version*.php" 2>/dev/null | wc -l) echo "Migrations before: $BEFORE" - # Try to generate migration - php bin/console make:migration --no-interaction || true + # 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) From a679d7c752a7d9dc4afa5a9a97b8244c24aaf8b4 Mon Sep 17 00:00:00 2001 From: Alexis Legros Date: Mon, 17 Nov 2025 15:59:33 +0100 Subject: [PATCH 11/11] test pipeline --- app/src/Entity/User.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/src/Entity/User.php b/app/src/Entity/User.php index f1644708..02ec7b5b 100644 --- a/app/src/Entity/User.php +++ b/app/src/Entity/User.php @@ -50,9 +50,6 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface #[ORM\Column(name: 'emailRecovery', type: 'string', length: 255, nullable: true)] private ?string $emailRecovery = null; - #[ORM\Column(name: 'aaaaatest', type: 'string', length: 20, nullable: true)] - private ?string $aaaaatest = null; - #[ORM\Column(name: 'imapLogin', type: 'string', length: 255, nullable: true)] private ?string $imapLogin = null;